diff --git a/Adafruit_NeoPixel b/Adafruit_NeoPixel deleted file mode 160000 index 15bfa178f2c8e21f732cce7850bc03f8b056291b..0000000000000000000000000000000000000000 --- a/Adafruit_NeoPixel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 15bfa178f2c8e21f732cce7850bc03f8b056291b diff --git a/Adafruit_VL53L0X b/Adafruit_VL53L0X deleted file mode 160000 index 23dc309c56ae7b3031b296380b0663c5dd5edb68..0000000000000000000000000000000000000000 --- a/Adafruit_VL53L0X +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 23dc309c56ae7b3031b296380b0663c5dd5edb68 diff --git a/Arduino-IRremote b/Arduino-IRremote deleted file mode 160000 index aa7edfe96f1b8d747b8c98835966bb114fbb0d76..0000000000000000000000000000000000000000 --- a/Arduino-IRremote +++ /dev/null @@ -1 +0,0 @@ -Subproject commit aa7edfe96f1b8d747b8c98835966bb114fbb0d76 diff --git a/ArduinoJson-v6.11.1/ArduinoJson-v6.11.1.h b/ArduinoJson-v6.11.1/ArduinoJson-v6.11.1.h deleted file mode 100644 index 8b8a4127dbada0fc5587b1ed3b4402bf65fb2456..0000000000000000000000000000000000000000 --- a/ArduinoJson-v6.11.1/ArduinoJson-v6.11.1.h +++ /dev/null @@ -1,5663 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2019 -// MIT License - -#pragma once - -#ifdef __cplusplus - -#ifndef ARDUINOJSON_DEBUG -#ifdef __clang__ -#pragma clang system_header -#elif defined __GNUC__ -#pragma GCC system_header -#endif -#endif -#define ARDUINOJSON_VERSION "6.11.1" -#define ARDUINOJSON_VERSION_MAJOR 6 -#define ARDUINOJSON_VERSION_MINOR 11 -#define ARDUINOJSON_VERSION_REVISION 1 -#if defined(_MSC_VER) -#define ARDUINOJSON_HAS_INT64 1 -#else -#define ARDUINOJSON_HAS_INT64 0 -#endif -#if __cplusplus >= 201103L -#define ARDUINOJSON_HAS_LONG_LONG 1 -#define ARDUINOJSON_HAS_NULLPTR 1 -#else -#define ARDUINOJSON_HAS_LONG_LONG 0 -#define ARDUINOJSON_HAS_NULLPTR 0 -#endif -#ifndef ARDUINOJSON_EMBEDDED_MODE -#if defined(ARDUINO) || defined(__IAR_SYSTEMS_ICC__) || defined(__XC) || \ - defined(__ARMCC_VERSION) -#define ARDUINOJSON_EMBEDDED_MODE 1 -#else -#define ARDUINOJSON_EMBEDDED_MODE 0 -#endif -#endif -#if ARDUINOJSON_EMBEDDED_MODE -#ifndef ARDUINOJSON_USE_DOUBLE -#define ARDUINOJSON_USE_DOUBLE 0 -#endif -#ifndef ARDUINOJSON_USE_LONG_LONG -#define ARDUINOJSON_USE_LONG_LONG 0 -#endif -#ifndef ARDUINOJSON_ENABLE_STD_STRING -#define ARDUINOJSON_ENABLE_STD_STRING 0 -#endif -#ifndef ARDUINOJSON_ENABLE_STD_STREAM -#define ARDUINOJSON_ENABLE_STD_STREAM 0 -#endif -#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT -#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10 -#endif -#else // ARDUINOJSON_EMBEDDED_MODE -#ifndef ARDUINOJSON_USE_DOUBLE -#define ARDUINOJSON_USE_DOUBLE 1 -#endif -#ifndef ARDUINOJSON_USE_LONG_LONG -#if ARDUINOJSON_HAS_LONG_LONG || ARDUINOJSON_HAS_INT64 -#define ARDUINOJSON_USE_LONG_LONG 1 -#else -#define ARDUINOJSON_USE_LONG_LONG 0 -#endif -#endif -#ifndef ARDUINOJSON_ENABLE_STD_STRING -#define ARDUINOJSON_ENABLE_STD_STRING 1 -#endif -#ifndef ARDUINOJSON_ENABLE_STD_STREAM -#define ARDUINOJSON_ENABLE_STD_STREAM 1 -#endif -#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT -#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50 -#endif -#endif // ARDUINOJSON_EMBEDDED_MODE -#ifdef ARDUINO -#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING -#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 -#endif -#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM -#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1 -#endif -#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT -#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1 -#endif -#else // ARDUINO -#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING -#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0 -#endif -#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM -#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0 -#endif -#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT -#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0 -#endif -#endif // ARDUINO -#ifndef ARDUINOJSON_ENABLE_PROGMEM -#ifdef PROGMEM -#define ARDUINOJSON_ENABLE_PROGMEM 1 -#else -#define ARDUINOJSON_ENABLE_PROGMEM 0 -#endif -#endif -#ifndef ARDUINOJSON_DECODE_UNICODE -#define ARDUINOJSON_DECODE_UNICODE 0 -#endif -#ifndef ARDUINOJSON_ENABLE_NAN -#define ARDUINOJSON_ENABLE_NAN 0 -#endif -#ifndef ARDUINOJSON_ENABLE_INFINITY -#define ARDUINOJSON_ENABLE_INFINITY 0 -#endif -#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD -#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7 -#endif -#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD -#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5 -#endif -#ifndef ARDUINOJSON_LITTLE_ENDIAN -#if defined(_MSC_VER) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ - defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64) -#define ARDUINOJSON_LITTLE_ENDIAN 1 -#else -#define ARDUINOJSON_LITTLE_ENDIAN 0 -#endif -#endif -#ifndef ARDUINOJSON_TAB -#define ARDUINOJSON_TAB " " -#endif -#define ARDUINOJSON_DO_CONCAT(A, B) A##B -#define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_DO_CONCAT(A, B) -#define ARDUINOJSON_CONCAT3(A, B, C) \ - ARDUINOJSON_CONCAT2(A, ARDUINOJSON_CONCAT2(B, C)) -#define ARDUINOJSON_CONCAT4(A, B, C, D) \ - ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), ARDUINOJSON_CONCAT2(C, D)) -#define ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, H) \ - ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), \ - ARDUINOJSON_CONCAT4(E, F, G, H)) -#define ARDUINOJSON_CONCAT10(A, B, C, D, E, F, G, H, I, J) \ - ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, ARDUINOJSON_CONCAT3(H, I, J)) -#define ARDUINOJSON_NAMESPACE \ - ARDUINOJSON_CONCAT10( \ - ArduinoJson, ARDUINOJSON_VERSION_MAJOR, ARDUINOJSON_VERSION_MINOR, \ - ARDUINOJSON_VERSION_REVISION, _, ARDUINOJSON_USE_LONG_LONG, \ - ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_DECODE_UNICODE, \ - ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY) -#ifdef ARDUINOJSON_DEBUG -#include <assert.h> -#define ARDUINOJSON_ASSERT(X) assert(X) -#else -#define ARDUINOJSON_ASSERT(X) ((void)0) -#endif -#include <stddef.h> // for size_t -namespace ARDUINOJSON_NAMESPACE { -template < size_t X, size_t Y, bool MaxIsX = (X > Y) > -struct Max {}; -template <size_t X, size_t Y> -struct Max<X, Y, true> { - static const size_t value = X; -}; -template <size_t X, size_t Y> -struct Max<X, Y, false> { - static const size_t value = Y; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -class not_null { - public: - explicit not_null(T ptr) : _ptr(ptr) { - ARDUINOJSON_ASSERT(ptr != NULL); - } - T get() const { - ARDUINOJSON_ASSERT(_ptr != NULL); - return _ptr; - } - private: - T _ptr; -}; -template <typename T> -not_null<T> make_not_null(T ptr) { - ARDUINOJSON_ASSERT(ptr != NULL); - return not_null<T>(ptr); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <bool Condition, class TrueType, class FalseType> -struct conditional { - typedef TrueType type; -}; -template <class TrueType, class FalseType> -struct conditional<false, TrueType, FalseType> { - typedef FalseType type; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <bool Condition, typename T = void> -struct enable_if {}; -template <typename T> -struct enable_if<true, T> { - typedef T type; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T, T v> -struct integral_constant { - static const T value = v; -}; -typedef integral_constant<bool, true> true_type; -typedef integral_constant<bool, false> false_type; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -struct is_array : false_type {}; -template <typename T> -struct is_array<T[]> : true_type {}; -template <typename T, size_t N> -struct is_array<T[N]> : true_type {}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TBase, typename TDerived> -class is_base_of { - protected: // <- to avoid GCC's "all member functions in class are private" - typedef char Yes[1]; - typedef char No[2]; - static Yes &probe(const TBase *); - static No &probe(...); - public: - static const bool value = - sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes); -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -struct is_const : false_type {}; -template <typename T> -struct is_const<const T> : true_type {}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename> -struct is_floating_point : false_type {}; -template <> -struct is_floating_point<float> : true_type {}; -template <> -struct is_floating_point<double> : true_type {}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T, typename U> -struct is_same : false_type {}; -template <typename T> -struct is_same<T, T> : true_type {}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -struct is_integral { - static const bool value = - is_same<T, signed char>::value || is_same<T, unsigned char>::value || - is_same<T, signed short>::value || is_same<T, unsigned short>::value || - is_same<T, signed int>::value || is_same<T, unsigned int>::value || - is_same<T, signed long>::value || is_same<T, unsigned long>::value || -#if ARDUINOJSON_HAS_LONG_LONG - is_same<T, signed long long>::value || - is_same<T, unsigned long long>::value || -#endif -#if ARDUINOJSON_HAS_INT64 - is_same<T, signed __int64>::value || - is_same<T, unsigned __int64>::value || -#endif - is_same<T, char>::value; -}; -template <typename T> -struct is_integral<const T> : is_integral<T> {}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename> -struct is_signed : false_type {}; -template <> -struct is_signed<char> : true_type {}; -template <> -struct is_signed<signed char> : true_type {}; -template <> -struct is_signed<signed short> : true_type {}; -template <> -struct is_signed<signed int> : true_type {}; -template <> -struct is_signed<signed long> : true_type {}; -template <> -struct is_signed<float> : true_type {}; -template <> -struct is_signed<double> : true_type {}; -#if ARDUINOJSON_HAS_LONG_LONG -template <> -struct is_signed<signed long long> : true_type {}; -#endif -#if ARDUINOJSON_HAS_INT64 -template <> -struct is_signed<signed __int64> : true_type {}; -#endif -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename> -struct is_unsigned : false_type {}; -template <> -struct is_unsigned<bool> : true_type {}; -template <> -struct is_unsigned<unsigned char> : true_type {}; -template <> -struct is_unsigned<unsigned short> : true_type {}; -template <> -struct is_unsigned<unsigned int> : true_type {}; -template <> -struct is_unsigned<unsigned long> : true_type {}; -#if ARDUINOJSON_HAS_INT64 -template <> -struct is_unsigned<unsigned __int64> : true_type {}; -#endif -#if ARDUINOJSON_HAS_LONG_LONG -template <> -struct is_unsigned<unsigned long long> : true_type {}; -#endif -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -struct type_identity { - typedef T type; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -struct make_unsigned; -template <> -struct make_unsigned<char> : type_identity<unsigned char> {}; -template <> -struct make_unsigned<signed char> : type_identity<unsigned char> {}; -template <> -struct make_unsigned<unsigned char> : type_identity<unsigned char> {}; -template <> -struct make_unsigned<signed short> : type_identity<unsigned short> {}; -template <> -struct make_unsigned<unsigned short> : type_identity<unsigned short> {}; -template <> -struct make_unsigned<signed int> : type_identity<unsigned int> {}; -template <> -struct make_unsigned<unsigned int> : type_identity<unsigned int> {}; -template <> -struct make_unsigned<signed long> : type_identity<unsigned long> {}; -template <> -struct make_unsigned<unsigned long> : type_identity<unsigned long> {}; -#if ARDUINOJSON_HAS_LONG_LONG -template <> -struct make_unsigned<signed long long> : type_identity<unsigned long long> {}; -template <> -struct make_unsigned<unsigned long long> : type_identity<unsigned long long> {}; -#endif -#if ARDUINOJSON_HAS_INT64 -template <> -struct make_unsigned<signed __int64> : type_identity<unsigned __int64> {}; -template <> -struct make_unsigned<unsigned __int64> : type_identity<unsigned __int64> {}; -#endif -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -struct remove_const { - typedef T type; -}; -template <typename T> -struct remove_const<const T> { - typedef T type; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -struct remove_reference { - typedef T type; -}; -template <typename T> -struct remove_reference<T&> { - typedef T type; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class MemoryPool; -class VariantData; -class VariantSlot; -class CollectionData { - VariantSlot *_head; - VariantSlot *_tail; - public: - VariantSlot *addSlot(MemoryPool *); - VariantData *add(MemoryPool *pool); - template <typename TAdaptedString> - VariantData *add(TAdaptedString key, MemoryPool *pool); - void clear(); - template <typename TAdaptedString> - bool containsKey(const TAdaptedString &key) const; - bool copyFrom(const CollectionData &src, MemoryPool *pool); - bool equalsArray(const CollectionData &other) const; - bool equalsObject(const CollectionData &other) const; - VariantData *get(size_t index) const; - template <typename TAdaptedString> - VariantData *get(TAdaptedString key) const; - VariantSlot *head() const { - return _head; - } - void remove(size_t index); - template <typename TAdaptedString> - void remove(TAdaptedString key) { - remove(getSlot(key)); - } - void remove(VariantSlot *slot); - size_t memoryUsage() const; - size_t nesting() const; - size_t size() const; - private: - VariantSlot *getSlot(size_t index) const; - template <typename TAdaptedString> - VariantSlot *getSlot(TAdaptedString key) const; - VariantSlot *getPreviousSlot(VariantSlot *) const; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -#if ARDUINOJSON_USE_DOUBLE -typedef double Float; -#else -typedef float Float; -#endif -} // namespace ARDUINOJSON_NAMESPACE -#include <stdint.h> // int64_t -namespace ARDUINOJSON_NAMESPACE { -#if ARDUINOJSON_USE_LONG_LONG -typedef int64_t Integer; -typedef uint64_t UInt; -#else -typedef long Integer; -typedef unsigned long UInt; -#endif -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -enum { - VALUE_MASK = 0x7F, - VALUE_IS_NULL = 0, - VALUE_IS_LINKED_RAW = 0x01, - VALUE_IS_OWNED_RAW = 0x02, - VALUE_IS_LINKED_STRING = 0x03, - VALUE_IS_OWNED_STRING = 0x04, - VALUE_IS_BOOLEAN = 0x05, - VALUE_IS_POSITIVE_INTEGER = 0x06, - VALUE_IS_NEGATIVE_INTEGER = 0x07, - VALUE_IS_FLOAT = 0x08, - COLLECTION_MASK = 0x60, - VALUE_IS_OBJECT = 0x20, - VALUE_IS_ARRAY = 0x40, - KEY_IS_OWNED = 0x80 -}; -struct RawData { - const char *data; - size_t size; -}; -union VariantContent { - Float asFloat; - UInt asInteger; - CollectionData asCollection; - const char *asString; - struct { - const char *data; - size_t size; - } asRaw; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -typedef conditional < sizeof(void*) <= 2, int8_t, int16_t >::type VariantSlotDiff; -class VariantSlot { - VariantContent _content; - uint8_t _flags; - VariantSlotDiff _next; - const char* _key; - public: - VariantData* data() { - return reinterpret_cast<VariantData*>(&_content); - } - const VariantData* data() const { - return reinterpret_cast<const VariantData*>(&_content); - } - VariantSlot* next() { - return _next ? this + _next : 0; - } - const VariantSlot* next() const { - return const_cast<VariantSlot*>(this)->next(); - } - VariantSlot* next(size_t distance) { - VariantSlot* slot = this; - while (distance--) { - if (!slot->_next) return 0; - slot += slot->_next; - } - return slot; - } - const VariantSlot* next(size_t distance) const { - return const_cast<VariantSlot*>(this)->next(distance); - } - void setNext(VariantSlot* slot) { - _next = VariantSlotDiff(slot ? slot - this : 0); - } - void setNextNotNull(VariantSlot* slot) { - ARDUINOJSON_ASSERT(slot != 0); - _next = VariantSlotDiff(slot - this); - } - void setOwnedKey(not_null<const char*> k) { - _flags |= KEY_IS_OWNED; - _key = k.get(); - } - void setLinkedKey(not_null<const char*> k) { - _flags &= VALUE_MASK; - _key = k.get(); - } - const char* key() const { - return _key; - } - bool ownsKey() const { - return (_flags & KEY_IS_OWNED) != 0; - } - void clear() { - _next = 0; - _flags = 0; - _key = 0; - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -inline bool isAligned(void *ptr) { - const size_t mask = sizeof(void *) - 1; - size_t addr = reinterpret_cast<size_t>(ptr); - return (addr & mask) == 0; -} -inline size_t addPadding(size_t bytes) { - const size_t mask = sizeof(void *) - 1; - return (bytes + mask) & ~mask; -} -template <size_t bytes> -struct AddPadding { - static const size_t mask = sizeof(void *) - 1; - static const size_t value = (bytes + mask) & ~mask; -}; -} // namespace ARDUINOJSON_NAMESPACE -#define JSON_STRING_SIZE(SIZE) (SIZE) -namespace ARDUINOJSON_NAMESPACE { -struct StringSlot { - char *value; - size_t size; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class MemoryPool { - public: - MemoryPool(char* buf, size_t capa) - : _begin(buf), - _left(buf), - _right(buf ? buf + capa : 0), - _end(buf ? buf + capa : 0) { - ARDUINOJSON_ASSERT(isAligned(_begin)); - ARDUINOJSON_ASSERT(isAligned(_right)); - ARDUINOJSON_ASSERT(isAligned(_end)); - } - void* buffer() { - return _begin; - } - size_t capacity() const { - return size_t(_end - _begin); - } - size_t size() const { - return size_t(_left - _begin + _end - _right); - } - VariantSlot* allocVariant() { - return allocRight<VariantSlot>(); - } - char* allocFrozenString(size_t n) { - if (!canAlloc(n)) return 0; - char* s = _left; - _left += n; - checkInvariants(); - return s; - } - StringSlot allocExpandableString() { - StringSlot s; - s.value = _left; - s.size = size_t(_right - _left); - _left = _right; - checkInvariants(); - return s; - } - void freezeString(StringSlot& s, size_t newSize) { - _left -= (s.size - newSize); - s.size = newSize; - checkInvariants(); - } - void clear() { - _left = _begin; - _right = _end; - } - bool canAlloc(size_t bytes) const { - return _left + bytes <= _right; - } - bool owns(void* p) const { - return _begin <= p && p < _end; - } - template <typename T> - T* allocRight() { - return reinterpret_cast<T*>(allocRight(sizeof(T))); - } - void* allocRight(size_t bytes) { - if (!canAlloc(bytes)) return 0; - _right -= bytes; - return _right; - } - void* operator new(size_t, void* p) { - return p; - } - private: - StringSlot* allocStringSlot() { - return allocRight<StringSlot>(); - } - void checkInvariants() { - ARDUINOJSON_ASSERT(_begin <= _left); - ARDUINOJSON_ASSERT(_left <= _right); - ARDUINOJSON_ASSERT(_right <= _end); - ARDUINOJSON_ASSERT(isAligned(_right)); - } - char *_begin, *_left, *_right, *_end; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename> -struct IsString : false_type {}; -template <typename T> -struct IsString<const T> : IsString<T> {}; -template <typename T> -struct IsString<T&> : IsString<T> {}; -} // namespace ARDUINOJSON_NAMESPACE -#include <string.h> // strcmp -namespace ARDUINOJSON_NAMESPACE { -inline int8_t safe_strcmp(const char* a, const char* b) { - if (a == b) return 0; - if (!a) return -1; - if (!b) return 1; - return static_cast<int8_t>(strcmp(a, b)); -} -inline int8_t safe_strncmp(const char* a, const char* b, size_t n) { - if (a == b) return 0; - if (!a) return -1; - if (!b) return 1; - return static_cast<int8_t>(strncmp(a, b, n)); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class ConstRamStringAdapter { - public: - ConstRamStringAdapter(const char* str = 0) : _str(str) {} - int8_t compare(const char* other) const { - return safe_strcmp(_str, other); - } - bool equals(const char* expected) const { - return compare(expected) == 0; - } - bool isNull() const { - return !_str; - } - template <typename TMemoryPool> - char* save(TMemoryPool*) const { - return 0; - } - size_t size() const { - if (!_str) return 0; - return strlen(_str); - } - const char* data() const { - return _str; - } - bool isStatic() const { - return true; - } - protected: - const char* _str; -}; -inline ConstRamStringAdapter adaptString(const char* str) { - return ConstRamStringAdapter(str); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class RamStringAdapter : public ConstRamStringAdapter { - public: - RamStringAdapter(const char* str) : ConstRamStringAdapter(str) {} - char* save(MemoryPool* pool) const { - if (!_str) return NULL; - size_t n = size() + 1; - char* dup = pool->allocFrozenString(n); - if (dup) memcpy(dup, _str, n); - return dup; - } - bool isStatic() const { - return false; - } -}; -template <typename TChar> -inline RamStringAdapter adaptString(const TChar* str) { - return RamStringAdapter(reinterpret_cast<const char*>(str)); -} -inline RamStringAdapter adaptString(char* str) { - return RamStringAdapter(str); -} -template <typename TChar> -struct IsString<TChar*> { - static const bool value = sizeof(TChar) == 1; -}; -template <> -struct IsString<void*> { - static const bool value = false; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class SizedRamStringAdapter { - public: - SizedRamStringAdapter(const char* str, size_t n) : _str(str), _size(n) {} - int8_t compare(const char* other) const { - return safe_strncmp(_str, other, _size) == 0; - } - bool equals(const char* expected) const { - return compare(expected) == 0; - } - bool isNull() const { - return !_str; - } - char* save(MemoryPool* pool) const { - if (!_str) return NULL; - char* dup = pool->allocFrozenString(_size); - if (dup) memcpy(dup, _str, _size); - return dup; - } - size_t size() const { - return _size; - } - bool isStatic() const { - return false; - } - private: - const char* _str; - size_t _size; -}; -template <typename TChar> -inline SizedRamStringAdapter adaptString(const TChar* str, size_t size) { - return SizedRamStringAdapter(reinterpret_cast<const char*>(str), size); -} -} // namespace ARDUINOJSON_NAMESPACE -#if ARDUINOJSON_ENABLE_STD_STRING -#include <string> -namespace ARDUINOJSON_NAMESPACE { -class StlStringAdapter { - public: - StlStringAdapter(const std::string& str) : _str(&str) {} - char* save(MemoryPool* pool) const { - size_t n = _str->length() + 1; - char* dup = pool->allocFrozenString(n); - if (dup) memcpy(dup, _str->c_str(), n); - return dup; - } - bool isNull() const { - return false; - } - int8_t compare(const char* other) const { - if (!other) return 1; - return static_cast<int8_t>(_str->compare(other)); - } - bool equals(const char* expected) const { - if (!expected) return false; - return *_str == expected; - } - const char* data() const { - return _str->data(); - } - size_t size() const { - return _str->size(); - } - bool isStatic() const { - return false; - } - private: - const std::string* _str; -}; -template <> -struct IsString<std::string> : true_type {}; -inline StlStringAdapter adaptString(const std::string& str) { - return StlStringAdapter(str); -} -} // namespace ARDUINOJSON_NAMESPACE -#endif -#if ARDUINOJSON_ENABLE_ARDUINO_STRING -#include <WString.h> -namespace ARDUINOJSON_NAMESPACE { -class ArduinoStringAdapter { - public: - ArduinoStringAdapter(const ::String& str) : _str(&str) {} - char* save(MemoryPool* pool) const { - if (isNull()) return NULL; - size_t n = _str->length() + 1; - char* dup = pool->allocFrozenString(n); - if (dup) memcpy(dup, _str->c_str(), n); - return dup; - } - bool isNull() const { - return !_str->c_str(); - } - int8_t compare(const char* other) const { - const char* me = _str->c_str(); - return safe_strcmp(me, other); - } - bool equals(const char* expected) const { - return compare(expected) == 0; - } - const char* data() const { - return _str->c_str(); - } - size_t size() const { - return _str->length(); - } - bool isStatic() const { - return false; - } - private: - const ::String* _str; -}; -template <> -struct IsString< ::String> : true_type {}; -template <> -struct IsString< ::StringSumHelper> : true_type {}; -inline ArduinoStringAdapter adaptString(const ::String& str) { - return ArduinoStringAdapter(str); -} -} // namespace ARDUINOJSON_NAMESPACE -#endif -#if ARDUINOJSON_ENABLE_PROGMEM -namespace ARDUINOJSON_NAMESPACE { -class FlashStringAdapter { - public: - FlashStringAdapter(const __FlashStringHelper* str) : _str(str) {} - int8_t compare(const char* other) const { - if (!other && !_str) return 0; - if (!_str) return -1; - if (!other) return 1; - return -strcmp_P(other, reinterpret_cast<const char*>(_str)); - } - bool equals(const char* expected) const { - return compare(expected) == 0; - } - bool isNull() const { - return !_str; - } - char* save(MemoryPool* pool) const { - if (!_str) return NULL; - size_t n = size() + 1; // copy the terminator - char* dup = pool->allocFrozenString(n); - if (dup) memcpy_P(dup, reinterpret_cast<const char*>(_str), n); - return dup; - } - const char* data() const { - return 0; - } - size_t size() const { - if (!_str) return 0; - return strlen_P(reinterpret_cast<const char*>(_str)); - } - bool isStatic() const { - return false; - } - private: - const __FlashStringHelper* _str; -}; -inline FlashStringAdapter adaptString(const __FlashStringHelper* str) { - return FlashStringAdapter(str); -} -template <> -struct IsString<const __FlashStringHelper*> : true_type {}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class SizedFlashStringAdapter { - public: - SizedFlashStringAdapter(const __FlashStringHelper* str, size_t sz) - : _str(str), _size(sz) {} - int8_t compare(const char* other) const { - if (!other && !_str) return 0; - if (!_str) return -1; - if (!other) return 1; - return -strncmp_P(other, reinterpret_cast<const char*>(_str), _size); - } - bool equals(const char* expected) const { - return compare(expected) == 0; - } - bool isNull() const { - return !_str; - } - char* save(MemoryPool* pool) const { - if (!_str) return NULL; - char* dup = pool->allocFrozenString(_size); - if (dup) memcpy_P(dup, (const char*)_str, _size); - return dup; - } - size_t size() const { - return _size; - } - bool isStatic() const { - return false; - } - private: - const __FlashStringHelper* _str; - size_t _size; -}; -inline SizedFlashStringAdapter adaptString(const __FlashStringHelper* str, - size_t sz) { - return SizedFlashStringAdapter(str, sz); -} -} // namespace ARDUINOJSON_NAMESPACE -#endif -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -class SerializedValue { - public: - explicit SerializedValue(T str) : _str(str) {} - operator T() const { - return _str; - } - const char* data() const { - return _str.c_str(); - } - size_t size() const { - return _str.length(); - } - private: - T _str; -}; -template <typename TChar> -class SerializedValue<TChar*> { - public: - explicit SerializedValue(TChar* p, size_t n) : _data(p), _size(n) {} - operator TChar*() const { - return _data; - } - TChar* data() const { - return _data; - } - size_t size() const { - return _size; - } - private: - TChar* _data; - size_t _size; -}; -template <typename T> -inline SerializedValue<T> serialized(T str) { - return SerializedValue<T>(str); -} -template <typename TChar> -inline SerializedValue<TChar*> serialized(TChar* p) { - return SerializedValue<TChar*>(p, adaptString(p).size()); -} -template <typename TChar> -inline SerializedValue<TChar*> serialized(TChar* p, size_t n) { - return SerializedValue<TChar*>(p, n); -} -} // namespace ARDUINOJSON_NAMESPACE -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" -#elif defined(__GNUC__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) -#pragma GCC diagnostic push -#endif -#pragma GCC diagnostic ignored "-Wconversion" -#endif -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4310) -#endif -namespace ARDUINOJSON_NAMESPACE { -template <typename T, typename Enable = void> -struct numeric_limits; -template <typename T> -struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> { - static T lowest() { - return 0; - } - static T highest() { - return T(-1); - } -}; -template <typename T> -struct numeric_limits < - T, typename enable_if < is_integral<T>::value && is_signed<T>::value >::type > { - static T lowest() { - return T(T(1) << (sizeof(T) * 8 - 1)); - } - static T highest() { - return T(~lowest()); - } -}; -} // namespace ARDUINOJSON_NAMESPACE -#ifdef _MSC_VER -#pragma warning(pop) -#endif -#include <stdlib.h> // for size_t -namespace ARDUINOJSON_NAMESPACE { -#ifndef isnan -template <typename T> -bool isnan(T x) { - return x != x; -} -#endif -#ifndef isinf -template <typename T> -bool isinf(T x) { - return x != 0.0 && x * 2 == x; -} -#endif -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T, typename F> -struct alias_cast_t { - union { - F raw; - T data; - }; -}; -template <typename T, typename F> -T alias_cast(F raw_data) { - alias_cast_t<T, F> ac; - ac.raw = raw_data; - return ac.data; -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T, size_t = sizeof(T)> -struct FloatTraits {}; -template <typename T> -struct FloatTraits<T, 8 /*64bits*/> { - typedef uint64_t mantissa_type; - static const short mantissa_bits = 52; - static const mantissa_type mantissa_max = - (mantissa_type(1) << mantissa_bits) - 1; - typedef int16_t exponent_type; - static const exponent_type exponent_max = 308; - template <typename TExponent> - static T make_float(T m, TExponent e) { - if (e > 0) { - for (uint8_t index = 0; e != 0; index++) { - if (e & 1) m *= positiveBinaryPowerOfTen(index); - e >>= 1; - } - } else { - e = TExponent(-e); - for (uint8_t index = 0; e != 0; index++) { - if (e & 1) m *= negativeBinaryPowerOfTen(index); - e >>= 1; - } - } - return m; - } - static T positiveBinaryPowerOfTen(int index) { - static T factors[] = { - 1e1, - 1e2, - 1e4, - 1e8, - 1e16, - forge(0x4693B8B5, 0xB5056E17), // 1e32 - forge(0x4D384F03, 0xE93FF9F5), // 1e64 - forge(0x5A827748, 0xF9301D32), // 1e128 - forge(0x75154FDD, 0x7F73BF3C) // 1e256 - }; - return factors[index]; - } - static T negativeBinaryPowerOfTen(int index) { - static T factors[] = { - forge(0x3FB99999, 0x9999999A), // 1e-1 - forge(0x3F847AE1, 0x47AE147B), // 1e-2 - forge(0x3F1A36E2, 0xEB1C432D), // 1e-4 - forge(0x3E45798E, 0xE2308C3A), // 1e-8 - forge(0x3C9CD2B2, 0x97D889BC), // 1e-16 - forge(0x3949F623, 0xD5A8A733), // 1e-32 - forge(0x32A50FFD, 0x44F4A73D), // 1e-64 - forge(0x255BBA08, 0xCF8C979D), // 1e-128 - forge(0x0AC80628, 0x64AC6F43) // 1e-256 - }; - return factors[index]; - } - static T negativeBinaryPowerOfTenPlusOne(int index) { - static T factors[] = { - 1e0, - forge(0x3FB99999, 0x9999999A), // 1e-1 - forge(0x3F50624D, 0xD2F1A9FC), // 1e-3 - forge(0x3E7AD7F2, 0x9ABCAF48), // 1e-7 - forge(0x3CD203AF, 0x9EE75616), // 1e-15 - forge(0x398039D6, 0x65896880), // 1e-31 - forge(0x32DA53FC, 0x9631D10D), // 1e-63 - forge(0x25915445, 0x81B7DEC2), // 1e-127 - forge(0x0AFE07B2, 0x7DD78B14) // 1e-255 - }; - return factors[index]; - } - static T nan() { - return forge(0x7ff80000, 0x00000000); - } - static T inf() { - return forge(0x7ff00000, 0x00000000); - } - static T highest() { - return forge(0x7FEFFFFF, 0xFFFFFFFF); - } - static T lowest() { - return forge(0xFFEFFFFF, 0xFFFFFFFF); - } - static T forge(uint32_t msb, uint32_t lsb) { - return alias_cast<T>((uint64_t(msb) << 32) | lsb); - } -}; -template <typename T> -struct FloatTraits<T, 4 /*32bits*/> { - typedef uint32_t mantissa_type; - static const short mantissa_bits = 23; - static const mantissa_type mantissa_max = - (mantissa_type(1) << mantissa_bits) - 1; - typedef int8_t exponent_type; - static const exponent_type exponent_max = 38; - template <typename TExponent> - static T make_float(T m, TExponent e) { - if (e > 0) { - for (uint8_t index = 0; e != 0; index++) { - if (e & 1) m *= positiveBinaryPowerOfTen(index); - e >>= 1; - } - } else { - e = -e; - for (uint8_t index = 0; e != 0; index++) { - if (e & 1) m *= negativeBinaryPowerOfTen(index); - e >>= 1; - } - } - return m; - } - static T positiveBinaryPowerOfTen(int index) { - static T factors[] = {1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f}; - return factors[index]; - } - static T negativeBinaryPowerOfTen(int index) { - static T factors[] = {1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f}; - return factors[index]; - } - static T negativeBinaryPowerOfTenPlusOne(int index) { - static T factors[] = {1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f}; - return factors[index]; - } - static T forge(uint32_t bits) { - return alias_cast<T>(bits); - } - static T nan() { - return forge(0x7fc00000); - } - static T inf() { - return forge(0x7f800000); - } - static T highest() { - return forge(0x7f7fffff); - } - static T lowest() { - return forge(0xFf7fffff); - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TOut, typename TIn> -typename enable_if < is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn), - bool >::type -canStorePositiveInteger(TIn value) { - return value <= TIn(numeric_limits<TOut>::highest()); -} -template <typename TOut, typename TIn> -typename enable_if < is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut), - bool>::type -canStorePositiveInteger(TIn) { - return true; -} -template <typename TOut, typename TIn> -typename enable_if<is_floating_point<TOut>::value, bool>::type -canStorePositiveInteger(TIn) { - return true; -} -template <typename TOut, typename TIn> -typename enable_if<is_floating_point<TOut>::value, bool>::type -canStoreNegativeInteger(TIn) { - return true; -} -template <typename TOut, typename TIn> -typename enable_if < is_integral<TOut>::value && is_signed<TOut>::value && -sizeof(TOut) <= sizeof(TIn), - bool >::type -canStoreNegativeInteger(TIn value) { - return value <= TIn(numeric_limits<TOut>::highest()) + 1; -} -template <typename TOut, typename TIn> -typename enable_if < is_integral<TOut>::value && is_signed<TOut>::value && -sizeof(TIn) < sizeof(TOut), - bool>::type -canStoreNegativeInteger(TIn) { - return true; -} -template <typename TOut, typename TIn> -typename enable_if < is_integral<TOut>::value && is_unsigned<TOut>::value, - bool >::type -canStoreNegativeInteger(TIn) { - return false; -} -template <typename TOut, typename TIn> -TOut convertPositiveInteger(TIn value) { - return canStorePositiveInteger<TOut>(value) ? TOut(value) : 0; -} -template <typename TOut, typename TIn> -TOut convertNegativeInteger(TIn value) { - return canStoreNegativeInteger<TOut>(value) ? TOut(~value + 1) : 0; -} -template <typename TOut, typename TIn> -typename enable_if<is_floating_point<TOut>::value, TOut>::type convertFloat( - TIn value) { - return TOut(value); -} -template <typename TOut, typename TIn> -typename enable_if < !is_floating_point<TOut>::value, TOut >::type convertFloat( - TIn value) { - return value >= numeric_limits<TOut>::lowest() && - value <= numeric_limits<TOut>::highest() - ? TOut(value) - : 0; -} -} // namespace ARDUINOJSON_NAMESPACE -#if defined(__clang__) -#pragma clang diagnostic pop -#elif defined(__GNUC__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) -#pragma GCC diagnostic pop -#endif -#endif -namespace ARDUINOJSON_NAMESPACE { -class VariantData { - VariantContent _content; // must be first to allow cast from array to variant - uint8_t _flags; - public: - template <typename Visitor> - void accept(Visitor &visitor) const { - switch (type()) { - case VALUE_IS_FLOAT: - return visitor.visitFloat(_content.asFloat); - case VALUE_IS_ARRAY: - return visitor.visitArray(_content.asCollection); - case VALUE_IS_OBJECT: - return visitor.visitObject(_content.asCollection); - case VALUE_IS_LINKED_STRING: - case VALUE_IS_OWNED_STRING: - return visitor.visitString(_content.asString); - case VALUE_IS_OWNED_RAW: - case VALUE_IS_LINKED_RAW: - return visitor.visitRawJson(_content.asRaw.data, _content.asRaw.size); - case VALUE_IS_NEGATIVE_INTEGER: - return visitor.visitNegativeInteger(_content.asInteger); - case VALUE_IS_POSITIVE_INTEGER: - return visitor.visitPositiveInteger(_content.asInteger); - case VALUE_IS_BOOLEAN: - return visitor.visitBoolean(_content.asInteger != 0); - default: - return visitor.visitNull(); - } - } - template <typename T> - T asIntegral() const; - template <typename T> - T asFloat() const; - const char *asString() const; - bool asBoolean() const; - CollectionData *asArray() { - return isArray() ? &_content.asCollection : 0; - } - const CollectionData *asArray() const { - return const_cast<VariantData *>(this)->asArray(); - } - CollectionData *asObject() { - return isObject() ? &_content.asCollection : 0; - } - const CollectionData *asObject() const { - return const_cast<VariantData *>(this)->asObject(); - } - bool copyFrom(const VariantData &src, MemoryPool *pool) { - switch (src.type()) { - case VALUE_IS_ARRAY: - return toArray().copyFrom(src._content.asCollection, pool); - case VALUE_IS_OBJECT: - return toObject().copyFrom(src._content.asCollection, pool); - case VALUE_IS_OWNED_STRING: - return setOwnedString(RamStringAdapter(src._content.asString), pool); - case VALUE_IS_OWNED_RAW: - return setOwnedRaw( - serialized(src._content.asRaw.data, src._content.asRaw.size), pool); - default: - setType(src.type()); - _content = src._content; - return true; - } - } - bool equals(const VariantData &other) const { - if (type() != other.type()) return false; - switch (type()) { - case VALUE_IS_LINKED_STRING: - case VALUE_IS_OWNED_STRING: - return !strcmp(_content.asString, other._content.asString); - case VALUE_IS_LINKED_RAW: - case VALUE_IS_OWNED_RAW: - return _content.asRaw.size == other._content.asRaw.size && - !memcmp(_content.asRaw.data, other._content.asRaw.data, - _content.asRaw.size); - case VALUE_IS_BOOLEAN: - case VALUE_IS_POSITIVE_INTEGER: - case VALUE_IS_NEGATIVE_INTEGER: - return _content.asInteger == other._content.asInteger; - case VALUE_IS_ARRAY: - return _content.asCollection.equalsArray(other._content.asCollection); - case VALUE_IS_OBJECT: - return _content.asCollection.equalsObject(other._content.asCollection); - case VALUE_IS_FLOAT: - return _content.asFloat == other._content.asFloat; - case VALUE_IS_NULL: - default: - return true; - } - } - bool isArray() const { - return (_flags & VALUE_IS_ARRAY) != 0; - } - bool isBoolean() const { - return type() == VALUE_IS_BOOLEAN; - } - bool isCollection() const { - return (_flags & COLLECTION_MASK) != 0; - } - template <typename T> - bool isInteger() const { - switch (type()) { - case VALUE_IS_POSITIVE_INTEGER: - return canStorePositiveInteger<T>(_content.asInteger); - case VALUE_IS_NEGATIVE_INTEGER: - return canStoreNegativeInteger<T>(_content.asInteger); - default: - return false; - } - } - bool isFloat() const { - return type() == VALUE_IS_FLOAT || type() == VALUE_IS_POSITIVE_INTEGER || - type() == VALUE_IS_NEGATIVE_INTEGER; - } - bool isString() const { - return type() == VALUE_IS_LINKED_STRING || type() == VALUE_IS_OWNED_STRING; - } - bool isObject() const { - return (_flags & VALUE_IS_OBJECT) != 0; - } - bool isNull() const { - return type() == VALUE_IS_NULL; - } - bool isEnclosed() const { - return isCollection() || isString(); - } - void remove(size_t index) { - if (isArray()) _content.asCollection.remove(index); - } - template <typename TAdaptedString> - void remove(TAdaptedString key) { - if (isObject()) _content.asCollection.remove(key); - } - void setBoolean(bool value) { - setType(VALUE_IS_BOOLEAN); - _content.asInteger = static_cast<UInt>(value); - } - void setFloat(Float value) { - setType(VALUE_IS_FLOAT); - _content.asFloat = value; - } - void setLinkedRaw(SerializedValue<const char *> value) { - if (value.data()) { - setType(VALUE_IS_LINKED_RAW); - _content.asRaw.data = value.data(); - _content.asRaw.size = value.size(); - } else { - setType(VALUE_IS_NULL); - } - } - template <typename T> - bool setOwnedRaw(SerializedValue<T> value, MemoryPool *pool) { - char *dup = adaptString(value.data(), value.size()).save(pool); - if (dup) { - setType(VALUE_IS_OWNED_RAW); - _content.asRaw.data = dup; - _content.asRaw.size = value.size(); - return true; - } else { - setType(VALUE_IS_NULL); - return false; - } - } - template <typename T> - typename enable_if<is_unsigned<T>::value>::type setInteger(T value) { - setUnsignedInteger(value); - } - template <typename T> - typename enable_if<is_signed<T>::value>::type setInteger(T value) { - setSignedInteger(value); - } - template <typename T> - void setSignedInteger(T value) { - if (value >= 0) { - setPositiveInteger(static_cast<UInt>(value)); - } else { - setNegativeInteger(~static_cast<UInt>(value) + 1); - } - } - void setPositiveInteger(UInt value) { - setType(VALUE_IS_POSITIVE_INTEGER); - _content.asInteger = value; - } - void setNegativeInteger(UInt value) { - setType(VALUE_IS_NEGATIVE_INTEGER); - _content.asInteger = value; - } - void setLinkedString(const char *value) { - if (value) { - setType(VALUE_IS_LINKED_STRING); - _content.asString = value; - } else { - setType(VALUE_IS_NULL); - } - } - void setNull() { - setType(VALUE_IS_NULL); - } - void setOwnedString(not_null<const char *> s) { - setType(VALUE_IS_OWNED_STRING); - _content.asString = s.get(); - } - bool setOwnedString(const char *s) { - if (s) { - setOwnedString(make_not_null(s)); - return true; - } else { - setType(VALUE_IS_NULL); - return false; - } - } - template <typename T> - bool setOwnedString(T value, MemoryPool *pool) { - return setOwnedString(value.save(pool)); - } - void setUnsignedInteger(UInt value) { - setType(VALUE_IS_POSITIVE_INTEGER); - _content.asInteger = static_cast<UInt>(value); - } - CollectionData &toArray() { - setType(VALUE_IS_ARRAY); - _content.asCollection.clear(); - return _content.asCollection; - } - CollectionData &toObject() { - setType(VALUE_IS_OBJECT); - _content.asCollection.clear(); - return _content.asCollection; - } - size_t memoryUsage() const { - switch (type()) { - case VALUE_IS_OWNED_STRING: - return strlen(_content.asString) + 1; - case VALUE_IS_OWNED_RAW: - return _content.asRaw.size; - case VALUE_IS_OBJECT: - case VALUE_IS_ARRAY: - return _content.asCollection.memoryUsage(); - default: - return 0; - } - } - size_t nesting() const { - return isCollection() ? _content.asCollection.nesting() : 0; - } - size_t size() const { - return isCollection() ? _content.asCollection.size() : 0; - } - VariantData *addElement(MemoryPool *pool) { - if (isNull()) toArray(); - if (!isArray()) return 0; - return _content.asCollection.add(pool); - } - VariantData *getElement(size_t index) const { - return isArray() ? _content.asCollection.get(index) : 0; - } - template <typename TAdaptedString> - VariantData *getMember(TAdaptedString key) const { - return isObject() ? _content.asCollection.get(key) : 0; - } - template <typename TAdaptedString> - VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool) { - if (isNull()) toObject(); - if (!isObject()) return 0; - VariantData *var = _content.asCollection.get(key); - if (var) return var; - return _content.asCollection.add(key, pool); - } - private: - uint8_t type() const { - return _flags & VALUE_MASK; - } - void setType(uint8_t t) { - _flags &= KEY_IS_OWNED; - _flags |= t; - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) { - return arr ? arr->add(pool) : 0; -} -template <typename Visitor> -inline void arrayAccept(const CollectionData *arr, Visitor &visitor) { - if (arr) - visitor.visitArray(*arr); - else - visitor.visitNull(); -} -inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) { - if (lhs == rhs) return true; - if (!lhs || !rhs) return false; - return lhs->equalsArray(*rhs); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TAdaptedString> -inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool) { - if (!var) return false; - if (key.isStatic()) { - var->setLinkedKey(make_not_null(key.data())); - } else { - const char* dup = key.save(pool); - if (!dup) return false; - var->setOwnedKey(make_not_null(dup)); - } - return true; -} -inline size_t slotSize(const VariantSlot* var) { - size_t n = 0; - while (var) { - n++; - var = var->next(); - } - return n; -} -inline VariantData* slotData(VariantSlot* slot) { - return reinterpret_cast<VariantData*>(slot); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -struct Visitable { -}; -template <typename T> -struct IsVisitable : is_base_of<Visitable, T> {}; -template <typename T> -struct IsVisitable<T&> : IsVisitable<T> {}; -} // namespace ARDUINOJSON_NAMESPACE -#ifdef _MSC_VER // Visual Studio -#define FORCE_INLINE // __forceinline causes C4714 when returning std::string -#define NO_INLINE __declspec(noinline) -#define DEPRECATED(msg) __declspec(deprecated(msg)) -#elif defined(__GNUC__) // GCC or Clang -#define FORCE_INLINE __attribute__((always_inline)) -#define NO_INLINE __attribute__((noinline)) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#define DEPRECATED(msg) __attribute__((deprecated(msg))) -#else -#define DEPRECATED(msg) __attribute__((deprecated)) -#endif -#else // Other compilers -#define FORCE_INLINE -#define NO_INLINE -#define DEPRECATED(msg) -#endif -#if __cplusplus >= 201103L -#define NOEXCEPT noexcept -#else -#define NOEXCEPT throw() -#endif -#if defined(__has_attribute) -#if __has_attribute(no_sanitize) -#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check))) -#else -#define ARDUINOJSON_NO_SANITIZE(check) -#endif -#else -#define ARDUINOJSON_NO_SANITIZE(check) -#endif -namespace ARDUINOJSON_NAMESPACE { -template <typename TImpl> -class VariantCasts { - public: - template <typename T> - FORCE_INLINE operator T() const { - return impl()->template as<T>(); - } - private: - const TImpl *impl() const { - return static_cast<const TImpl *>(this); - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T, typename Enable = void> -struct Comparer; -template <typename T> -struct Comparer<T, typename enable_if<IsString<T>::value>::type> { - T rhs; - int result; - explicit Comparer(T value) : rhs(value), result(1) {} - void visitArray(const CollectionData &) {} - void visitObject(const CollectionData &) {} - void visitFloat(Float) {} - void visitString(const char *lhs) { - result = -adaptString(rhs).compare(lhs); - } - void visitRawJson(const char *, size_t) {} - void visitNegativeInteger(UInt) {} - void visitPositiveInteger(UInt) {} - void visitBoolean(bool) {} - void visitNull() { - result = adaptString(rhs).compare(NULL); - } -}; -template <typename T> -typename enable_if<is_signed<T>::value, int>::type sign(const T &value) { - return value < 0 ? -1 : value > 0 ? 1 : 0; -} -template <typename T> -typename enable_if<is_unsigned<T>::value, int>::type sign(const T &value) { - return value > 0 ? 1 : 0; -} -template <typename T> -struct Comparer < T, typename enable_if < is_integral<T>::value || - is_floating_point<T>::value >::type > { - T rhs; - int result; - explicit Comparer(T value) : rhs(value), result(1) {} - void visitArray(const CollectionData &) {} - void visitObject(const CollectionData &) {} - void visitFloat(Float lhs) { - result = sign(lhs - static_cast<Float>(rhs)); - } - void visitString(const char *) {} - void visitRawJson(const char *, size_t) {} - void visitNegativeInteger(UInt lhs) { - result = -sign(static_cast<T>(lhs) + rhs); - } - void visitPositiveInteger(UInt lhs) { - result = static_cast<T>(lhs) < rhs ? -1 : static_cast<T>(lhs) > rhs ? 1 : 0; - } - void visitBoolean(bool) {} - void visitNull() {} -}; -template <> -struct Comparer<bool, void> { - bool rhs; - int result; - explicit Comparer(bool value) : rhs(value), result(1) {} - void visitArray(const CollectionData &) {} - void visitObject(const CollectionData &) {} - void visitFloat(Float) {} - void visitString(const char *) {} - void visitRawJson(const char *, size_t) {} - void visitNegativeInteger(UInt) {} - void visitPositiveInteger(UInt) {} - void visitBoolean(bool lhs) { - result = static_cast<int>(lhs - rhs); - } - void visitNull() {} -}; -#if ARDUINOJSON_HAS_NULLPTR -template <> -struct Comparer<decltype(nullptr), void> { - int result; -explicit Comparer(decltype(nullptr)) : result(1) {} -void visitArray(const CollectionData &) {} -void visitObject(const CollectionData &) {} -void visitFloat(Float) {} -void visitString(const char *) {} -void visitRawJson(const char *, size_t) {} -void visitNegativeInteger(UInt) {} -void visitPositiveInteger(UInt) {} -void visitBoolean(bool) {} -void visitNull() { - result = 0; -} -}; -#endif -template <typename TVariant> -class VariantComparisons { - private: - template <typename T> - static int compare(TVariant lhs, const T &rhs) { - Comparer<T> comparer(rhs); - lhs.accept(comparer); - return comparer.result; - } - public: - template <typename T> - friend bool operator==(T *lhs, TVariant rhs) { - return compare(rhs, lhs) == 0; - } - template <typename T> - friend bool operator==(const T &lhs, TVariant rhs) { - return compare(rhs, lhs) == 0; - } - template <typename T> - friend bool operator==(TVariant lhs, T *rhs) { - return compare(lhs, rhs) == 0; - } - template <typename T> - friend bool operator==(TVariant lhs, const T &rhs) { - return compare(lhs, rhs) == 0; - } - template <typename T> - friend bool operator!=(T *lhs, TVariant rhs) { - return compare(rhs, lhs) != 0; - } - template <typename T> - friend bool operator!=(const T &lhs, TVariant rhs) { - return compare(rhs, lhs) != 0; - } - template <typename T> - friend bool operator!=(TVariant lhs, T *rhs) { - return compare(lhs, rhs) != 0; - } - template <typename T> - friend bool operator!=(TVariant lhs, const T &rhs) { - return compare(lhs, rhs) != 0; - } - template <typename T> - friend bool operator<(T *lhs, TVariant rhs) { - return compare(rhs, lhs) > 0; - } - template <typename T> - friend bool operator<(const T &lhs, TVariant rhs) { - return compare(rhs, lhs) > 0; - } - template <typename T> - friend bool operator<(TVariant lhs, T *rhs) { - return compare(lhs, rhs) < 0; - } - template <typename T> - friend bool operator<(TVariant lhs, const T &rhs) { - return compare(lhs, rhs) < 0; - } - template <typename T> - friend bool operator<=(T *lhs, TVariant rhs) { - return compare(rhs, lhs) >= 0; - } - template <typename T> - friend bool operator<=(const T &lhs, TVariant rhs) { - return compare(rhs, lhs) >= 0; - } - template <typename T> - friend bool operator<=(TVariant lhs, T *rhs) { - return compare(lhs, rhs) <= 0; - } - template <typename T> - friend bool operator<=(TVariant lhs, const T &rhs) { - return compare(lhs, rhs) <= 0; - } - template <typename T> - friend bool operator>(T *lhs, TVariant rhs) { - return compare(rhs, lhs) < 0; - } - template <typename T> - friend bool operator>(const T &lhs, TVariant rhs) { - return compare(rhs, lhs) < 0; - } - template <typename T> - friend bool operator>(TVariant lhs, T *rhs) { - return compare(lhs, rhs) > 0; - } - template <typename T> - friend bool operator>(TVariant lhs, const T &rhs) { - return compare(lhs, rhs) > 0; - } - template <typename T> - friend bool operator>=(T *lhs, TVariant rhs) { - return compare(rhs, lhs) <= 0; - } - template <typename T> - friend bool operator>=(const T &lhs, TVariant rhs) { - return compare(rhs, lhs) <= 0; - } - template <typename T> - friend bool operator>=(TVariant lhs, T *rhs) { - return compare(lhs, rhs) >= 0; - } - template <typename T> - friend bool operator>=(TVariant lhs, const T &rhs) { - return compare(lhs, rhs) >= 0; - } -}; -} // namespace ARDUINOJSON_NAMESPACE -#if ARDUINOJSON_ENABLE_ARDUINO_STRING -#endif -#if ARDUINOJSON_ENABLE_STD_STRING -#endif -namespace ARDUINOJSON_NAMESPACE { -template <typename> -struct IsWriteableString : false_type {}; -template <typename TString> -class DynamicStringWriter {}; -#if ARDUINOJSON_ENABLE_ARDUINO_STRING -template <> -struct IsWriteableString<String> : true_type {}; -template <> -class DynamicStringWriter<String> { - public: - DynamicStringWriter(String &str) : _str(&str) {} - size_t write(uint8_t c) { - _str->operator+=(static_cast<char>(c)); - return 1; - } - size_t write(const uint8_t *s, size_t n) { - _str->reserve(_str->length() + n); - while (n > 0) { - _str->operator+=(static_cast<char>(*s++)); - n--; - } - return n; - } - private: - String *_str; -}; -#endif -#if ARDUINOJSON_ENABLE_STD_STRING -template <> -struct IsWriteableString<std::string> : true_type {}; -template <> -class DynamicStringWriter<std::string> { - public: - DynamicStringWriter(std::string &str) : _str(&str) {} - size_t write(uint8_t c) { - _str->operator+=(static_cast<char>(c)); - return 1; - } - size_t write(const uint8_t *s, size_t n) { - _str->append(reinterpret_cast<const char *>(s), n); - return n; - } - private: - std::string *_str; -}; -#endif -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class ArrayRef; -class ArrayConstRef; -class ObjectRef; -class ObjectConstRef; -class VariantRef; -class VariantConstRef; -template <typename T> -struct VariantAs { - typedef T type; -}; -template <> -struct VariantAs<char*> { - typedef const char* type; -}; -template <typename T> -struct VariantConstAs { - typedef typename VariantAs<T>::type type; -}; -template <> -struct VariantConstAs<VariantRef> { - typedef VariantConstRef type; -}; -template <> -struct VariantConstAs<ObjectRef> { - typedef ObjectConstRef type; -}; -template <> -struct VariantConstAs<ArrayRef> { - typedef ArrayConstRef type; -}; -template <typename T> -inline typename enable_if<is_integral<T>::value, T>::type variantAs( - const VariantData* _data) { - return _data != 0 ? _data->asIntegral<T>() : T(0); -} -template <typename T> -inline typename enable_if<is_same<T, bool>::value, T>::type variantAs( - const VariantData* _data) { - return _data != 0 ? _data->asBoolean() : false; -} -template <typename T> -inline typename enable_if<is_floating_point<T>::value, T>::type variantAs( - const VariantData* _data) { - return _data != 0 ? _data->asFloat<T>() : T(0); -} -template <typename T> -inline typename enable_if < is_same<T, const char*>::value || -is_same<T, char*>::value, - const char* >::type -variantAs(const VariantData* _data) { - return _data != 0 ? _data->asString() : 0; -} -template <typename T> -inline typename enable_if<is_same<ArrayConstRef, T>::value, T>::type variantAs( - const VariantData* _data); -template <typename T> -inline typename enable_if<is_same<ObjectConstRef, T>::value, T>::type variantAs( - const VariantData* _data); -template <typename T> -inline typename enable_if<is_same<VariantConstRef, T>::value, T>::type -variantAs(const VariantData* _data); -template <typename T> -inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs( - const VariantData* _data); -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TImpl> -class VariantOr { - public: - template <typename T> - T operator|(const T &defaultValue) const { - if (impl()->template is<T>()) - return impl()->template as<T>(); - else - return defaultValue; - } - const char *operator|(const char *defaultValue) const { - const char *value = impl()->template as<const char *>(); - return value ? value : defaultValue; - } - private: - const TImpl *impl() const { - return static_cast<const TImpl *>(this); - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename> -class ElementProxy; -template <typename TArray> -class ArrayShortcuts { - public: - FORCE_INLINE ElementProxy<const TArray &> operator[](size_t index) const; - FORCE_INLINE ObjectRef createNestedObject() const; - FORCE_INLINE ArrayRef createNestedArray() const; - template <typename T> - FORCE_INLINE bool add(const T &value) const { - return impl()->addElement().set(value); - } - template <typename T> - FORCE_INLINE bool add(T *value) const { - return impl()->addElement().set(value); - } - private: - const TArray *impl() const { - return static_cast<const TArray *>(this); - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TParent, typename TStringRef> -class MemberProxy; -template <typename TObject> -class ObjectShortcuts { - public: - template <typename TString> - FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type - containsKey(const TString &key) const; - template <typename TChar> - FORCE_INLINE typename enable_if<IsString<TChar *>::value, bool>::type - containsKey(TChar *key) const; - template <typename TString> - FORCE_INLINE - typename enable_if<IsString<TString>::value, - MemberProxy<const TObject &, const TString &> >::type - operator[](const TString &key) const; - template <typename TChar> - FORCE_INLINE typename enable_if<IsString<TChar *>::value, - MemberProxy<const TObject &, TChar *> >::type - operator[](TChar *key) const; - template <typename TString> - FORCE_INLINE ArrayRef createNestedArray(const TString &key) const; - template <typename TChar> - FORCE_INLINE ArrayRef createNestedArray(TChar *key) const; - template <typename TString> - ObjectRef createNestedObject(const TString &key) const; - template <typename TChar> - ObjectRef createNestedObject(TChar *key) const; - private: - const TObject *impl() const { - return static_cast<const TObject *>(this); - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TVariant> -class VariantShortcuts : public ObjectShortcuts<TVariant>, - public ArrayShortcuts<TVariant> { - public: - using ArrayShortcuts<TVariant>::createNestedArray; - using ArrayShortcuts<TVariant>::createNestedObject; - using ArrayShortcuts<TVariant>::operator[]; - using ObjectShortcuts<TVariant>::createNestedArray; - using ObjectShortcuts<TVariant>::createNestedObject; - using ObjectShortcuts<TVariant>::operator[]; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TImpl> -class VariantOperators : public VariantCasts<TImpl>, - public VariantComparisons<TImpl>, - public VariantOr<TImpl>, - public VariantShortcuts<TImpl> {}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename Visitor> -inline void variantAccept(const VariantData *var, Visitor &visitor) { - if (var != 0) - var->accept(visitor); - else - visitor.visitNull(); -} -inline const CollectionData *variantAsArray(const VariantData *var) { - return var != 0 ? var->asArray() : 0; -} -inline const CollectionData *variantAsObject(const VariantData *var) { - return var != 0 ? var->asObject() : 0; -} -inline CollectionData *variantAsObject(VariantData *var) { - return var != 0 ? var->asObject() : 0; -} -inline bool variantCopyFrom(VariantData *dst, const VariantData *src, - MemoryPool *pool) { - if (!dst) return false; - if (!src) { - dst->setNull(); - return true; - } - return dst->copyFrom(*src, pool); -} -inline bool variantEquals(const VariantData *a, const VariantData *b) { - if (a == b) return true; - if (!a || !b) return false; - return a->equals(*b); -} -inline bool variantIsArray(const VariantData *var) { - return var && var->isArray(); -} -inline bool variantIsBoolean(const VariantData *var) { - return var && var->isBoolean(); -} -template <typename T> -inline bool variantIsInteger(const VariantData *var) { - return var && var->isInteger<T>(); -} -inline bool variantIsFloat(const VariantData *var) { - return var && var->isFloat(); -} -inline bool variantIsString(const VariantData *var) { - return var && var->isString(); -} -inline bool variantIsObject(const VariantData *var) { - return var && var->isObject(); -} -inline bool variantIsNull(const VariantData *var) { - return var == 0 || var->isNull(); -} -inline bool variantSetBoolean(VariantData *var, bool value) { - if (!var) return false; - var->setBoolean(value); - return true; -} -inline bool variantSetFloat(VariantData *var, Float value) { - if (!var) return false; - var->setFloat(value); - return true; -} -inline bool variantSetLinkedRaw(VariantData *var, - SerializedValue<const char *> value) { - if (!var) return false; - var->setLinkedRaw(value); - return true; -} -template <typename T> -inline bool variantSetOwnedRaw(VariantData *var, SerializedValue<T> value, - MemoryPool *pool) { - return var != 0 && var->setOwnedRaw(value, pool); -} -template <typename T> -inline bool variantSetSignedInteger(VariantData *var, T value) { - if (!var) return false; - var->setSignedInteger(value); - return true; -} -inline bool variantSetLinkedString(VariantData *var, const char *value) { - if (!var) return false; - var->setLinkedString(value); - return true; -} -inline void variantSetNull(VariantData *var) { - if (!var) return; - var->setNull(); -} -inline bool variantSetOwnedString(VariantData *var, char *value) { - if (!var) return false; - var->setOwnedString(value); - return true; -} -template <typename T> -inline bool variantSetOwnedString(VariantData *var, T value, MemoryPool *pool) { - return var != 0 && var->setOwnedString(value, pool); -} -inline bool variantSetUnsignedInteger(VariantData *var, UInt value) { - if (!var) return false; - var->setUnsignedInteger(value); - return true; -} -inline size_t variantSize(const VariantData *var) { - return var != 0 ? var->size() : 0; -} -inline CollectionData *variantToArray(VariantData *var) { - if (!var) return 0; - return &var->toArray(); -} -inline CollectionData *variantToObject(VariantData *var) { - if (!var) return 0; - return &var->toObject(); -} -inline NO_INLINE VariantData *variantAdd(VariantData *var, MemoryPool *pool) { - return var != 0 ? var->addElement(pool) : 0; -} -template <typename TChar> -NO_INLINE VariantData *variantGetOrCreate(VariantData *var, TChar *key, - MemoryPool *pool) { - return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0; -} -template <typename TString> -NO_INLINE VariantData *variantGetOrCreate(VariantData *var, const TString &key, - MemoryPool *pool) { - return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0; -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class ArrayRef; -class ObjectRef; -template <typename, typename> -class MemberProxy; -template <typename TData> -class VariantRefBase { - public: - template <typename T> - FORCE_INLINE typename enable_if<is_integral<T>::value, bool>::type is() - const { - return variantIsInteger<T>(_data); - } - template <typename T> - FORCE_INLINE typename enable_if<is_floating_point<T>::value, bool>::type is() - const { - return variantIsFloat(_data); - } - template <typename T> - FORCE_INLINE typename enable_if<is_same<T, bool>::value, bool>::type is() - const { - return variantIsBoolean(_data); - } - template <typename T> - FORCE_INLINE typename enable_if < is_same<T, const char *>::value || - is_same<T, char *>::value || - IsWriteableString<T>::value, - bool >::type - is() const { - return variantIsString(_data); - } - template <typename T> - FORCE_INLINE typename enable_if < - is_same<typename remove_const<T>::type, ArrayRef>::value, bool >::type - is() const { - return variantIsArray(_data); - } - template <typename T> - FORCE_INLINE typename enable_if < - is_same<typename remove_const<T>::type, ObjectRef>::value, bool >::type - is() const { - return variantIsObject(_data); - } - FORCE_INLINE bool isNull() const { - return variantIsNull(_data); - } - FORCE_INLINE bool isUndefined() const { - return !_data; - } - FORCE_INLINE size_t memoryUsage() const { - return _data ? _data->memoryUsage() : 0; - } - FORCE_INLINE size_t nesting() const { - return _data ? _data->nesting() : 0; - } - size_t size() const { - return variantSize(_data); - } - protected: - VariantRefBase(TData *data) : _data(data) {} - TData *_data; -}; -class VariantRef : public VariantRefBase<VariantData>, - public VariantOperators<VariantRef>, - public Visitable { - typedef VariantRefBase<VariantData> base_type; - friend class VariantConstRef; - public: - FORCE_INLINE VariantRef(MemoryPool *pool, VariantData *data) - : base_type(data), _pool(pool) {} - FORCE_INLINE VariantRef() : base_type(0), _pool(0) {} - FORCE_INLINE void clear() const { - return variantSetNull(_data); - } - FORCE_INLINE bool set(bool value) const { - return variantSetBoolean(_data, value); - } - template <typename T> - FORCE_INLINE bool set( - T value, - typename enable_if<is_floating_point<T>::value>::type * = 0) const { - return variantSetFloat(_data, static_cast<Float>(value)); - } - template <typename T> - FORCE_INLINE bool set( - T value, - typename enable_if < is_integral<T>::value && is_signed<T>::value >::type * = - 0) const { - return variantSetSignedInteger(_data, value); - } - template <typename T> - FORCE_INLINE bool set( - T value, typename enable_if < is_integral<T>::value && - is_unsigned<T>::value >::type * = 0) const { - return variantSetUnsignedInteger(_data, static_cast<UInt>(value)); - } - FORCE_INLINE bool set(SerializedValue<const char *> value) const { - return variantSetLinkedRaw(_data, value); - } - template <typename T> - FORCE_INLINE bool set( - SerializedValue<T> value, - typename enable_if < !is_same<const char *, T>::value >::type * = 0) const { - return variantSetOwnedRaw(_data, value, _pool); - } - template <typename T> - FORCE_INLINE bool set( - const T &value, - typename enable_if<IsString<T>::value>::type * = 0) const { - return variantSetOwnedString(_data, adaptString(value), _pool); - } - template <typename T> - FORCE_INLINE bool set( - T *value, typename enable_if<IsString<T *>::value>::type * = 0) const { - return variantSetOwnedString(_data, adaptString(value), _pool); - } - FORCE_INLINE bool set(const char *value) const { - return variantSetLinkedString(_data, value); - } - template <typename TVariant> - typename enable_if<IsVisitable<TVariant>::value, bool>::type set( - const TVariant &value) const; - template <typename T> - FORCE_INLINE typename enable_if < !is_same<T, ArrayRef>::value & & - !is_same<T, ObjectRef>::value & & - !is_same<T, VariantRef>::value, - typename VariantAs<T>::type >::type - as() const { - return variantAs<T>(_data); - } - template <typename T> - FORCE_INLINE typename enable_if<is_same<T, ArrayRef>::value, T>::type as() - const; - template <typename T> - FORCE_INLINE typename enable_if<is_same<T, ObjectRef>::value, T>::type as() - const; - template <typename T> - FORCE_INLINE typename enable_if<is_same<T, VariantRef>::value, T>::type as() - const { - return *this; - } - template <typename Visitor> - void accept(Visitor &visitor) const { - variantAccept(_data, visitor); - } - FORCE_INLINE bool operator==(VariantRef lhs) const { - return variantEquals(_data, lhs._data); - } - FORCE_INLINE bool operator!=(VariantRef lhs) const { - return !variantEquals(_data, lhs._data); - } - template <typename T> - typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type to() const; - template <typename T> - typename enable_if<is_same<T, ObjectRef>::value, ObjectRef>::type to() const; - template <typename T> - typename enable_if<is_same<T, VariantRef>::value, VariantRef>::type to() - const; - VariantRef addElement() const; - FORCE_INLINE VariantRef getElement(size_t) const; - template <typename TChar> - FORCE_INLINE VariantRef getMember(TChar *) const; - template <typename TString> - FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type - getMember(const TString &) const; - template <typename TChar> - FORCE_INLINE VariantRef getOrAddMember(TChar *) const; - template <typename TString> - FORCE_INLINE VariantRef getOrAddMember(const TString &) const; - FORCE_INLINE void remove(size_t index) const { - if (_data) _data->remove(index); - } - template <typename TChar> - FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove( - TChar *key) const { - if (_data) _data->remove(adaptString(key)); - } - template <typename TString> - FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( - const TString &key) const { - if (_data) _data->remove(adaptString(key)); - } - private: - MemoryPool *_pool; -}; // namespace ARDUINOJSON_NAMESPACE -class VariantConstRef : public VariantRefBase<const VariantData>, - public VariantOperators<VariantConstRef>, - public Visitable { - typedef VariantRefBase<const VariantData> base_type; - friend class VariantRef; - public: - VariantConstRef() : base_type(0) {} - VariantConstRef(const VariantData *data) : base_type(data) {} - VariantConstRef(VariantRef var) : base_type(var._data) {} - template <typename Visitor> - void accept(Visitor &visitor) const { - variantAccept(_data, visitor); - } - template <typename T> - FORCE_INLINE typename VariantConstAs<T>::type as() const { - return variantAs<typename VariantConstAs<T>::type>(_data); - } - FORCE_INLINE VariantConstRef operator[](size_t index) const; - template <typename TString> - FORCE_INLINE - typename enable_if<IsString<TString>::value, VariantConstRef>::type - operator[](const TString &key) const { - return VariantConstRef(objectGet(variantAsObject(_data), adaptString(key))); - } - template <typename TChar> - FORCE_INLINE - typename enable_if<IsString<TChar *>::value, VariantConstRef>::type - operator[](TChar *key) const { - const CollectionData *obj = variantAsObject(_data); - return VariantConstRef(obj ? obj->get(adaptString(key)) : 0); - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class VariantPtr { - public: - VariantPtr(MemoryPool *pool, VariantData *data) : _variant(pool, data) {} - VariantRef *operator->() { - return &_variant; - } - VariantRef &operator*() { - return _variant; - } - private: - VariantRef _variant; -}; -class ArrayIterator { - public: - ArrayIterator() : _slot(0) {} - explicit ArrayIterator(MemoryPool *pool, VariantSlot *slot) - : _pool(pool), _slot(slot) {} - VariantRef operator*() const { - return VariantRef(_pool, _slot->data()); - } - VariantPtr operator->() { - return VariantPtr(_pool, _slot->data()); - } - bool operator==(const ArrayIterator &other) const { - return _slot == other._slot; - } - bool operator!=(const ArrayIterator &other) const { - return _slot != other._slot; - } - ArrayIterator &operator++() { - _slot = _slot->next(); - return *this; - } - ArrayIterator &operator+=(size_t distance) { - _slot = _slot->next(distance); - return *this; - } - VariantSlot *internal() { - return _slot; - } - private: - MemoryPool *_pool; - VariantSlot *_slot; -}; -class VariantConstPtr { - public: - VariantConstPtr(const VariantData *data) : _variant(data) {} - VariantConstRef *operator->() { - return &_variant; - } - VariantConstRef &operator*() { - return _variant; - } - private: - VariantConstRef _variant; -}; -class ArrayConstRefIterator { - public: - ArrayConstRefIterator() : _slot(0) {} - explicit ArrayConstRefIterator(const VariantSlot *slot) : _slot(slot) {} - VariantConstRef operator*() const { - return VariantConstRef(_slot->data()); - } - VariantConstPtr operator->() { - return VariantConstPtr(_slot->data()); - } - bool operator==(const ArrayConstRefIterator &other) const { - return _slot == other._slot; - } - bool operator!=(const ArrayConstRefIterator &other) const { - return _slot != other._slot; - } - ArrayConstRefIterator &operator++() { - _slot = _slot->next(); - return *this; - } - ArrayConstRefIterator &operator+=(size_t distance) { - _slot = _slot->next(distance); - return *this; - } - const VariantSlot *internal() { - return _slot; - } - private: - const VariantSlot *_slot; -}; -} // namespace ARDUINOJSON_NAMESPACE -#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \ - ((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot)) -namespace ARDUINOJSON_NAMESPACE { -class ObjectRef; -template <typename> -class ElementProxy; -template <typename TData> -class ArrayRefBase { - public: - operator VariantConstRef() const { - const void* data = _data; // prevent warning cast-align - return VariantConstRef(reinterpret_cast<const VariantData*>(data)); - } - template <typename Visitor> - FORCE_INLINE void accept(Visitor& visitor) const { - arrayAccept(_data, visitor); - } - FORCE_INLINE bool isNull() const { - return _data == 0; - } - FORCE_INLINE size_t memoryUsage() const { - return _data ? _data->memoryUsage() : 0; - } - FORCE_INLINE size_t nesting() const { - return _data ? _data->nesting() : 0; - } - FORCE_INLINE size_t size() const { - return _data ? _data->size() : 0; - } - protected: - ArrayRefBase(TData* data) : _data(data) {} - TData* _data; -}; -class ArrayConstRef : public ArrayRefBase<const CollectionData>, - public Visitable { - friend class ArrayRef; - typedef ArrayRefBase<const CollectionData> base_type; - public: - typedef ArrayConstRefIterator iterator; - FORCE_INLINE iterator begin() const { - if (!_data) return iterator(); - return iterator(_data->head()); - } - FORCE_INLINE iterator end() const { - return iterator(); - } - FORCE_INLINE ArrayConstRef() : base_type(0) {} - FORCE_INLINE ArrayConstRef(const CollectionData* data) : base_type(data) {} - FORCE_INLINE bool operator==(ArrayConstRef rhs) const { - return arrayEquals(_data, rhs._data); - } - FORCE_INLINE VariantConstRef operator[](size_t index) const { - return getElement(index); - } - FORCE_INLINE VariantConstRef getElement(size_t index) const { - return VariantConstRef(_data ? _data->get(index) : 0); - } -}; -class ArrayRef : public ArrayRefBase<CollectionData>, - public ArrayShortcuts<ArrayRef>, - public Visitable { - typedef ArrayRefBase<CollectionData> base_type; - public: - typedef ArrayIterator iterator; - FORCE_INLINE ArrayRef() : base_type(0), _pool(0) {} - FORCE_INLINE ArrayRef(MemoryPool* pool, CollectionData* data) - : base_type(data), _pool(pool) {} - operator VariantRef() { - void* data = _data; // prevent warning cast-align - return VariantRef(_pool, reinterpret_cast<VariantData*>(data)); - } - operator ArrayConstRef() const { - return ArrayConstRef(_data); - } - VariantRef addElement() const { - return VariantRef(_pool, arrayAdd(_data, _pool)); - } - FORCE_INLINE iterator begin() const { - if (!_data) return iterator(); - return iterator(_pool, _data->head()); - } - FORCE_INLINE iterator end() const { - return iterator(); - } - FORCE_INLINE bool set(ArrayConstRef src) const { - if (!_data || !src._data) return false; - return _data->copyFrom(*src._data, _pool); - } - FORCE_INLINE bool operator==(ArrayRef rhs) const { - return arrayEquals(_data, rhs._data); - } - FORCE_INLINE VariantRef getElement(size_t index) const { - return VariantRef(_pool, _data ? _data->get(index) : 0); - } - FORCE_INLINE void remove(iterator it) const { - if (!_data) return; - _data->remove(it.internal()); - } - FORCE_INLINE void remove(size_t index) const { - if (!_data) return; - _data->remove(index); - } - private: - MemoryPool* _pool; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename Visitor> -void objectAccept(const CollectionData *obj, Visitor &visitor) { - if (obj) - visitor.visitObject(*obj); - else - visitor.visitNull(); -} -inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) { - if (lhs == rhs) return true; - if (!lhs || !rhs) return false; - return lhs->equalsObject(*rhs); -} -template <typename TAdaptedString> -inline VariantData *objectGet(const CollectionData *obj, TAdaptedString key) { - if (!obj) return 0; - return obj->get(key); -} -template <typename TAdaptedString> -void objectRemove(CollectionData *obj, TAdaptedString key) { - if (!obj) return; - obj->remove(key); -} -template <typename TAdaptedString> -inline VariantData *objectGetOrCreate(CollectionData *obj, TAdaptedString key, - MemoryPool *pool) { - if (!obj) return 0; - if (key.isNull()) return 0; - VariantData *var = obj->get(key); - if (var) return var; - return obj->add(key, pool); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class String { - public: - String() : _data(0), _isStatic(true) {} - String(const char* data, bool isStaticData = true) - : _data(data), _isStatic(isStaticData) {} - const char* c_str() const { - return _data; - } - bool isNull() const { - return !_data; - } - bool isStatic() const { - return _isStatic; - } - friend bool operator==(String lhs, String rhs) { - if (lhs._data == rhs._data) return true; - if (!lhs._data) return false; - if (!rhs._data) return false; - return strcmp(lhs._data, rhs._data) == 0; - } - private: - const char* _data; - bool _isStatic; -}; -class StringAdapter : public RamStringAdapter { - public: - StringAdapter(const String& str) - : RamStringAdapter(str.c_str()), _isStatic(str.isStatic()) {} - bool isStatic() const { - return _isStatic; - } - /* const char* save(MemoryPool* pool) const { - if (_isStatic) return c_str(); - return RamStringAdapter::save(pool); - }*/ - private: - bool _isStatic; -}; -template <> -struct IsString<String> : true_type {}; -inline StringAdapter adaptString(const String& str) { - return StringAdapter(str); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class Pair { - public: - Pair(MemoryPool* pool, VariantSlot* slot) { - if (slot) { - _key = String(slot->key(), !slot->ownsKey()); - _value = VariantRef(pool, slot->data()); - } - } - String key() const { - return _key; - } - VariantRef value() const { - return _value; - } - private: - String _key; - VariantRef _value; -}; -class PairConst { - public: - PairConst(const VariantSlot* slot) { - if (slot) { - _key = String(slot->key(), !slot->ownsKey()); - _value = VariantConstRef(slot->data()); - } - } - String key() const { - return _key; - } - VariantConstRef value() const { - return _value; - } - private: - String _key; - VariantConstRef _value; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class PairPtr { - public: - PairPtr(MemoryPool *pool, VariantSlot *slot) : _pair(pool, slot) {} - const Pair *operator->() const { - return &_pair; - } - const Pair &operator*() const { - return _pair; - } - private: - Pair _pair; -}; -class ObjectIterator { - public: - ObjectIterator() : _slot(0) {} - explicit ObjectIterator(MemoryPool *pool, VariantSlot *slot) - : _pool(pool), _slot(slot) {} - Pair operator*() const { - return Pair(_pool, _slot); - } - PairPtr operator->() { - return PairPtr(_pool, _slot); - } - bool operator==(const ObjectIterator &other) const { - return _slot == other._slot; - } - bool operator!=(const ObjectIterator &other) const { - return _slot != other._slot; - } - ObjectIterator &operator++() { - _slot = _slot->next(); - return *this; - } - ObjectIterator &operator+=(size_t distance) { - _slot = _slot->next(distance); - return *this; - } - VariantSlot *internal() { - return _slot; - } - private: - MemoryPool *_pool; - VariantSlot *_slot; -}; -class PairConstPtr { - public: - PairConstPtr(const VariantSlot *slot) : _pair(slot) {} - const PairConst *operator->() const { - return &_pair; - } - const PairConst &operator*() const { - return _pair; - } - private: - PairConst _pair; -}; -class ObjectConstIterator { - public: - ObjectConstIterator() : _slot(0) {} - explicit ObjectConstIterator(const VariantSlot *slot) : _slot(slot) {} - PairConst operator*() const { - return PairConst(_slot); - } - PairConstPtr operator->() { - return PairConstPtr(_slot); - } - bool operator==(const ObjectConstIterator &other) const { - return _slot == other._slot; - } - bool operator!=(const ObjectConstIterator &other) const { - return _slot != other._slot; - } - ObjectConstIterator &operator++() { - _slot = _slot->next(); - return *this; - } - ObjectConstIterator &operator+=(size_t distance) { - _slot = _slot->next(distance); - return *this; - } - const VariantSlot *internal() { - return _slot; - } - private: - const VariantSlot *_slot; -}; -} // namespace ARDUINOJSON_NAMESPACE -#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \ - ((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot)) -namespace ARDUINOJSON_NAMESPACE { -template <typename TData> -class ObjectRefBase { - public: - operator VariantConstRef() const { - const void* data = _data; // prevent warning cast-align - return VariantConstRef(reinterpret_cast<const VariantData*>(data)); - } - template <typename Visitor> - FORCE_INLINE void accept(Visitor& visitor) const { - objectAccept(_data, visitor); - } - FORCE_INLINE bool isNull() const { - return _data == 0; - } - FORCE_INLINE size_t memoryUsage() const { - return _data ? _data->memoryUsage() : 0; - } - FORCE_INLINE size_t nesting() const { - return _data ? _data->nesting() : 0; - } - FORCE_INLINE size_t size() const { - return _data ? _data->size() : 0; - } - protected: - ObjectRefBase(TData* data) : _data(data) {} - TData* _data; -}; -class ObjectConstRef : public ObjectRefBase<const CollectionData>, - public Visitable { - friend class ObjectRef; - typedef ObjectRefBase<const CollectionData> base_type; - public: - typedef ObjectConstIterator iterator; - ObjectConstRef() : base_type(0) {} - ObjectConstRef(const CollectionData* data) : base_type(data) {} - FORCE_INLINE iterator begin() const { - if (!_data) return iterator(); - return iterator(_data->head()); - } - FORCE_INLINE iterator end() const { - return iterator(); - } - template <typename TString> - FORCE_INLINE bool containsKey(const TString& key) const { - return !getMember(key).isUndefined(); - } - template <typename TChar> - FORCE_INLINE bool containsKey(TChar* key) const { - return !getMember(key).isUndefined(); - } - template <typename TString> - FORCE_INLINE VariantConstRef getMember(const TString& key) const { - return get_impl(adaptString(key)); - } - template <typename TChar> - FORCE_INLINE VariantConstRef getMember(TChar* key) const { - return get_impl(adaptString(key)); - } - template <typename TString> - FORCE_INLINE - typename enable_if<IsString<TString>::value, VariantConstRef>::type - operator[](const TString& key) const { - return get_impl(adaptString(key)); - } - template <typename TChar> - FORCE_INLINE - typename enable_if<IsString<TChar*>::value, VariantConstRef>::type - operator[](TChar* key) const { - return get_impl(adaptString(key)); - } - FORCE_INLINE bool operator==(ObjectConstRef rhs) const { - return objectEquals(_data, rhs._data); - } - private: - template <typename TAdaptedString> - FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const { - return VariantConstRef(objectGet(_data, key)); - } -}; -class ObjectRef : public ObjectRefBase<CollectionData>, - public ObjectShortcuts<ObjectRef>, - public Visitable { - typedef ObjectRefBase<CollectionData> base_type; - public: - typedef ObjectIterator iterator; - FORCE_INLINE ObjectRef() : base_type(0), _pool(0) {} - FORCE_INLINE ObjectRef(MemoryPool* buf, CollectionData* data) - : base_type(data), _pool(buf) {} - operator VariantRef() const { - void* data = _data; // prevent warning cast-align - return VariantRef(_pool, reinterpret_cast<VariantData*>(data)); - } - operator ObjectConstRef() const { - return ObjectConstRef(_data); - } - FORCE_INLINE iterator begin() const { - if (!_data) return iterator(); - return iterator(_pool, _data->head()); - } - FORCE_INLINE iterator end() const { - return iterator(); - } - void clear() const { - if (!_data) return; - _data->clear(); - } - FORCE_INLINE bool set(ObjectConstRef src) { - if (!_data || !src._data) return false; - return _data->copyFrom(*src._data, _pool); - } - template <typename TString> - FORCE_INLINE VariantRef getMember(const TString& key) const { - return get_impl(adaptString(key)); - } - template <typename TChar> - FORCE_INLINE VariantRef getMember(TChar* key) const { - return get_impl(adaptString(key)); - } - template <typename TString> - FORCE_INLINE VariantRef getOrAddMember(const TString& key) const { - return getOrCreate_impl(adaptString(key)); - } - template <typename TChar> - FORCE_INLINE VariantRef getOrAddMember(TChar* key) const { - return getOrCreate_impl(adaptString(key)); - } - FORCE_INLINE bool operator==(ObjectRef rhs) const { - return objectEquals(_data, rhs._data); - } - FORCE_INLINE void remove(iterator it) const { - if (!_data) return; - _data->remove(it.internal()); - } - template <typename TString> - FORCE_INLINE void remove(const TString& key) const { - objectRemove(_data, adaptString(key)); - } - template <typename TChar> - FORCE_INLINE void remove(TChar* key) const { - objectRemove(_data, adaptString(key)); - } - private: - template <typename TAdaptedString> - FORCE_INLINE VariantRef get_impl(TAdaptedString key) const { - return VariantRef(_pool, objectGet(_data, key)); - } - template <typename TAdaptedString> - FORCE_INLINE VariantRef getOrCreate_impl(TAdaptedString key) const { - return VariantRef(_pool, objectGetOrCreate(_data, key, _pool)); - } - MemoryPool* _pool; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class ArrayRef; -class ObjectRef; -class VariantRef; -template <typename T> -struct VariantTo {}; -template <> -struct VariantTo<ArrayRef> { - typedef ArrayRef type; -}; -template <> -struct VariantTo<ObjectRef> { - typedef ObjectRef type; -}; -template <> -struct VariantTo<VariantRef> { - typedef VariantRef type; -}; -} // namespace ARDUINOJSON_NAMESPACE -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4522) -#endif -namespace ARDUINOJSON_NAMESPACE { -template <typename TArray> -class ElementProxy : public VariantOperators<ElementProxy<TArray> >, - public Visitable { - typedef ElementProxy<TArray> this_type; - public: - FORCE_INLINE ElementProxy(TArray array, size_t index) - : _array(array), _index(index) {} - FORCE_INLINE this_type& operator=(const this_type& src) { - getUpstreamElement().set(src.as<VariantConstRef>()); - return *this; - } - template <typename T> - FORCE_INLINE this_type& operator=(const T& src) { - getUpstreamElement().set(src); - return *this; - } - template <typename T> - FORCE_INLINE this_type& operator=(T* src) { - getUpstreamElement().set(src); - return *this; - } - FORCE_INLINE void clear() const { - getUpstreamElement().clear(); - } - FORCE_INLINE bool isNull() const { - return getUpstreamElement().isNull(); - } - template <typename T> - FORCE_INLINE typename VariantAs<T>::type as() const { - return getUpstreamElement().template as<T>(); - } - template <typename T> - FORCE_INLINE bool is() const { - return getUpstreamElement().template is<T>(); - } - template <typename T> - FORCE_INLINE typename VariantTo<T>::type to() const { - return getUpstreamElement().template to<T>(); - } - template <typename TValue> - FORCE_INLINE bool set(const TValue& value) const { - return getUpstreamElement().set(value); - } - template <typename TValue> - FORCE_INLINE bool set(TValue* value) const { - return getUpstreamElement().set(value); - } - template <typename Visitor> - void accept(Visitor& visitor) const { - return getUpstreamElement().accept(visitor); - } - FORCE_INLINE size_t size() const { - return getUpstreamElement().size(); - } - template <typename TNestedKey> - VariantRef getMember(TNestedKey* key) const { - return getUpstreamElement().getMember(key); - } - template <typename TNestedKey> - VariantRef getMember(const TNestedKey& key) const { - return getUpstreamElement().getMember(key); - } - template <typename TNestedKey> - VariantRef getOrAddMember(TNestedKey* key) const { - return getUpstreamElement().getOrAddMember(key); - } - template <typename TNestedKey> - VariantRef getOrAddMember(const TNestedKey& key) const { - return getUpstreamElement().getOrAddMember(key); - } - VariantRef addElement() const { - return getUpstreamElement().addElement(); - } - VariantRef getElement(size_t index) const { - return getUpstreamElement().getElement(index); - } - FORCE_INLINE void remove(size_t index) const { - getUpstreamElement().remove(index); - } - template <typename TChar> - FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove( - TChar* key) const { - getUpstreamElement().remove(key); - } - template <typename TString> - FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( - const TString& key) const { - getUpstreamElement().remove(key); - } - private: - FORCE_INLINE VariantRef getUpstreamElement() const { - return _array.getElement(_index); - } - TArray _array; - const size_t _index; -}; -template <typename TArray> -inline ElementProxy<const TArray&> ArrayShortcuts<TArray>::operator[]( - size_t index) const { - return ElementProxy<const TArray&>(*impl(), index); -} -} // namespace ARDUINOJSON_NAMESPACE -#ifdef _MSC_VER -#pragma warning(pop) -#endif -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4522) -#endif -namespace ARDUINOJSON_NAMESPACE { -template <typename TObject, typename TStringRef> -class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >, - public Visitable { - typedef MemberProxy<TObject, TStringRef> this_type; - public: - FORCE_INLINE MemberProxy(TObject variant, TStringRef key) - : _object(variant), _key(key) {} - FORCE_INLINE operator VariantConstRef() const { - return getUpstreamMember(); - } - FORCE_INLINE this_type &operator=(const this_type &src) { - getOrAddUpstreamMember().set(src); - return *this; - } - template <typename TValue> - FORCE_INLINE typename enable_if < !is_array<TValue>::value, this_type & >::type - operator=(const TValue &src) { - getOrAddUpstreamMember().set(src); - return *this; - } - template <typename TChar> - FORCE_INLINE this_type &operator=(TChar *src) { - getOrAddUpstreamMember().set(src); - return *this; - } - FORCE_INLINE void clear() const { - getUpstreamMember().clear(); - } - FORCE_INLINE bool isNull() const { - return getUpstreamMember().isNull(); - } - template <typename TValue> - FORCE_INLINE typename VariantAs<TValue>::type as() const { - return getUpstreamMember().template as<TValue>(); - } - template <typename TValue> - FORCE_INLINE bool is() const { - return getUpstreamMember().template is<TValue>(); - } - FORCE_INLINE size_t size() const { - return getUpstreamMember().size(); - } - FORCE_INLINE void remove(size_t index) const { - getUpstreamMember().remove(index); - } - template <typename TChar> - FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove( - TChar *key) const { - getUpstreamMember().remove(key); - } - template <typename TString> - FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( - const TString &key) const { - getUpstreamMember().remove(key); - } - template <typename TValue> - FORCE_INLINE typename VariantTo<TValue>::type to() { - return getOrAddUpstreamMember().template to<TValue>(); - } - template <typename TValue> - FORCE_INLINE typename enable_if < !is_array<TValue>::value, bool >::type set( - const TValue &value) { - return getOrAddUpstreamMember().set(value); - } - template <typename TChar> - FORCE_INLINE bool set(const TChar *value) { - return getOrAddUpstreamMember().set(value); - } - template <typename Visitor> - void accept(Visitor &visitor) const { - return getUpstreamMember().accept(visitor); - } - FORCE_INLINE VariantRef addElement() const { - return getOrAddUpstreamMember().addElement(); - } - FORCE_INLINE VariantRef getElement(size_t index) const { - return getUpstreamMember().getElement(index); - } - template <typename TChar> - FORCE_INLINE VariantRef getMember(TChar *key) const { - return getUpstreamMember().getMember(key); - } - template <typename TString> - FORCE_INLINE VariantRef getMember(const TString &key) const { - return getUpstreamMember().getMember(key); - } - template <typename TChar> - FORCE_INLINE VariantRef getOrAddMember(TChar *key) const { - return getOrAddUpstreamMember().getOrAddMember(key); - } - template <typename TString> - FORCE_INLINE VariantRef getOrAddMember(const TString &key) const { - return getOrAddUpstreamMember().getOrAddMember(key); - } - private: - FORCE_INLINE VariantRef getUpstreamMember() const { - return _object.getMember(_key); - } - FORCE_INLINE VariantRef getOrAddUpstreamMember() const { - return _object.getOrAddMember(_key); - } - TObject _object; - TStringRef _key; -}; -template <typename TObject> -template <typename TString> -inline typename enable_if<IsString<TString>::value, - MemberProxy<const TObject &, const TString &> >::type -ObjectShortcuts<TObject>::operator[](const TString &key) const { - return MemberProxy<const TObject &, const TString &>(*impl(), key); -} -template <typename TObject> -template <typename TString> -inline typename enable_if<IsString<TString *>::value, - MemberProxy<const TObject &, TString *> >::type -ObjectShortcuts<TObject>::operator[](TString *key) const { - return MemberProxy<const TObject &, TString *>(*impl(), key); -} -} // namespace ARDUINOJSON_NAMESPACE -#ifdef _MSC_VER -#pragma warning(pop) -#endif -namespace ARDUINOJSON_NAMESPACE { -class JsonDocument : public Visitable { - public: - template <typename Visitor> - void accept(Visitor& visitor) const { - return getVariant().accept(visitor); - } - template <typename T> - typename VariantAs<T>::type as() { - return getVariant().template as<T>(); - } - template <typename T> - typename VariantConstAs<T>::type as() const { - return getVariant().template as<T>(); - } - void clear() { - _pool.clear(); - _data.setNull(); - } - template <typename T> - bool is() const { - return getVariant().template is<T>(); - } - bool isNull() const { - return getVariant().isNull(); - } - size_t memoryUsage() const { - return _pool.size(); - } - size_t nesting() const { - return _data.nesting(); - } - size_t capacity() const { - return _pool.capacity(); - } - size_t size() const { - return _data.size(); - } - bool set(const JsonDocument& src) { - return to<VariantRef>().set(src.as<VariantRef>()); - } - template <typename T> - typename enable_if < !is_base_of<JsonDocument, T>::value, bool >::type set( - const T& src) { - return to<VariantRef>().set(src); - } - template <typename T> - typename VariantTo<T>::type to() { - clear(); - return getVariant().template to<T>(); - } - MemoryPool& memoryPool() { - return _pool; - } - VariantData& data() { - return _data; - } - ArrayRef createNestedArray() { - return addElement().to<ArrayRef>(); - } - template <typename TChar> - ArrayRef createNestedArray(TChar* key) { - return getOrAddMember(key).template to<ArrayRef>(); - } - template <typename TString> - ArrayRef createNestedArray(const TString& key) { - return getOrAddMember(key).template to<ArrayRef>(); - } - ObjectRef createNestedObject() { - return addElement().to<ObjectRef>(); - } - template <typename TChar> - ObjectRef createNestedObject(TChar* key) { - return getOrAddMember(key).template to<ObjectRef>(); - } - template <typename TString> - ObjectRef createNestedObject(const TString& key) { - return getOrAddMember(key).template to<ObjectRef>(); - } - template <typename TChar> - bool containsKey(TChar* key) const { - return !getMember(key).isUndefined(); - } - template <typename TString> - bool containsKey(const TString& key) const { - return !getMember(key).isUndefined(); - } - template <typename TString> - FORCE_INLINE - typename enable_if<IsString<TString>::value, - MemberProxy<JsonDocument&, const TString&> >::type - operator[](const TString& key) { - return MemberProxy<JsonDocument&, const TString&>(*this, key); - } - template <typename TChar> - FORCE_INLINE typename enable_if<IsString<TChar*>::value, - MemberProxy<JsonDocument&, TChar*> >::type - operator[](TChar* key) { - return MemberProxy<JsonDocument&, TChar*>(*this, key); - } - template <typename TString> - FORCE_INLINE - typename enable_if<IsString<TString>::value, VariantConstRef>::type - operator[](const TString& key) const { - return getMember(key); - } - template <typename TChar> - FORCE_INLINE - typename enable_if<IsString<TChar*>::value, VariantConstRef>::type - operator[](TChar* key) const { - return getMember(key); - } - FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) { - return ElementProxy<JsonDocument&>(*this, index); - } - FORCE_INLINE VariantConstRef operator[](size_t index) const { - return getElement(index); - } - FORCE_INLINE VariantRef getElement(size_t index) { - return VariantRef(&_pool, _data.getElement(index)); - } - FORCE_INLINE VariantConstRef getElement(size_t index) const { - return VariantConstRef(_data.getElement(index)); - } - template <typename TChar> - FORCE_INLINE VariantConstRef getMember(TChar* key) const { - return VariantConstRef(_data.getMember(adaptString(key))); - } - template <typename TString> - FORCE_INLINE - typename enable_if<IsString<TString>::value, VariantConstRef>::type - getMember(const TString& key) const { - return VariantConstRef(_data.getMember(adaptString(key))); - } - template <typename TChar> - FORCE_INLINE VariantRef getMember(TChar* key) { - return VariantRef(&_pool, _data.getMember(adaptString(key))); - } - template <typename TString> - FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type - getMember(const TString& key) { - return VariantRef(&_pool, _data.getMember(adaptString(key))); - } - template <typename TChar> - FORCE_INLINE VariantRef getOrAddMember(TChar* key) { - return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool)); - } - template <typename TString> - FORCE_INLINE VariantRef getOrAddMember(const TString& key) { - return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool)); - } - FORCE_INLINE VariantRef addElement() { - return VariantRef(&_pool, _data.addElement(&_pool)); - } - template <typename TValue> - FORCE_INLINE bool add(const TValue& value) { - return addElement().set(value); - } - template <typename TChar> - FORCE_INLINE bool add(TChar* value) { - return addElement().set(value); - } - FORCE_INLINE void remove(size_t index) { - _data.remove(index); - } - template <typename TChar> - FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove( - TChar* key) { - _data.remove(adaptString(key)); - } - template <typename TString> - FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( - const TString& key) { - _data.remove(adaptString(key)); - } - protected: - JsonDocument(MemoryPool pool) : _pool(pool) { - _data.setNull(); - } - JsonDocument(char* buf, size_t capa) : _pool(buf, capa) { - _data.setNull(); - } - void replacePool(MemoryPool pool) { - _pool = pool; - } - private: - VariantRef getVariant() { - return VariantRef(&_pool, &_data); - } - VariantConstRef getVariant() const { - return VariantConstRef(&_data); - } - MemoryPool _pool; - VariantData _data; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TAllocator> -class AllocatorOwner { - protected: - AllocatorOwner() {} - AllocatorOwner(const AllocatorOwner& src) : _allocator(src._allocator) {} - AllocatorOwner(TAllocator allocator) : _allocator(allocator) {} - void* allocate(size_t n) { - return _allocator.allocate(n); - } - void deallocate(void* p) { - _allocator.deallocate(p); - } - private: - TAllocator _allocator; -}; -template <typename TAllocator> -class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument { - public: - explicit BasicJsonDocument(size_t capa, TAllocator allocator = TAllocator()) - : AllocatorOwner<TAllocator>(allocator), JsonDocument(allocPool(capa)) {} - BasicJsonDocument(const BasicJsonDocument& src) - : AllocatorOwner<TAllocator>(src), - JsonDocument(allocPool(src.memoryUsage())) { - set(src); - } - template <typename T> - BasicJsonDocument(const T& src, - typename enable_if<IsVisitable<T>::value>::type* = 0) - : JsonDocument(allocPool(src.memoryUsage())) { - set(src); - } - BasicJsonDocument(VariantRef src) - : JsonDocument(allocPool(src.memoryUsage())) { - set(src); - } - ~BasicJsonDocument() { - freePool(); - } - BasicJsonDocument& operator=(const BasicJsonDocument& src) { - reallocPoolIfTooSmall(src.memoryUsage()); - set(src); - return *this; - } - template <typename T> - BasicJsonDocument& operator=(const T& src) { - reallocPoolIfTooSmall(src.memoryUsage()); - set(src); - return *this; - } - private: - MemoryPool allocPool(size_t requiredSize) { - size_t capa = addPadding(requiredSize); - return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa); - } - void reallocPoolIfTooSmall(size_t requiredSize) { - if (requiredSize <= capacity()) return; - freePool(); - replacePool(allocPool(addPadding(requiredSize))); - } - void freePool() { - this->deallocate(memoryPool().buffer()); - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -struct DefaultAllocator { - void* allocate(size_t n) { - return malloc(n); - } - void deallocate(void* p) { - free(p); - } -}; -typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <size_t desiredCapacity> -class StaticJsonDocument : public JsonDocument { - static const size_t _capacity = - AddPadding<Max<1, desiredCapacity>::value>::value; - public: - StaticJsonDocument() : JsonDocument(_buffer, _capacity) {} - StaticJsonDocument(const StaticJsonDocument& src) - : JsonDocument(_buffer, _capacity) { - set(src); - } - template <typename T> - StaticJsonDocument(const T& src, - typename enable_if<IsVisitable<T>::value>::type* = 0) - : JsonDocument(_buffer, _capacity) { - set(src); - } - StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, _capacity) { - set(src); - } - StaticJsonDocument operator=(const StaticJsonDocument& src) { - set(src); - return *this; - } - template <typename T> - StaticJsonDocument operator=(const T& src) { - set(src); - return *this; - } - private: - char _buffer[_capacity]; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TArray> -inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const { - return impl()->addElement().template to<ArrayRef>(); -} -template <typename TArray> -inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const { - return impl()->addElement().template to<ObjectRef>(); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T, size_t N> -inline bool copyArray(T (&src)[N], ArrayRef dst) { - return copyArray(src, N, dst); -} -template <typename T> -inline bool copyArray(T* src, size_t len, ArrayRef dst) { - bool ok = true; - for (size_t i = 0; i < len; i++) { - ok &= dst.add(src[i]); - } - return ok; -} -template <typename T, size_t N1, size_t N2> -inline bool copyArray(T (&src)[N1][N2], ArrayRef dst) { - bool ok = true; - for (size_t i = 0; i < N1; i++) { - ArrayRef nestedArray = dst.createNestedArray(); - for (size_t j = 0; j < N2; j++) { - ok &= nestedArray.add(src[i][j]); - } - } - return ok; -} -template <typename T, size_t N> -inline size_t copyArray(ArrayConstRef src, T (&dst)[N]) { - return copyArray(src, dst, N); -} -template <typename T> -inline size_t copyArray(ArrayConstRef src, T* dst, size_t len) { - size_t i = 0; - for (ArrayConstRef::iterator it = src.begin(); it != src.end() && i < len; - ++it) - dst[i++] = *it; - return i; -} -template <typename T, size_t N1, size_t N2> -inline void copyArray(ArrayConstRef src, T (&dst)[N1][N2]) { - size_t i = 0; - for (ArrayConstRef::iterator it = src.begin(); it != src.end() && i < N1; - ++it) { - copyArray(it->as<ArrayConstRef>(), dst[i++]); - } -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) { - VariantSlot* slot = pool->allocVariant(); - if (!slot) return 0; - if (_tail) { - _tail->setNextNotNull(slot); - _tail = slot; - } else { - _head = slot; - _tail = slot; - } - slot->clear(); - return slot; -} -inline VariantData* CollectionData::add(MemoryPool* pool) { - return slotData(addSlot(pool)); -} -template <typename TAdaptedString> -inline VariantData* CollectionData::add(TAdaptedString key, MemoryPool* pool) { - VariantSlot* slot = addSlot(pool); - if (!slotSetKey(slot, key, pool)) return 0; - return slot->data(); -} -inline void CollectionData::clear() { - _head = 0; - _tail = 0; -} -template <typename TAdaptedString> -inline bool CollectionData::containsKey(const TAdaptedString& key) const { - return getSlot(key) != 0; -} -inline bool CollectionData::copyFrom(const CollectionData& src, - MemoryPool* pool) { - clear(); - for (VariantSlot* s = src._head; s; s = s->next()) { - VariantData* var; - if (s->key() != 0) { - if (s->ownsKey()) - var = add(RamStringAdapter(s->key()), pool); - else - var = add(ConstRamStringAdapter(s->key()), pool); - } else { - var = add(pool); - } - if (!var) return false; - if (!var->copyFrom(*s->data(), pool)) return false; - } - return true; -} -inline bool CollectionData::equalsObject(const CollectionData& other) const { - size_t count = 0; - for (VariantSlot* slot = _head; slot; slot = slot->next()) { - VariantData* v1 = slot->data(); - VariantData* v2 = other.get(adaptString(slot->key())); - if (!variantEquals(v1, v2)) return false; - count++; - } - return count == other.size(); -} -inline bool CollectionData::equalsArray(const CollectionData& other) const { - VariantSlot* s1 = _head; - VariantSlot* s2 = other._head; - for (;;) { - if (s1 == s2) return true; - if (!s1 || !s2) return false; - if (!variantEquals(s1->data(), s2->data())) return false; - s1 = s1->next(); - s2 = s2->next(); - } -} -template <typename TAdaptedString> -inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const { - VariantSlot* slot = _head; - while (slot) { - if (key.equals(slot->key())) break; - slot = slot->next(); - } - return slot; -} -inline VariantSlot* CollectionData::getSlot(size_t index) const { - return _head->next(index); -} -inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const { - VariantSlot* current = _head; - while (current) { - VariantSlot* next = current->next(); - if (next == target) return current; - current = next; - } - return 0; -} -template <typename TAdaptedString> -inline VariantData* CollectionData::get(TAdaptedString key) const { - VariantSlot* slot = getSlot(key); - return slot ? slot->data() : 0; -} -inline VariantData* CollectionData::get(size_t index) const { - VariantSlot* slot = getSlot(index); - return slot ? slot->data() : 0; -} -inline void CollectionData::remove(VariantSlot* slot) { - if (!slot) return; - VariantSlot* prev = getPreviousSlot(slot); - VariantSlot* next = slot->next(); - if (prev) - prev->setNext(next); - else - _head = next; - if (!next) _tail = prev; -} -inline void CollectionData::remove(size_t index) { - remove(getSlot(index)); -} -inline size_t CollectionData::memoryUsage() const { - size_t total = 0; - for (VariantSlot* s = _head; s; s = s->next()) { - total += sizeof(VariantSlot) + s->data()->memoryUsage(); - if (s->ownsKey()) total += strlen(s->key()) + 1; - } - return total; -} -inline size_t CollectionData::nesting() const { - size_t maxChildNesting = 0; - for (VariantSlot* s = _head; s; s = s->next()) { - size_t childNesting = s->data()->nesting(); - if (childNesting > maxChildNesting) maxChildNesting = childNesting; - } - return maxChildNesting + 1; -} -inline size_t CollectionData::size() const { - return slotSize(_head); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TObject> -template <typename TString> -inline ArrayRef ObjectShortcuts<TObject>::createNestedArray( - const TString& key) const { - return impl()->getOrAddMember(key).template to<ArrayRef>(); -} -template <typename TObject> -template <typename TChar> -inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(TChar* key) const { - return impl()->getOrAddMember(key).template to<ArrayRef>(); -} -template <typename TObject> -template <typename TString> -inline ObjectRef ObjectShortcuts<TObject>::createNestedObject( - const TString& key) const { - return impl()->getOrAddMember(key).template to<ObjectRef>(); -} -template <typename TObject> -template <typename TChar> -inline ObjectRef ObjectShortcuts<TObject>::createNestedObject( - TChar* key) const { - return impl()->getOrAddMember(key).template to<ObjectRef>(); -} -template <typename TObject> -template <typename TString> -inline typename enable_if<IsString<TString>::value, bool>::type -ObjectShortcuts<TObject>::containsKey(const TString& key) const { - return !impl()->getMember(key).isUndefined(); -} -template <typename TObject> -template <typename TChar> -inline typename enable_if<IsString<TChar*>::value, bool>::type -ObjectShortcuts<TObject>::containsKey(TChar* key) const { - return !impl()->getMember(key).isUndefined(); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -inline typename enable_if<is_same<ArrayConstRef, T>::value, T>::type variantAs( - const VariantData* _data) { - return ArrayConstRef(variantAsArray(_data)); -} -template <typename T> -inline typename enable_if<is_same<ObjectConstRef, T>::value, T>::type variantAs( - const VariantData* _data) { - return ObjectConstRef(variantAsObject(_data)); -} -template <typename T> -inline typename enable_if<is_same<VariantConstRef, T>::value, T>::type -variantAs(const VariantData* _data) { - return VariantConstRef(_data); -} -template <typename T> -inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs( - const VariantData* _data) { - const char* cstr = _data != 0 ? _data->asString() : 0; - if (cstr) return T(cstr); - T s; - serializeJson(VariantConstRef(_data), s); - return s; -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -inline bool isdigit(char c) { - return '0' <= c && c <= '9'; -} -inline bool issign(char c) { - return '-' == c || c == '+'; -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TFloat, typename TUInt> -struct ParsedNumber { - ParsedNumber() : uintValue(0), floatValue(0), _type(VALUE_IS_NULL) {} - ParsedNumber(TUInt value, bool is_negative) - : uintValue(value), - floatValue(TFloat(value)), - _type(uint8_t(is_negative ? VALUE_IS_NEGATIVE_INTEGER - : VALUE_IS_POSITIVE_INTEGER)) {} - ParsedNumber(TFloat value) : floatValue(value), _type(VALUE_IS_FLOAT) {} - template <typename T> - T as() const { - switch (_type) { - case VALUE_IS_NEGATIVE_INTEGER: - return convertNegativeInteger<T>(uintValue); - case VALUE_IS_POSITIVE_INTEGER: - return convertPositiveInteger<T>(uintValue); - case VALUE_IS_FLOAT: - return convertFloat<T>(floatValue); - default: - return 0; - } - } - uint8_t type() const { - return _type; - } - TUInt uintValue; - TFloat floatValue; - uint8_t _type; -}; -template <typename A, typename B> -struct choose_largest : conditional < (sizeof(A) > sizeof(B)), A, B > {}; -template <typename TFloat, typename TUInt> -inline ParsedNumber<TFloat, TUInt> parseNumber(const char *s) { - typedef FloatTraits<TFloat> traits; - typedef typename choose_largest<typename traits::mantissa_type, TUInt>::type - mantissa_t; - typedef typename traits::exponent_type exponent_t; - typedef ParsedNumber<TFloat, TUInt> return_type; - ARDUINOJSON_ASSERT(s != 0); - bool is_negative = false; - switch (*s) { - case '-': - is_negative = true; - s++; - break; - case '+': - s++; - break; - } -#if ARDUINOJSON_ENABLE_NAN - if (*s == 'n' || *s == 'N') return traits::nan(); -#endif -#if ARDUINOJSON_ENABLE_INFINITY - if (*s == 'i' || *s == 'I') - return is_negative ? -traits::inf() : traits::inf(); -#endif - if (!isdigit(*s) && *s != '.') return return_type(); - mantissa_t mantissa = 0; - exponent_t exponent_offset = 0; - const mantissa_t maxUint = TUInt(-1); - while (isdigit(*s)) { - uint8_t digit = uint8_t(*s - '0'); - if (mantissa > maxUint / 10) break; - mantissa *= 10; - if (mantissa > maxUint - digit) break; - mantissa += digit; - s++; - } - if (*s == '\0') return return_type(TUInt(mantissa), is_negative); - while (mantissa > traits::mantissa_max) { - mantissa /= 10; - exponent_offset++; - } - while (isdigit(*s)) { - exponent_offset++; - s++; - } - if (*s == '.') { - s++; - while (isdigit(*s)) { - if (mantissa < traits::mantissa_max / 10) { - mantissa = mantissa * 10 + uint8_t(*s - '0'); - exponent_offset--; - } - s++; - } - } - int exponent = 0; - if (*s == 'e' || *s == 'E') { - s++; - bool negative_exponent = false; - if (*s == '-') { - negative_exponent = true; - s++; - } else if (*s == '+') { - s++; - } - while (isdigit(*s)) { - exponent = exponent * 10 + (*s - '0'); - if (exponent + exponent_offset > traits::exponent_max) { - if (negative_exponent) - return is_negative ? -0.0f : 0.0f; - else - return is_negative ? -traits::inf() : traits::inf(); - } - s++; - } - if (negative_exponent) exponent = -exponent; - } - exponent += exponent_offset; - if (*s != '\0') return return_type(); - TFloat result = traits::make_float(static_cast<TFloat>(mantissa), exponent); - return is_negative ? -result : result; -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -inline T parseFloat(const char* s) { - typedef typename choose_largest<Float, T>::type TFloat; - return parseNumber<TFloat, UInt>(s).template as<T>(); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -T parseInteger(const char *s) { - typedef typename choose_largest<UInt, typename make_unsigned<T>::type>::type - TUInt; - return parseNumber<Float, TUInt>(s).template as<T>(); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -inline T VariantData::asIntegral() const { - switch (type()) { - case VALUE_IS_POSITIVE_INTEGER: - case VALUE_IS_BOOLEAN: - return convertPositiveInteger<T>(_content.asInteger); - case VALUE_IS_NEGATIVE_INTEGER: - return convertNegativeInteger<T>(_content.asInteger); - case VALUE_IS_LINKED_STRING: - case VALUE_IS_OWNED_STRING: - return parseInteger<T>(_content.asString); - case VALUE_IS_FLOAT: - return convertFloat<T>(_content.asFloat); - default: - return 0; - } -} -inline bool VariantData::asBoolean() const { - switch (type()) { - case VALUE_IS_POSITIVE_INTEGER: - case VALUE_IS_BOOLEAN: - case VALUE_IS_NEGATIVE_INTEGER: - return _content.asInteger != 0; - case VALUE_IS_FLOAT: - return _content.asFloat != 0; - case VALUE_IS_LINKED_STRING: - case VALUE_IS_OWNED_STRING: - return strcmp("true", _content.asString) == 0; - default: - return false; - } -} -template <typename T> -inline T VariantData::asFloat() const { - switch (type()) { - case VALUE_IS_POSITIVE_INTEGER: - case VALUE_IS_BOOLEAN: - return static_cast<T>(_content.asInteger); - case VALUE_IS_NEGATIVE_INTEGER: - return -static_cast<T>(_content.asInteger); - case VALUE_IS_LINKED_STRING: - case VALUE_IS_OWNED_STRING: - return parseFloat<T>(_content.asString); - case VALUE_IS_FLOAT: - return static_cast<T>(_content.asFloat); - default: - return 0; - } -} -inline const char *VariantData::asString() const { - switch (type()) { - case VALUE_IS_LINKED_STRING: - case VALUE_IS_OWNED_STRING: - return _content.asString; - default: - return 0; - } -} -template <typename TVariant> -typename enable_if<IsVisitable<TVariant>::value, bool>::type VariantRef::set( - const TVariant &value) const { - VariantConstRef v = value; - return variantCopyFrom(_data, v._data, _pool); -} -template <typename T> -inline typename enable_if<is_same<T, ArrayRef>::value, T>::type VariantRef::as() -const { - return ArrayRef(_pool, _data != 0 ? _data->asArray() : 0); -} -template <typename T> -inline typename enable_if<is_same<T, ObjectRef>::value, T>::type -VariantRef::as() const { - return ObjectRef(_pool, variantAsObject(_data)); -} -template <typename T> -inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type -VariantRef::to() const { - return ArrayRef(_pool, variantToArray(_data)); -} -template <typename T> -typename enable_if<is_same<T, ObjectRef>::value, ObjectRef>::type -VariantRef::to() const { - return ObjectRef(_pool, variantToObject(_data)); -} -template <typename T> -typename enable_if<is_same<T, VariantRef>::value, VariantRef>::type -VariantRef::to() const { - variantSetNull(_data); - return *this; -} -inline VariantConstRef VariantConstRef::operator[](size_t index) const { - return ArrayConstRef(_data != 0 ? _data->asArray() : 0)[index]; -} -inline VariantRef VariantRef::addElement() const { - return VariantRef(_pool, variantAdd(_data, _pool)); -} -inline VariantRef VariantRef::getElement(size_t index) const { - return VariantRef(_pool, _data != 0 ? _data->getElement(index) : 0); -} -template <typename TChar> -inline VariantRef VariantRef::getMember(TChar *key) const { - return VariantRef(_pool, _data != 0 ? _data->getMember(adaptString(key)) : 0); -} -template <typename TString> -inline typename enable_if<IsString<TString>::value, VariantRef>::type -VariantRef::getMember(const TString &key) const { - return VariantRef(_pool, _data != 0 ? _data->getMember(adaptString(key)) : 0); -} -template <typename TChar> -inline VariantRef VariantRef::getOrAddMember(TChar *key) const { - return VariantRef(_pool, variantGetOrCreate(_data, key, _pool)); -} -template <typename TString> -inline VariantRef VariantRef::getOrAddMember(const TString &key) const { - return VariantRef(_pool, variantGetOrCreate(_data, key, _pool)); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class StringBuilder { - public: - explicit StringBuilder(MemoryPool* parent) : _parent(parent), _size(0) { - _slot = _parent->allocExpandableString(); - } - void append(const char* s) { - while (*s) append(*s++); - } - void append(const char* s, size_t n) { - while (n-- > 0) append(*s++); - } - void append(char c) { - if (!_slot.value) return; - if (_size >= _slot.size) { - _slot.value = 0; - return; - } - _slot.value[_size++] = c; - } - char* complete() { - append('\0'); - if (_slot.value) { - _parent->freezeString(_slot, _size); - } - return _slot.value; - } - private: - MemoryPool* _parent; - size_t _size; - StringSlot _slot; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class StringCopier { - public: - typedef ARDUINOJSON_NAMESPACE::StringBuilder StringBuilder; - StringCopier(MemoryPool* pool) : _pool(pool) {} - StringBuilder startString() { - return StringBuilder(_pool); - } - private: - MemoryPool* _pool; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class StringMover { - public: - class StringBuilder { - public: - StringBuilder(char** ptr) : _writePtr(ptr), _startPtr(*ptr) {} - void append(char c) { - *(*_writePtr)++ = char(c); - } - char* complete() const { - *(*_writePtr)++ = 0; - return _startPtr; - } - private: - char** _writePtr; - char* _startPtr; - }; - StringMover(char* ptr) : _ptr(ptr) {} - StringBuilder startString() { - return StringBuilder(&_ptr); - } - private: - char* _ptr; -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TInput, typename Enable = void> -struct StringStorage { - typedef StringCopier type; - static type create(MemoryPool& pool, TInput&) { - return type(&pool); - } -}; -template <typename TChar> -struct StringStorage < TChar*, - typename enable_if < !is_const<TChar>::value >::type > { - typedef StringMover type; - static type create(MemoryPool&, TChar* input) { - return type(reinterpret_cast<char*>(input)); - } -}; -template <typename TInput> -typename StringStorage<TInput>::type makeStringStorage(MemoryPool& pool, - TInput& input) { - return StringStorage<TInput>::create(pool, input); -} -template <typename TChar> -typename StringStorage<TChar*>::type makeStringStorage(MemoryPool& pool, - TChar* input) { - return StringStorage<TChar*>::create(pool, input); -} -} // namespace ARDUINOJSON_NAMESPACE -#if ARDUINOJSON_ENABLE_ARDUINO_STREAM -#include <Stream.h> -namespace ARDUINOJSON_NAMESPACE { -struct ArduinoStreamReader { - Stream& _stream; - public: - explicit ArduinoStreamReader(Stream& stream) : _stream(stream) {} - int read() { - uint8_t c; - return _stream.readBytes(&c, 1) ? c : -1; - } -}; -inline ArduinoStreamReader makeReader(Stream& input) { - return ArduinoStreamReader(input); -} -} // namespace ARDUINOJSON_NAMESPACE -#endif -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -struct IsCharOrVoid { - static const bool value = - is_same<T, void>::value || is_same<T, char>::value || - is_same<T, unsigned char>::value || is_same<T, signed char>::value; -}; -template <typename T> -struct IsCharOrVoid<const T> : IsCharOrVoid<T> {}; -class UnsafeCharPointerReader { - const char* _ptr; - public: - explicit UnsafeCharPointerReader(const char* ptr) - : _ptr(ptr ? ptr : reinterpret_cast<const char*>("")) {} - int read() { - return static_cast<unsigned char>(*_ptr++); - } -}; -class SafeCharPointerReader { - const char* _ptr; - const char* _end; - public: - explicit SafeCharPointerReader(const char* ptr, size_t len) - : _ptr(ptr ? ptr : reinterpret_cast<const char*>("")), _end(_ptr + len) {} - int read() { - if (_ptr < _end) - return static_cast<unsigned char>(*_ptr++); - else - return -1; - } -}; -template <typename TChar> -inline typename enable_if<IsCharOrVoid<TChar>::value, - UnsafeCharPointerReader>::type -makeReader(TChar* input) { - return UnsafeCharPointerReader(reinterpret_cast<const char*>(input)); -} -template <typename TChar> -inline -typename enable_if<IsCharOrVoid<TChar>::value, SafeCharPointerReader>::type -makeReader(TChar* input, size_t n) { - return SafeCharPointerReader(reinterpret_cast<const char*>(input), n); -} -#if ARDUINOJSON_ENABLE_ARDUINO_STRING -inline SafeCharPointerReader makeReader(const ::String& input) { - return SafeCharPointerReader(input.c_str(), input.length()); -} -#endif -} // namespace ARDUINOJSON_NAMESPACE -#if ARDUINOJSON_ENABLE_STD_STREAM -#include <ostream> -#endif -namespace ARDUINOJSON_NAMESPACE { -class DeserializationError { - typedef void (DeserializationError::*bool_type)() const; - void safeBoolHelper() const {} - public: - enum Code { - Ok, - IncompleteInput, - InvalidInput, - NoMemory, - NotSupported, - TooDeep - }; - DeserializationError() {} - DeserializationError(Code c) : _code(c) {} - friend bool operator==(const DeserializationError& lhs, - const DeserializationError& rhs) { - return lhs._code == rhs._code; - } - friend bool operator!=(const DeserializationError& lhs, - const DeserializationError& rhs) { - return lhs._code != rhs._code; - } - friend bool operator==(const DeserializationError& lhs, Code rhs) { - return lhs._code == rhs; - } - friend bool operator==(Code lhs, const DeserializationError& rhs) { - return lhs == rhs._code; - } - friend bool operator!=(const DeserializationError& lhs, Code rhs) { - return lhs._code != rhs; - } - friend bool operator!=(Code lhs, const DeserializationError& rhs) { - return lhs != rhs._code; - } - operator bool_type() const { - return _code != Ok ? &DeserializationError::safeBoolHelper : 0; - } - friend bool operator==(bool value, const DeserializationError& err) { - return static_cast<bool>(err) == value; - } - friend bool operator==(const DeserializationError& err, bool value) { - return static_cast<bool>(err) == value; - } - friend bool operator!=(bool value, const DeserializationError& err) { - return static_cast<bool>(err) != value; - } - friend bool operator!=(const DeserializationError& err, bool value) { - return static_cast<bool>(err) != value; - } - Code code() const { - return _code; - } - const char* c_str() const { - switch (_code) { - case Ok: - return "Ok"; - case TooDeep: - return "TooDeep"; - case NoMemory: - return "NoMemory"; - case InvalidInput: - return "InvalidInput"; - case IncompleteInput: - return "IncompleteInput"; - case NotSupported: - return "NotSupported"; - default: - return "???"; - } - } - private: - Code _code; -}; -#if ARDUINOJSON_ENABLE_STD_STREAM -inline std::ostream& operator<<(std::ostream& s, - const DeserializationError& e) { - s << e.c_str(); - return s; -} -inline std::ostream& operator<<(std::ostream& s, DeserializationError::Code c) { - s << DeserializationError(c).c_str(); - return s; -} -#endif -} // namespace ARDUINOJSON_NAMESPACE -#if ARDUINOJSON_ENABLE_PROGMEM -namespace ARDUINOJSON_NAMESPACE { -class UnsafeFlashStringReader { - const char* _ptr; - public: - explicit UnsafeFlashStringReader(const __FlashStringHelper* ptr) - : _ptr(reinterpret_cast<const char*>(ptr)) {} - int read() { - return pgm_read_byte_near(_ptr++); - } -}; -class SafeFlashStringReader { - const char* _ptr; - const char* _end; - public: - explicit SafeFlashStringReader(const __FlashStringHelper* ptr, size_t size) - : _ptr(reinterpret_cast<const char*>(ptr)), _end(_ptr + size) {} - int read() { - if (_ptr < _end) - return pgm_read_byte_near(_ptr++); - else - return -1; - } -}; -inline UnsafeFlashStringReader makeReader(const __FlashStringHelper* input) { - return UnsafeFlashStringReader(input); -} -inline SafeFlashStringReader makeReader(const __FlashStringHelper* input, - size_t size) { - return SafeFlashStringReader(input, size); -} -} // namespace ARDUINOJSON_NAMESPACE -#endif -namespace ARDUINOJSON_NAMESPACE { -template <typename TIterator> -class IteratorReader { - TIterator _ptr, _end; - public: - explicit IteratorReader(TIterator begin, TIterator end) - : _ptr(begin), _end(end) {} - int read() { - if (_ptr < _end) - return static_cast<unsigned char>(*_ptr++); - else - return -1; - } -}; -template <typename TInput> -inline IteratorReader<typename TInput::const_iterator> makeReader( - const TInput& input) { - return IteratorReader<typename TInput::const_iterator>(input.begin(), - input.end()); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -struct NestingLimit { - NestingLimit() : value(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {} - explicit NestingLimit(uint8_t n) : value(n) {} - uint8_t value; -}; -} // namespace ARDUINOJSON_NAMESPACE -#if ARDUINOJSON_ENABLE_STD_STREAM -#include <istream> -namespace ARDUINOJSON_NAMESPACE { -class StdStreamReader { - std::istream& _stream; - char _current; - public: - explicit StdStreamReader(std::istream& stream) - : _stream(stream), _current(0) {} - int read() { - return _stream.get(); - } - private: - StdStreamReader& operator=(const StdStreamReader&); // Visual Studio C4512 -}; -inline StdStreamReader makeReader(std::istream& input) { - return StdStreamReader(input); -} -} // namespace ARDUINOJSON_NAMESPACE -#endif -namespace ARDUINOJSON_NAMESPACE { -template <template <typename, typename> class TDeserializer, typename TReader, - typename TWriter> -TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool &pool, - TReader reader, TWriter writer, - uint8_t nestingLimit) { - return TDeserializer<TReader, TWriter>(pool, reader, writer, nestingLimit); -} -template <template <typename, typename> class TDeserializer, typename TString> -typename enable_if < !is_array<TString>::value, DeserializationError >::type -deserialize(JsonDocument &doc, const TString &input, - NestingLimit nestingLimit) { - doc.clear(); - return makeDeserializer<TDeserializer>( - doc.memoryPool(), makeReader(input), - makeStringStorage(doc.memoryPool(), input), nestingLimit.value) - .parse(doc.data()); -} -template <template <typename, typename> class TDeserializer, typename TChar> -DeserializationError deserialize(JsonDocument &doc, TChar *input, - NestingLimit nestingLimit) { - doc.clear(); - return makeDeserializer<TDeserializer>( - doc.memoryPool(), makeReader(input), - makeStringStorage(doc.memoryPool(), input), nestingLimit.value) - .parse(doc.data()); -} -template <template <typename, typename> class TDeserializer, typename TChar> -DeserializationError deserialize(JsonDocument &doc, TChar *input, - size_t inputSize, NestingLimit nestingLimit) { - doc.clear(); - return makeDeserializer<TDeserializer>( - doc.memoryPool(), makeReader(input, inputSize), - makeStringStorage(doc.memoryPool(), input), nestingLimit.value) - .parse(doc.data()); -} -template <template <typename, typename> class TDeserializer, typename TStream> -DeserializationError deserialize(JsonDocument &doc, TStream &input, - NestingLimit nestingLimit) { - doc.clear(); - return makeDeserializer<TDeserializer>( - doc.memoryPool(), makeReader(input), - makeStringStorage(doc.memoryPool(), input), nestingLimit.value) - .parse(doc.data()); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class EscapeSequence { - public: - static char escapeChar(char c) { - const char *p = escapeTable(false); - while (p[0] && p[1] != c) { - p += 2; - } - return p[0]; - } - static char unescapeChar(char c) { - const char *p = escapeTable(true); - for (;;) { - if (p[0] == '\0') return c; - if (p[0] == c) return p[1]; - p += 2; - } - } - private: - static const char *escapeTable(bool excludeIdenticals) { - return &"\"\"\\\\b\bf\fn\nr\rt\t"[excludeIdenticals ? 4 : 0]; - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -namespace Utf8 { -template <typename TStringBuilder> -inline void encodeCodepoint(uint16_t codepoint, TStringBuilder &str) { - if (codepoint < 0x80) { - str.append(char(codepoint)); - return; - } - if (codepoint >= 0x00000800) { - str.append(char(0xe0 /*0b11100000*/ | (codepoint >> 12))); - str.append(char(((codepoint >> 6) & 0x3f /*0b00111111*/) | 0x80)); - } else { - str.append(char(0xc0 /*0b11000000*/ | (codepoint >> 6))); - } - str.append(char((codepoint & 0x3f /*0b00111111*/) | 0x80)); -} -} // namespace Utf8 -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TReader, typename TStringStorage> -class JsonDeserializer { - typedef typename remove_reference<TStringStorage>::type::StringBuilder - StringBuilder; - public: - JsonDeserializer(MemoryPool &pool, TReader reader, - TStringStorage stringStorage, uint8_t nestingLimit) - : _pool(&pool), - _reader(reader), - _stringStorage(stringStorage), - _nestingLimit(nestingLimit), - _loaded(false) {} - DeserializationError parse(VariantData &variant) { - DeserializationError err = parseVariant(variant); - if (!err && _current != 0 && !variant.isEnclosed()) { - err = DeserializationError::InvalidInput; - } - return err; - } - private: - JsonDeserializer &operator=(const JsonDeserializer &); // non-copiable - char current() { - if (!_loaded) { - int c = _reader.read(); - _current = static_cast<char>(c > 0 ? c : 0); - _loaded = true; - } - return _current; - } - void move() { - _loaded = false; - } - FORCE_INLINE bool eat(char charToSkip) { - if (current() != charToSkip) return false; - move(); - return true; - } - DeserializationError parseVariant(VariantData &variant) { - DeserializationError err = skipSpacesAndComments(); - if (err) return err; - switch (current()) { - case '[': - return parseArray(variant.toArray()); - case '{': - return parseObject(variant.toObject()); - case '\"': - case '\'': - return parseStringValue(variant); - default: - return parseNumericValue(variant); - } - } - DeserializationError parseArray(CollectionData &array) { - if (_nestingLimit == 0) return DeserializationError::TooDeep; - if (!eat('[')) return DeserializationError::InvalidInput; - DeserializationError err = skipSpacesAndComments(); - if (err) return err; - if (eat(']')) return DeserializationError::Ok; - for (;;) { - VariantData *value = array.add(_pool); - if (!value) return DeserializationError::NoMemory; - _nestingLimit--; - err = parseVariant(*value); - _nestingLimit++; - if (err) return err; - err = skipSpacesAndComments(); - if (err) return err; - if (eat(']')) return DeserializationError::Ok; - if (!eat(',')) return DeserializationError::InvalidInput; - } - } - DeserializationError parseObject(CollectionData &object) { - if (_nestingLimit == 0) return DeserializationError::TooDeep; - if (!eat('{')) return DeserializationError::InvalidInput; - DeserializationError err = skipSpacesAndComments(); - if (err) return err; - if (eat('}')) return DeserializationError::Ok; - for (;;) { - VariantSlot *slot = object.addSlot(_pool); - if (!slot) return DeserializationError::NoMemory; - const char *key; - err = parseKey(key); - if (err) return err; - slot->setOwnedKey(make_not_null(key)); - err = skipSpacesAndComments(); - if (err) return err; // Colon - if (!eat(':')) return DeserializationError::InvalidInput; - _nestingLimit--; - err = parseVariant(*slot->data()); - _nestingLimit++; - if (err) return err; - err = skipSpacesAndComments(); - if (err) return err; - if (eat('}')) return DeserializationError::Ok; - if (!eat(',')) return DeserializationError::InvalidInput; - err = skipSpacesAndComments(); - if (err) return err; - } - } - DeserializationError parseKey(const char *&key) { - if (isQuote(current())) { - return parseQuotedString(key); - } else { - return parseNonQuotedString(key); - } - } - DeserializationError parseStringValue(VariantData &variant) { - const char *value; - DeserializationError err = parseQuotedString(value); - if (err) return err; - variant.setOwnedString(make_not_null(value)); - return DeserializationError::Ok; - } - DeserializationError parseQuotedString(const char *&result) { - StringBuilder builder = _stringStorage.startString(); - const char stopChar = current(); - move(); - for (;;) { - char c = current(); - move(); - if (c == stopChar) break; - if (c == '\0') return DeserializationError::IncompleteInput; - if (c == '\\') { - c = current(); - if (c == '\0') return DeserializationError::IncompleteInput; - if (c == 'u') { -#if ARDUINOJSON_DECODE_UNICODE - uint16_t codepoint; - move(); - DeserializationError err = parseCodepoint(codepoint); - if (err) return err; - Utf8::encodeCodepoint(codepoint, builder); - continue; -#else - return DeserializationError::NotSupported; -#endif - } - c = EscapeSequence::unescapeChar(c); - if (c == '\0') return DeserializationError::InvalidInput; - move(); - } - builder.append(c); - } - result = builder.complete(); - if (!result) return DeserializationError::NoMemory; - return DeserializationError::Ok; - } - DeserializationError parseNonQuotedString(const char *&result) { - StringBuilder builder = _stringStorage.startString(); - char c = current(); - if (c == '\0') return DeserializationError::IncompleteInput; - if (canBeInNonQuotedString(c)) { // no quotes - do { - move(); - builder.append(c); - c = current(); - } while (canBeInNonQuotedString(c)); - } else { - return DeserializationError::InvalidInput; - } - result = builder.complete(); - if (!result) return DeserializationError::NoMemory; - return DeserializationError::Ok; - } - DeserializationError parseNumericValue(VariantData &result) { - char buffer[64]; - uint8_t n = 0; - char c = current(); - while (canBeInNonQuotedString(c) && n < 63) { - move(); - buffer[n++] = c; - c = current(); - } - buffer[n] = 0; - c = buffer[0]; - if (c == 't') { // true - result.setBoolean(true); - return n == 4 ? DeserializationError::Ok - : DeserializationError::IncompleteInput; - } - if (c == 'f') { // false - result.setBoolean(false); - return n == 5 ? DeserializationError::Ok - : DeserializationError::IncompleteInput; - } - if (c == 'n') { // null - return n == 4 ? DeserializationError::Ok - : DeserializationError::IncompleteInput; - } - ParsedNumber<Float, UInt> num = parseNumber<Float, UInt>(buffer); - switch (num.type()) { - case VALUE_IS_NEGATIVE_INTEGER: - result.setNegativeInteger(num.uintValue); - return DeserializationError::Ok; - case VALUE_IS_POSITIVE_INTEGER: - result.setPositiveInteger(num.uintValue); - return DeserializationError::Ok; - case VALUE_IS_FLOAT: - result.setFloat(num.floatValue); - return DeserializationError::Ok; - } - return DeserializationError::InvalidInput; - } - DeserializationError parseCodepoint(uint16_t &codepoint) { - codepoint = 0; - for (uint8_t i = 0; i < 4; ++i) { - char digit = current(); - if (!digit) return DeserializationError::IncompleteInput; - uint8_t value = decodeHex(digit); - if (value > 0x0F) return DeserializationError::InvalidInput; - codepoint = uint16_t((codepoint << 4) | value); - move(); - } - return DeserializationError::Ok; - } - static inline bool isBetween(char c, char min, char max) { - return min <= c && c <= max; - } - static inline bool canBeInNonQuotedString(char c) { - return isBetween(c, '0', '9') || isBetween(c, '_', 'z') || - isBetween(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; - } - static inline bool isQuote(char c) { - return c == '\'' || c == '\"'; - } - static inline uint8_t decodeHex(char c) { - if (c < 'A') return uint8_t(c - '0'); - c = char(c & ~0x20); // uppercase - return uint8_t(c - 'A' + 10); - } - DeserializationError skipSpacesAndComments() { - for (;;) { - switch (current()) { - case '\0': - return DeserializationError::IncompleteInput; - case ' ': - case '\t': - case '\r': - case '\n': - move(); - continue; - case '/': - move(); // skip '/' - switch (current()) { - case '*': { - move(); // skip '*' - bool wasStar = false; - for (;;) { - char c = current(); - if (c == '\0') return DeserializationError::IncompleteInput; - if (c == '/' && wasStar) { - move(); - break; - } - wasStar = c == '*'; - move(); - } - break; - } - case '/': - for (;;) { - move(); - char c = current(); - if (c == '\0') return DeserializationError::IncompleteInput; - if (c == '\n') break; - } - break; - default: - return DeserializationError::InvalidInput; - } - break; - default: - return DeserializationError::Ok; - } - } - } - MemoryPool *_pool; - TReader _reader; - TStringStorage _stringStorage; - uint8_t _nestingLimit; - char _current; - bool _loaded; -}; -template <typename TInput> -DeserializationError deserializeJson( - JsonDocument &doc, const TInput &input, - NestingLimit nestingLimit = NestingLimit()) { - return deserialize<JsonDeserializer>(doc, input, nestingLimit); -} -template <typename TInput> -DeserializationError deserializeJson( - JsonDocument &doc, TInput *input, - NestingLimit nestingLimit = NestingLimit()) { - return deserialize<JsonDeserializer>(doc, input, nestingLimit); -} -template <typename TInput> -DeserializationError deserializeJson( - JsonDocument &doc, TInput *input, size_t inputSize, - NestingLimit nestingLimit = NestingLimit()) { - return deserialize<JsonDeserializer>(doc, input, inputSize, nestingLimit); -} -template <typename TInput> -DeserializationError deserializeJson( - JsonDocument &doc, TInput &input, - NestingLimit nestingLimit = NestingLimit()) { - return deserialize<JsonDeserializer>(doc, input, nestingLimit); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class DummyWriter { - public: - size_t write(uint8_t) { - return 1; - } - size_t write(const uint8_t*, size_t n) { - return n; - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <template <typename> class TSerializer, typename TSource> -size_t measure(const TSource &source) { - DummyWriter dp; - TSerializer<DummyWriter> serializer(dp); - source.accept(serializer); - return serializer.bytesWritten(); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -class StaticStringWriter { - public: - StaticStringWriter(char *buf, size_t size) : end(buf + size - 1), p(buf) { - *p = '\0'; - } - size_t write(uint8_t c) { - if (p >= end) return 0; - *p++ = static_cast<char>(c); - *p = '\0'; - return 1; - } - size_t write(const uint8_t *s, size_t n) { - char *begin = p; - while (p < end && n > 0) { - *p++ = static_cast<char>(*s++); - n--; - } - *p = '\0'; - return size_t(p - begin); - } - private: - char *end; - char *p; -}; -} // namespace ARDUINOJSON_NAMESPACE -#if ARDUINOJSON_ENABLE_STD_STREAM -#if ARDUINOJSON_ENABLE_STD_STREAM -namespace ARDUINOJSON_NAMESPACE { -class StreamWriter { - public: - explicit StreamWriter(std::ostream& os) : _os(os) {} - size_t write(uint8_t c) { - _os << c; - return 1; - } - size_t write(const uint8_t* s, size_t n) { - _os.write(reinterpret_cast<const char*>(s), - static_cast<std::streamsize>(n)); - return n; - } - private: - StreamWriter& operator=(const StreamWriter&); - std::ostream& _os; -}; -} // namespace ARDUINOJSON_NAMESPACE -#endif // ARDUINOJSON_ENABLE_STD_STREAM -#endif -namespace ARDUINOJSON_NAMESPACE { -template <template <typename> class TSerializer, typename TSource, - typename TDestination> -size_t doSerialize(const TSource &source, TDestination &destination) { - TSerializer<TDestination> serializer(destination); - source.accept(serializer); - return serializer.bytesWritten(); -} -#if ARDUINOJSON_ENABLE_STD_STREAM -template <template <typename> class TSerializer, typename TSource> -size_t serialize(const TSource &source, std::ostream &destination) { - StreamWriter writer(destination); - return doSerialize<TSerializer>(source, writer); -} -#endif -#if ARDUINOJSON_ENABLE_ARDUINO_PRINT -template <template <typename> class TSerializer, typename TSource> -size_t serialize(const TSource &source, Print &destination) { - return doSerialize<TSerializer>(source, destination); -} -#endif -template <template <typename> class TSerializer, typename TSource> -size_t serialize(const TSource &source, char *buffer, size_t bufferSize) { - StaticStringWriter writer(buffer, bufferSize); - return doSerialize<TSerializer>(source, writer); -} -template <template <typename> class TSerializer, typename TSource, size_t N> -size_t serialize(const TSource &source, char (&buffer)[N]) { - StaticStringWriter writer(buffer, N); - return doSerialize<TSerializer>(source, writer); -} -template <template <typename> class TSerializer, typename TSource, - typename TString> -typename enable_if<IsWriteableString<TString>::value, size_t>::type serialize( - const TSource &source, TString &str) { - DynamicStringWriter<TString> writer(str); - return doSerialize<TSerializer>(source, writer); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TFloat> -struct FloatParts { - uint32_t integral; - uint32_t decimal; - int16_t exponent; - int8_t decimalPlaces; - FloatParts(TFloat value) { - uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000; - decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6; - exponent = normalize(value); - integral = uint32_t(value); - for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) { - maxDecimalPart /= 10; - decimalPlaces--; - } - TFloat remainder = (value - TFloat(integral)) * TFloat(maxDecimalPart); - decimal = uint32_t(remainder); - remainder = remainder - TFloat(decimal); - decimal += uint32_t(remainder * 2); - if (decimal >= maxDecimalPart) { - decimal = 0; - integral++; - if (exponent && integral >= 10) { - exponent++; - integral = 1; - } - } - while (decimal % 10 == 0 && decimalPlaces > 0) { - decimal /= 10; - decimalPlaces--; - } - } - static int16_t normalize(TFloat& value) { - typedef FloatTraits<TFloat> traits; - int16_t powersOf10 = 0; - int8_t index = sizeof(TFloat) == 8 ? 8 : 5; - int bit = 1 << index; - if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) { - for (; index >= 0; index--) { - if (value >= traits::positiveBinaryPowerOfTen(index)) { - value *= traits::negativeBinaryPowerOfTen(index); - powersOf10 = int16_t(powersOf10 + bit); - } - bit >>= 1; - } - } - if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) { - for (; index >= 0; index--) { - if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) { - value *= traits::positiveBinaryPowerOfTen(index); - powersOf10 = int16_t(powersOf10 - bit); - } - bit >>= 1; - } - } - return powersOf10; - } -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TWriter> -class TextFormatter { - public: - explicit TextFormatter(TWriter &writer) : _writer(writer), _length(0) {} - size_t bytesWritten() const { - return _length; - } - void writeBoolean(bool value) { - if (value) - writeRaw("true"); - else - writeRaw("false"); - } - void writeString(const char *value) { - if (!value) { - writeRaw("null"); - } else { - writeRaw('\"'); - while (*value) writeChar(*value++); - writeRaw('\"'); - } - } - void writeChar(char c) { - char specialChar = EscapeSequence::escapeChar(c); - if (specialChar) { - writeRaw('\\'); - writeRaw(specialChar); - } else { - writeRaw(c); - } - } - template <typename T> - void writeFloat(T value) { - if (isnan(value)) return writeRaw(ARDUINOJSON_ENABLE_NAN ? "NaN" : "null"); -#if ARDUINOJSON_ENABLE_INFINITY - if (value < 0.0) { - writeRaw('-'); - value = -value; - } - if (isinf(value)) return writeRaw("Infinity"); -#else - if (isinf(value)) return writeRaw("null"); - if (value < 0.0) { - writeRaw('-'); - value = -value; - } -#endif - FloatParts<T> parts(value); - writePositiveInteger(parts.integral); - if (parts.decimalPlaces) writeDecimals(parts.decimal, parts.decimalPlaces); - if (parts.exponent < 0) { - writeRaw("e-"); - writePositiveInteger(-parts.exponent); - } - if (parts.exponent > 0) { - writeRaw('e'); - writePositiveInteger(parts.exponent); - } - } - void writeNegativeInteger(UInt value) { - writeRaw('-'); - writePositiveInteger(value); - } - template <typename T> - void writePositiveInteger(T value) { - char buffer[22]; - char *end = buffer + sizeof(buffer); - char *begin = end; - do { - *--begin = char(value % 10 + '0'); - value = T(value / 10); - } while (value); - writeRaw(begin, end); - } - void writeDecimals(uint32_t value, int8_t width) { - char buffer[16]; - char *end = buffer + sizeof(buffer); - char *begin = end; - while (width--) { - *--begin = char(value % 10 + '0'); - value /= 10; - } - *--begin = '.'; - writeRaw(begin, end); - } - void writeRaw(const char *s) { - _length += _writer.write(reinterpret_cast<const uint8_t *>(s), strlen(s)); - } - void writeRaw(const char *s, size_t n) { - _length += _writer.write(reinterpret_cast<const uint8_t *>(s), n); - } - void writeRaw(const char *begin, const char *end) { - _length += _writer.write(reinterpret_cast<const uint8_t *>(begin), - static_cast<size_t>(end - begin)); - } - template <size_t N> - void writeRaw(const char (&s)[N]) { - _length += _writer.write(reinterpret_cast<const uint8_t *>(s), N - 1); - } - void writeRaw(char c) { - _length += _writer.write(static_cast<uint8_t>(c)); - } - protected: - TWriter &_writer; - size_t _length; - private: - TextFormatter &operator=(const TextFormatter &); // cannot be assigned -}; -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TWriter> -class JsonSerializer { - public: - JsonSerializer(TWriter &writer) : _formatter(writer) {} - FORCE_INLINE void visitArray(const CollectionData &array) { - write('['); - VariantSlot *slot = array.head(); - while (slot != 0) { - slot->data()->accept(*this); - slot = slot->next(); - if (slot == 0) break; - write(','); - } - write(']'); - } - void visitObject(const CollectionData &object) { - write('{'); - VariantSlot *slot = object.head(); - while (slot != 0) { - _formatter.writeString(slot->key()); - write(':'); - slot->data()->accept(*this); - slot = slot->next(); - if (slot == 0) break; - write(','); - } - write('}'); - } - void visitFloat(Float value) { - _formatter.writeFloat(value); - } - void visitString(const char *value) { - _formatter.writeString(value); - } - void visitRawJson(const char *data, size_t n) { - _formatter.writeRaw(data, n); - } - void visitNegativeInteger(UInt value) { - _formatter.writeNegativeInteger(value); - } - void visitPositiveInteger(UInt value) { - _formatter.writePositiveInteger(value); - } - void visitBoolean(bool value) { - _formatter.writeBoolean(value); - } - void visitNull() { - _formatter.writeRaw("null"); - } - size_t bytesWritten() const { - return _formatter.bytesWritten(); - } - protected: - void write(char c) { - _formatter.writeRaw(c); - } - void write(const char *s) { - _formatter.writeRaw(s); - } - private: - TextFormatter<TWriter> _formatter; -}; -template <typename TSource, typename TDestination> -size_t serializeJson(const TSource &source, TDestination &destination) { - return serialize<JsonSerializer>(source, destination); -} -template <typename TSource> -size_t serializeJson(const TSource &source, char *buffer, size_t bufferSize) { - return serialize<JsonSerializer>(source, buffer, bufferSize); -} -template <typename TSource> -size_t measureJson(const TSource &source) { - return measure<JsonSerializer>(source); -} -#if ARDUINOJSON_ENABLE_STD_STREAM -template <typename T> -inline typename enable_if<IsVisitable<T>::value, std::ostream &>::type -operator<<(std::ostream &os, const T &source) { - serializeJson(source, os); - return os; -} -#endif -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TWriter> -class PrettyJsonSerializer : public JsonSerializer<TWriter> { - typedef JsonSerializer<TWriter> base; - public: - PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {} - void visitArray(const CollectionData &array) { - VariantSlot *slot = array.head(); - if (!slot) return base::write("[]"); - base::write("[\r\n"); - _nesting++; - while (slot != 0) { - indent(); - slot->data()->accept(*this); - slot = slot->next(); - base::write(slot ? ",\r\n" : "\r\n"); - } - _nesting--; - indent(); - base::write("]"); - } - void visitObject(const CollectionData &object) { - VariantSlot *slot = object.head(); - if (!slot) return base::write("{}"); - base::write("{\r\n"); - _nesting++; - while (slot != 0) { - indent(); - base::visitString(slot->key()); - base::write(": "); - slot->data()->accept(*this); - slot = slot->next(); - base::write(slot ? ",\r\n" : "\r\n"); - } - _nesting--; - indent(); - base::write("}"); - } - private: - void indent() { - for (uint8_t i = 0; i < _nesting; i++) base::write(ARDUINOJSON_TAB); - } - uint8_t _nesting; -}; -template <typename TSource, typename TDestination> -size_t serializeJsonPretty(const TSource &source, TDestination &destination) { - return serialize<PrettyJsonSerializer>(source, destination); -} -template <typename TSource> -size_t serializeJsonPretty(const TSource &source, char *buffer, - size_t bufferSize) { - return serialize<PrettyJsonSerializer>(source, buffer, bufferSize); -} -template <typename TSource> -size_t measureJsonPretty(const TSource &source) { - return measure<PrettyJsonSerializer>(source); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename T> -inline void swap(T& a, T& b) { - T t(a); - a = b; - b = t; -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -#if ARDUINOJSON_LITTLE_ENDIAN -inline void fixEndianess(uint8_t *p, integral_constant<size_t, 8>) { - swap(p[0], p[7]); - swap(p[1], p[6]); - swap(p[2], p[5]); - swap(p[3], p[4]); -} -inline void fixEndianess(uint8_t *p, integral_constant<size_t, 4>) { - swap(p[0], p[3]); - swap(p[1], p[2]); -} -inline void fixEndianess(uint8_t *p, integral_constant<size_t, 2>) { - swap(p[0], p[1]); -} -inline void fixEndianess(uint8_t *, integral_constant<size_t, 1>) {} -template <typename T> -inline void fixEndianess(T &value) { - fixEndianess(reinterpret_cast<uint8_t *>(&value), - integral_constant<size_t, sizeof(T)>()); -} -#else -template <typename T> -inline void fixEndianess(T &) {} -#endif -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -inline void doubleToFloat(const uint8_t d[8], uint8_t f[4]) { - f[0] = uint8_t((d[0] & 0xC0) | (d[0] << 3 & 0x3f) | (d[1] >> 5)); - f[1] = uint8_t((d[1] << 3) | (d[2] >> 5)); - f[2] = uint8_t((d[2] << 3) | (d[3] >> 5)); - f[3] = uint8_t((d[3] << 3) | (d[4] >> 5)); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TReader, typename TStringStorage> -class MsgPackDeserializer { - typedef typename remove_reference<TStringStorage>::type::StringBuilder - StringBuilder; - public: - MsgPackDeserializer(MemoryPool &pool, TReader reader, - TStringStorage stringStorage, uint8_t nestingLimit) - : _pool(&pool), - _reader(reader), - _stringStorage(stringStorage), - _nestingLimit(nestingLimit) {} - DeserializationError parse(VariantData &variant) { - uint8_t code; - if (!readByte(code)) return DeserializationError::IncompleteInput; - if ((code & 0x80) == 0) { - variant.setUnsignedInteger(code); - return DeserializationError::Ok; - } - if ((code & 0xe0) == 0xe0) { - variant.setSignedInteger(static_cast<int8_t>(code)); - return DeserializationError::Ok; - } - if ((code & 0xe0) == 0xa0) { - return readString(variant, code & 0x1f); - } - if ((code & 0xf0) == 0x90) { - return readArray(variant.toArray(), code & 0x0F); - } - if ((code & 0xf0) == 0x80) { - return readObject(variant.toObject(), code & 0x0F); - } - switch (code) { - case 0xc0: - return DeserializationError::Ok; - case 0xc2: - variant.setBoolean(false); - return DeserializationError::Ok; - case 0xc3: - variant.setBoolean(true); - return DeserializationError::Ok; - case 0xcc: - return readInteger<uint8_t>(variant); - case 0xcd: - return readInteger<uint16_t>(variant); - case 0xce: - return readInteger<uint32_t>(variant); - case 0xcf: -#if ARDUINOJSON_USE_LONG_LONG - return readInteger<uint64_t>(variant); -#else - return DeserializationError::NotSupported; -#endif - case 0xd0: - return readInteger<int8_t>(variant); - case 0xd1: - return readInteger<int16_t>(variant); - case 0xd2: - return readInteger<int32_t>(variant); - case 0xd3: -#if ARDUINOJSON_USE_LONG_LONG - return readInteger<int64_t>(variant); -#else - return DeserializationError::NotSupported; -#endif - case 0xca: - return readFloat<float>(variant); - case 0xcb: - return readDouble<double>(variant); - case 0xd9: - return readString<uint8_t>(variant); - case 0xda: - return readString<uint16_t>(variant); - case 0xdb: - return readString<uint32_t>(variant); - case 0xdc: - return readArray<uint16_t>(variant.toArray()); - case 0xdd: - return readArray<uint32_t>(variant.toArray()); - case 0xde: - return readObject<uint16_t>(variant.toObject()); - case 0xdf: - return readObject<uint32_t>(variant.toObject()); - default: - return DeserializationError::NotSupported; - } - } - private: - MsgPackDeserializer &operator=(const MsgPackDeserializer &); - bool readByte(uint8_t &value) { - int c = _reader.read(); - if (c < 0) return false; - value = static_cast<uint8_t>(c); - return true; - } - bool readBytes(uint8_t *p, size_t n) { - for (size_t i = 0; i < n; i++) { - if (!readByte(p[i])) return false; - } - return true; - } - template <typename T> - bool readBytes(T &value) { - return readBytes(reinterpret_cast<uint8_t *>(&value), sizeof(value)); - } - template <typename T> - T readInteger() { - T value; - readBytes(value); - fixEndianess(value); - return value; - } - template <typename T> - bool readInteger(T &value) { - if (!readBytes(value)) return false; - fixEndianess(value); - return true; - } - template <typename T> - DeserializationError readInteger(VariantData &variant) { - T value; - if (!readInteger(value)) return DeserializationError::IncompleteInput; - variant.setInteger(value); - return DeserializationError::Ok; - } - template <typename T> - typename enable_if<sizeof(T) == 4, DeserializationError>::type readFloat( - VariantData &variant) { - T value; - if (!readBytes(value)) return DeserializationError::IncompleteInput; - fixEndianess(value); - variant.setFloat(value); - return DeserializationError::Ok; - } - template <typename T> - typename enable_if<sizeof(T) == 8, DeserializationError>::type readDouble( - VariantData &variant) { - T value; - if (!readBytes(value)) return DeserializationError::IncompleteInput; - fixEndianess(value); - variant.setFloat(value); - return DeserializationError::Ok; - } - template <typename T> - typename enable_if<sizeof(T) == 4, DeserializationError>::type readDouble( - VariantData &variant) { - uint8_t i[8]; // input is 8 bytes - T value; // output is 4 bytes - uint8_t *o = reinterpret_cast<uint8_t *>(&value); - if (!readBytes(i, 8)) return DeserializationError::IncompleteInput; - doubleToFloat(i, o); - fixEndianess(value); - variant.setFloat(value); - return DeserializationError::Ok; - } - template <typename T> - DeserializationError readString(VariantData &variant) { - T size; - if (!readInteger(size)) return DeserializationError::IncompleteInput; - return readString(variant, size); - } - template <typename T> - DeserializationError readString(const char *&str) { - T size; - if (!readInteger(size)) return DeserializationError::IncompleteInput; - return readString(str, size); - } - DeserializationError readString(VariantData &variant, size_t n) { - const char *s; - DeserializationError err = readString(s, n); - if (!err) variant.setOwnedString(make_not_null(s)); - return err; - } - DeserializationError readString(const char *&result, size_t n) { - StringBuilder builder = _stringStorage.startString(); - for (; n; --n) { - uint8_t c; - if (!readBytes(c)) return DeserializationError::IncompleteInput; - builder.append(static_cast<char>(c)); - } - result = builder.complete(); - if (!result) return DeserializationError::NoMemory; - return DeserializationError::Ok; - } - template <typename TSize> - DeserializationError readArray(CollectionData &array) { - TSize size; - if (!readInteger(size)) return DeserializationError::IncompleteInput; - return readArray(array, size); - } - DeserializationError readArray(CollectionData &array, size_t n) { - if (_nestingLimit == 0) return DeserializationError::TooDeep; - --_nestingLimit; - for (; n; --n) { - VariantData *value = array.add(_pool); - if (!value) return DeserializationError::NoMemory; - DeserializationError err = parse(*value); - if (err) return err; - } - ++_nestingLimit; - return DeserializationError::Ok; - } - template <typename TSize> - DeserializationError readObject(CollectionData &object) { - TSize size; - if (!readInteger(size)) return DeserializationError::IncompleteInput; - return readObject(object, size); - } - DeserializationError readObject(CollectionData &object, size_t n) { - if (_nestingLimit == 0) return DeserializationError::TooDeep; - --_nestingLimit; - for (; n; --n) { - VariantSlot *slot = object.addSlot(_pool); - if (!slot) return DeserializationError::NoMemory; - const char *key; - DeserializationError err = parseKey(key); - if (err) return err; - slot->setOwnedKey(make_not_null(key)); - err = parse(*slot->data()); - if (err) return err; - } - ++_nestingLimit; - return DeserializationError::Ok; - } - DeserializationError parseKey(const char *&key) { - uint8_t code; - if (!readByte(code)) return DeserializationError::IncompleteInput; - if ((code & 0xe0) == 0xa0) return readString(key, code & 0x1f); - switch (code) { - case 0xd9: - return readString<uint8_t>(key); - case 0xda: - return readString<uint16_t>(key); - case 0xdb: - return readString<uint32_t>(key); - default: - return DeserializationError::NotSupported; - } - } - MemoryPool *_pool; - TReader _reader; - TStringStorage _stringStorage; - uint8_t _nestingLimit; -}; -template <typename TInput> -DeserializationError deserializeMsgPack( - JsonDocument &doc, const TInput &input, - NestingLimit nestingLimit = NestingLimit()) { - return deserialize<MsgPackDeserializer>(doc, input, nestingLimit); -} -template <typename TInput> -DeserializationError deserializeMsgPack( - JsonDocument &doc, TInput *input, - NestingLimit nestingLimit = NestingLimit()) { - return deserialize<MsgPackDeserializer>(doc, input, nestingLimit); -} -template <typename TInput> -DeserializationError deserializeMsgPack( - JsonDocument &doc, TInput *input, size_t inputSize, - NestingLimit nestingLimit = NestingLimit()) { - return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit); -} -template <typename TInput> -DeserializationError deserializeMsgPack( - JsonDocument &doc, TInput &input, - NestingLimit nestingLimit = NestingLimit()) { - return deserialize<MsgPackDeserializer>(doc, input, nestingLimit); -} -} // namespace ARDUINOJSON_NAMESPACE -namespace ARDUINOJSON_NAMESPACE { -template <typename TWriter> -class MsgPackSerializer { - public: - MsgPackSerializer(TWriter& writer) : _writer(&writer), _bytesWritten(0) {} - template <typename T> - typename enable_if<sizeof(T) == 4>::type visitFloat(T value32) { - writeByte(0xCA); - writeInteger(value32); - } - template <typename T> - ARDUINOJSON_NO_SANITIZE("float-cast-overflow") - typename enable_if<sizeof(T) == 8>::type visitFloat(T value64) { - float value32 = float(value64); - if (value32 == value64) { - writeByte(0xCA); - writeInteger(value32); - } else { - writeByte(0xCB); - writeInteger(value64); - } - } - void visitArray(const CollectionData& array) { - size_t n = array.size(); - if (n < 0x10) { - writeByte(uint8_t(0x90 + array.size())); - } else if (n < 0x10000) { - writeByte(0xDC); - writeInteger(uint16_t(n)); - } else { - writeByte(0xDD); - writeInteger(uint32_t(n)); - } - for (VariantSlot* slot = array.head(); slot; slot = slot->next()) { - slot->data()->accept(*this); - } - } - void visitObject(const CollectionData& object) { - size_t n = object.size(); - if (n < 0x10) { - writeByte(uint8_t(0x80 + n)); - } else if (n < 0x10000) { - writeByte(0xDE); - writeInteger(uint16_t(n)); - } else { - writeByte(0xDF); - writeInteger(uint32_t(n)); - } - for (VariantSlot* slot = object.head(); slot; slot = slot->next()) { - visitString(slot->key()); - slot->data()->accept(*this); - } - } - void visitString(const char* value) { - if (!value) return writeByte(0xC0); // nil - size_t n = strlen(value); - if (n < 0x20) { - writeByte(uint8_t(0xA0 + n)); - } else if (n < 0x100) { - writeByte(0xD9); - writeInteger(uint8_t(n)); - } else if (n < 0x10000) { - writeByte(0xDA); - writeInteger(uint16_t(n)); - } else { - writeByte(0xDB); - writeInteger(uint32_t(n)); - } - writeBytes(reinterpret_cast<const uint8_t*>(value), n); - } - void visitRawJson(const char* data, size_t size) { - writeBytes(reinterpret_cast<const uint8_t*>(data), size); - } - void visitNegativeInteger(UInt value) { - UInt negated = UInt(~value + 1); - if (value <= 0x20) { - writeInteger(int8_t(negated)); - } else if (value <= 0x80) { - writeByte(0xD0); - writeInteger(int8_t(negated)); - } else if (value <= 0x8000) { - writeByte(0xD1); - writeInteger(int16_t(negated)); - } else if (value <= 0x80000000) { - writeByte(0xD2); - writeInteger(int32_t(negated)); - } -#if ARDUINOJSON_USE_LONG_LONG - else { - writeByte(0xD3); - writeInteger(int64_t(negated)); - } -#endif - } - void visitPositiveInteger(UInt value) { - if (value <= 0x7F) { - writeInteger(uint8_t(value)); - } else if (value <= 0xFF) { - writeByte(0xCC); - writeInteger(uint8_t(value)); - } else if (value <= 0xFFFF) { - writeByte(0xCD); - writeInteger(uint16_t(value)); - } else if (value <= 0xFFFFFFFF) { - writeByte(0xCE); - writeInteger(uint32_t(value)); - } -#if ARDUINOJSON_USE_LONG_LONG - else { - writeByte(0xCF); - writeInteger(uint64_t(value)); - } -#endif - } - void visitBoolean(bool value) { - writeByte(value ? 0xC3 : 0xC2); - } - void visitNull() { - writeByte(0xC0); - } - size_t bytesWritten() const { - return _bytesWritten; - } - private: - void writeByte(uint8_t c) { - _bytesWritten += _writer->write(c); - } - void writeBytes(const uint8_t* p, size_t n) { - _bytesWritten += _writer->write(p, n); - } - template <typename T> - void writeInteger(T value) { - fixEndianess(value); - writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value)); - } - TWriter* _writer; - size_t _bytesWritten; -}; -template <typename TSource, typename TDestination> -inline size_t serializeMsgPack(const TSource& source, TDestination& output) { - return serialize<MsgPackSerializer>(source, output); -} -template <typename TSource, typename TDestination> -inline size_t serializeMsgPack(const TSource& source, TDestination* output, - size_t size) { - return serialize<MsgPackSerializer>(source, output, size); -} -template <typename TSource> -inline size_t measureMsgPack(const TSource& source) { - return measure<MsgPackSerializer>(source); -} -} // namespace ARDUINOJSON_NAMESPACE -#ifdef __GNUC__ -#define ARDUINOJSON_PRAGMA(x) _Pragma(#x) -#define ARDUINOJSON_COMPILE_ERROR(msg) ARDUINOJSON_PRAGMA(GCC error msg) -#define ARDUINOJSON_STRINGIFY(S) #S -#define ARDUINOJSON_DEPRECATION_ERROR(X, Y) \ - ARDUINOJSON_COMPILE_ERROR(ARDUINOJSON_STRINGIFY(X is a Y from ArduinoJson 5. Please see arduinojson.org/upgrade to learn how to upgrade your program to ArduinoJson version 6)) -#define StaticJsonBuffer ARDUINOJSON_DEPRECATION_ERROR(StaticJsonBuffer, class) -#define DynamicJsonBuffer ARDUINOJSON_DEPRECATION_ERROR(DynamicJsonBuffer, class) -#define JsonBuffer ARDUINOJSON_DEPRECATION_ERROR(JsonBuffer, class) -#define RawJson ARDUINOJSON_DEPRECATION_ERROR(RawJson, function) -#endif -namespace ArduinoJson { -typedef ARDUINOJSON_NAMESPACE::ArrayConstRef JsonArrayConst; -typedef ARDUINOJSON_NAMESPACE::ArrayRef JsonArray; -typedef ARDUINOJSON_NAMESPACE::Float JsonFloat; -typedef ARDUINOJSON_NAMESPACE::Integer JsonInteger; -typedef ARDUINOJSON_NAMESPACE::ObjectConstRef JsonObjectConst; -typedef ARDUINOJSON_NAMESPACE::ObjectRef JsonObject; -typedef ARDUINOJSON_NAMESPACE::Pair JsonPair; -typedef ARDUINOJSON_NAMESPACE::String JsonString; -typedef ARDUINOJSON_NAMESPACE::UInt JsonUInt; -typedef ARDUINOJSON_NAMESPACE::VariantConstRef JsonVariantConst; -typedef ARDUINOJSON_NAMESPACE::VariantRef JsonVariant; -using ARDUINOJSON_NAMESPACE::BasicJsonDocument; -using ARDUINOJSON_NAMESPACE::copyArray; -using ARDUINOJSON_NAMESPACE::DeserializationError; -using ARDUINOJSON_NAMESPACE::deserializeJson; -using ARDUINOJSON_NAMESPACE::deserializeMsgPack; -using ARDUINOJSON_NAMESPACE::DynamicJsonDocument; -using ARDUINOJSON_NAMESPACE::JsonDocument; -using ARDUINOJSON_NAMESPACE::serialized; -using ARDUINOJSON_NAMESPACE::serializeJson; -using ARDUINOJSON_NAMESPACE::serializeJsonPretty; -using ARDUINOJSON_NAMESPACE::serializeMsgPack; -using ARDUINOJSON_NAMESPACE::StaticJsonDocument; -namespace DeserializationOption { -using ARDUINOJSON_NAMESPACE::NestingLimit; -} -} // namespace ArduinoJson - -using namespace ArduinoJson; - -#else - -#error ArduinoJson requires a C++ compiler, please change file extension to .cc or .cpp - -#endif diff --git a/Encoder b/Encoder deleted file mode 160000 index c083e9cbd6400f7e72a794c0d371a00a09d2a25d..0000000000000000000000000000000000000000 --- a/Encoder +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c083e9cbd6400f7e72a794c0d371a00a09d2a25d diff --git a/FastLED/LICENSE b/FastLED/LICENSE deleted file mode 100644 index ebe476330b11a015fbbbf7f81f9feb013558d940..0000000000000000000000000000000000000000 --- a/FastLED/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 FastLED - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/FastLED/PORTING.md b/FastLED/PORTING.md deleted file mode 100644 index beb4e6c65de8dbbf6e73321804258af77dcca8f9..0000000000000000000000000000000000000000 --- a/FastLED/PORTING.md +++ /dev/null @@ -1,56 +0,0 @@ -New platform porting guide -========================== - -# Fast porting for a new board on existing hardware - -Sometimes "porting" FastLED simply consists of supplying new pin definitions for the given platform. For example, platforms/avr/fastpin_avr.h contains various pin definitions for all the AVR variant chipsets/boards that FastLED supports. Defining a set of pins involves setting up a set of definitions - for example here's one full set from the avr fastpin file: - -``` -#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) - -_FL_IO(A); _FL_IO(B); _FL_IO(C); _FL_IO(D); - -#define MAX_PIN 31 -_FL_DEFPIN(0, 0, B); _FL_DEFPIN(1, 1, B); _FL_DEFPIN(2, 2, B); _FL_DEFPIN(3, 3, B); -_FL_DEFPIN(4, 4, B); _FL_DEFPIN(5, 5, B); _FL_DEFPIN(6, 6, B); _FL_DEFPIN(7, 7, B); -_FL_DEFPIN(8, 0, D); _FL_DEFPIN(9, 1, D); _FL_DEFPIN(10, 2, D); _FL_DEFPIN(11, 3, D); -_FL_DEFPIN(12, 4, D); _FL_DEFPIN(13, 5, D); _FL_DEFPIN(14, 6, D); _FL_DEFPIN(15, 7, D); -_FL_DEFPIN(16, 0, C); _FL_DEFPIN(17, 1, C); _FL_DEFPIN(18, 2, C); _FL_DEFPIN(19, 3, C); -_FL_DEFPIN(20, 4, C); _FL_DEFPIN(21, 5, C); _FL_DEFPIN(22, 6, C); _FL_DEFPIN(23, 7, C); -_FL_DEFPIN(24, 0, A); _FL_DEFPIN(25, 1, A); _FL_DEFPIN(26, 2, A); _FL_DEFPIN(27, 3, A); -_FL_DEFPIN(28, 4, A); _FL_DEFPIN(29, 5, A); _FL_DEFPIN(30, 6, A); _FL_DEFPIN(31, 7, A); - -#define HAS_HARDWARE_PIN_SUPPORT 1 -``` - -The ```_FL_IO``` macro is used to define the port registers for the platform while the ```_FL_DEFPIN``` macro is used to define pins. The parameters to the macro are the pin number, the bit on the port that represents that pin, and the port identifier itself. On some platforms, like the AVR, ports are identified by letter. On other platforms, like arm, ports are identified by number. - -The ```HAS_HARDWARE_PIN_SUPPORT``` define tells the rest of the FastLED library that there is hardware pin support available. There may be other platform specific defines for things like hardware SPI ports and such. - -## Setting up the basic files/folders - -* Create platform directory (e.g. platforms/arm/kl26) -* Create configuration header led_sysdefs_arm_kl26.h: - * Define platform flags (like FASTLED_ARM/FASTLED_TEENSY) - * Define configuration parameters re: interrupts, or clock doubling - * Include extar system header files if needed -* Create main platform include, fastled_arm_kl26.h - * Include the various other header files as needed -* Modify led_sysdefs.h to conditionally include platform sysdefs header file -* Modify platforms.h to conditionally include platform fastled header - -## Porting fastpin.h - -The heart of the FastLED library is the fast pin accesss. This is a templated class that provides 1-2 cycle pin access, bypassing digital write and other such things. As such, this will usually be the first bit of the library that you will want to port when moving to a new platform. Once you have FastPIN up and running then you can do some basic work like testing toggles or running bit-bang'd SPI output. - -There's two low level FastPin classes. There's the base FastPIN template class, and then there is FastPinBB which is for bit-banded access on those MCUs that support bitbanding. Note that the bitband class is optional and primarily useful in the implementation of other functionality internal to the platform. This file is also where you would do the pin to port/bit mapping defines. - -Explaining how the macros work and should be used is currently beyond the scope of this document. - -## Porting fastspi.h - -This is where you define the low level interface to the hardware SPI system (including a writePixels method that does a bunch of housekeeping for writing led data). Use the fastspi_nop.h file as a reference for the methods that need to be implemented. There are ofteh other useful methods that can help with the internals of the SPI code, I recommend taking a look at how the various platforms implement their SPI classes. - -## Porting clockless.h - -This is where you define the code for the clockless controllers. Across ARM platforms this will usually be fairly similar - though different arm platforms will have different clock sources that you can/should use. diff --git a/FastLED/README.md b/FastLED/README.md deleted file mode 100644 index da63e755b6e3b1f041787c55d068142fb92e20db..0000000000000000000000000000000000000000 --- a/FastLED/README.md +++ /dev/null @@ -1,91 +0,0 @@ -[](https://gitter.im/FastLED/public) -[](https://www.ardu-badge.com/FastLED) - -IMPORTANT NOTE: For AVR based systems, avr-gcc 4.8.x is supported and tested. This means Arduino 1.6.5 and later. - - -FastLED 3.4 -=========== - -This is a library for easily & efficiently controlling a wide variety of LED chipsets, like the ones -sold by adafruit (Neopixel, DotStar, LPD8806), Sparkfun (WS2801), and aliexpress. In addition to writing to the -leds, this library also includes a number of functions for high-performing 8bit math for manipulating -your RGB values, as well as low level classes for abstracting out access to pins and SPI hardware, while -still keeping things as fast as possible. Tested with Arduino up to 1.6.5 from arduino.cc. - -Quick note for people installing from GitHub repo zips, rename the folder FastLED before copying it to your Arduino/libraries folder. Github likes putting -branchname into the name of the folder, which unfortunately, makes Arduino cranky! - -We have multiple goals with this library: - -* Quick start for new developers - hook up your leds and go, no need to think about specifics of the led chipsets being used -* Zero pain switching LED chipsets - you get some new leds that the library supports, just change the definition of LEDs you're using, et. voila! Your code is running with the new leds. -* High performance - with features like zero cost global brightness scaling, high performance 8-bit math for RGB manipulation, and some of the fastest bit-bang'd SPI support around, FastLED wants to keep as many CPU cycles available for your led patterns as possible - -## Getting help - -If you need help with using the library, please consider going to the reddit community first, which is at http://fastled.io/r (or https://reddit.com/r/FastLED) - there are hundreds of people in that group and many times you will get a quicker answer to your question there, as you will be likely to run into other people who have had the same issue. If you run into bugs with the library (compilation failures, the library doing the wrong thing), or if you'd like to request that we support a particular platform or LED chipset, then please open an issue at http://fastled.io/issues and we will try to figure out what is going wrong. - -## Simple example - -How quickly can you get up and running with the library? Here's a simple blink program: - - #include "FastLED.h" - #define NUM_LEDS 60 - CRGB leds[NUM_LEDS]; - void setup() { FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS); } - void loop() { - leds[0] = CRGB::White; FastLED.show(); delay(30); - leds[0] = CRGB::Black; FastLED.show(); delay(30); - } - -## Supported LED chipsets - -Here's a list of all the LED chipsets are supported. More details on the led chipsets are included *TODO: Link to wiki page* - -* Adafruit's DotStars - AKA the APA102 -* Adafruit's Neopixel - aka the WS2812B (also WS2811/WS2812/WS2813, also supported in lo-speed mode) - a 3 wire addressable led chipset -* TM1809/4 - 3 wire chipset, cheaply available on aliexpress.com -* TM1803 - 3 wire chipset, sold by radio shack -* UCS1903 - another 3 wire led chipset, cheap -* GW6205 - another 3 wire led chipset -* LPD8806 - SPI based chipset, very high speed -* WS2801 - SPI based chipset, cheap and widely available -* SM16716 - SPI based chipset -* APA102 - SPI based chipset -* P9813 - aka Cool Neon's Total Control Lighting -* DMX - send rgb data out over DMX using arduino DMX libraries -* SmartMatrix panels - needs the SmartMatrix library - https://github.com/pixelmatix/SmartMatrix -* LPD6803 - SPI based chpiset, chip CMODE pin must be set to 1 (inside oscillator mode) - - -HL1606, and "595"-style shift registers are no longer supported by the library. The older Version 1 of the library ("FastSPI_LED") has support for these, but is missing many of the advanced features of current versions and is no longer being maintained. - - -## Supported platforms - -Right now the library is supported on a variety of arduino compatable platforms. If it's ARM or AVR and uses the arduino software (or a modified version of it to build) then it is likely supported. Note that we have a long list of upcoming platforms to support, so if you don't see what you're looking for here, ask, it may be on the roadmap (or may already be supported). N.B. at the moment we are only supporting the stock compilers that ship with the arduino software. Support for upgraded compilers, as well as using AVR studio and skipping the arduino entirely, should be coming in a near future release. - -* Arduino & compatibles - straight up arduino devices, uno, duo, leonardo, mega, nano, etc... -* Arduino Yún -* Adafruit Trinket & Gemma - Trinket Pro may be supported, but haven't tested to confirm yet -* Teensy 2, Teensy++ 2, Teensy 3.0, Teensy 3.1/3.2, Teensy LC, Teensy 3.5, Teensy 3.6, and Teensy 4.0 - arduino compataible from pjrc.com with some extra goodies (note the teensy 3, 3.1, and LC are ARM, not AVR!) -* Arduino Due and the digistump DigiX -* RFDuino -* SparkCore -* Arduino Zero -* ESP8266 using the arduino board definitions from http://arduino.esp8266.com/stable/package_esp8266com_index.json - please be sure to also read https://github.com/FastLED/FastLED/wiki/ESP8266-notes for information specific to the 8266. -* The wino board - http://wino-board.com -* ESP32 based boards - -What types of platforms are we thinking about supporting in the future? Here's a short list: ChipKit32, Maple, Beagleboard - -## What about that name? - -Wait, what happend to FastSPI_LED and FastSPI_LED2? The library was initially named FastSPI_LED because it was focused on very fast and efficient SPI access. However, since then, the library has expanded to support a number of LED chipsets that don't use SPI, as well as a number of math and utility functions for LED processing across the board. We decided that the name FastLED more accurately represents the totality of what the library provides, everything fast, for LEDs. - -## For more information - -Check out the official site http://fastled.io for links to documentation, issues, and news - - -*TODO* - get candy diff --git a/FastLED/component.mk b/FastLED/component.mk deleted file mode 100644 index 874ca9b0ac040e9b77b943968083fc05c0fd5ab9..0000000000000000000000000000000000000000 --- a/FastLED/component.mk +++ /dev/null @@ -1,2 +0,0 @@ -COMPONENT_ADD_INCLUDEDIRS := ./src src/platforms/esp/32 -COMPONENT_SRCDIRS := ./src src/platforms/esp/32 diff --git a/FastLED/docs/Doxyfile b/FastLED/docs/Doxyfile deleted file mode 100644 index 25e4f92e1078eb7efaf405a082b3fa22ea549a99..0000000000000000000000000000000000000000 --- a/FastLED/docs/Doxyfile +++ /dev/null @@ -1,2524 +0,0 @@ -# Doxyfile 1.8.18 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the configuration -# file that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# https://www.gnu.org/software/libiconv/ for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = FastLED - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = 3.3.3 - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = ../docs - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = YES - -# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line -# such as -# /*************** -# as being the beginning of a Javadoc-style comment "banner". If set to NO, the -# Javadoc-style will behave just like regular comments and it will not be -# interpreted by doxygen. -# The default value is: NO. - -JAVADOC_BANNER = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. -# When you need a literal { or } or , in the value part of an alias you have to -# escape them by means of a backslash (\), this can lead to conflicts with the -# commands \{ and \} for these it is advised to use the version @{ and @} or use -# a double escape (\\{ and \\}) - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice -# sources only. Doxygen will then generate output that is more tailored for that -# language. For instance, namespaces will be presented as modules, types will be -# separated into more groups, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_SLICE = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: -# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser -# tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files -# as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See https://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 5 - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual -# methods of a class will be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIV_VIRTUAL = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# declarations. If set to NO, these declarations will be included in the -# documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# (including Cygwin) ands Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = YES - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if <section_label> ... \endif and \cond <section_label> -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. If -# EXTRACT_ALL is set to YES then this flag will automatically be disabled. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = ../ ../lib8tion - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv/) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), -# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen -# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. - -FILE_PATTERNS = -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# <filter> <input-file> -# -# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# entity all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see https://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = YES - -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = NO - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - -# If clang assisted parsing is enabled you can provide the clang parser with the -# path to the compilation database (see: -# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files -# were built. This is equivalent to specifying the "-p" option to a clang tool, -# such as clang-check. These options will then be passed to the parser. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. - -CLANG_DATABASE_PATH = - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = YES - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# https://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML -# documentation will contain a main index with vertical navigation menus that -# are dynamically created via JavaScript. If disabled, the navigation index will -# consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have JavaScript, -# like the Qt help browser. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_MENUS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = YES - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: https://developer.apple.com/xcode/), introduced with OSX -# 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy -# genXcode/_index.html for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = YES - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg -# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see -# https://inkscape.org) to generate formulas as SVG images instead of PNGs for -# the HTML output. These images will generally look nicer at scaled resolutions. -# Possible values are: png The default and svg Looks nicer but requires the -# pdf2svg tool. -# The default value is: png. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FORMULA_FORMAT = png - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands -# to create new LaTeX commands to be used in formulas as building blocks. See -# the section "Including formulas" for details. - -FORMULA_MACROFILE = - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side JavaScript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use <access key> + S -# (what the <access key> is depends on the OS and browser, but it is typically -# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down -# key> to jump into the search results window, the results can be navigated -# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel -# the search. The filter options can be selected when the cursor is inside the -# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> -# to select a filter and <Enter> or <escape> to activate or cancel the filter -# option. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using JavaScript. There -# are two flavors of web server based searching depending on the EXTERNAL_SEARCH -# setting. When disabled, doxygen will generate a PHP script for searching and -# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing -# and searching needs to be provided by external tools. See the section -# "External Indexing and Searching" for details. -# The default value is: NO. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SERVER_BASED_SEARCH = NO - -# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP -# script for searching. Instead the search results are written to an XML file -# which needs to be processed by an external indexer. Doxygen will invoke an -# external search engine pointed to by the SEARCHENGINE_URL option to obtain the -# search results. -# -# Doxygen ships with an example indexer (doxyindexer) and search engine -# (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: https://xapian.org/). -# -# See the section "External Indexing and Searching" for details. -# The default value is: NO. -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTERNAL_SEARCH = NO - -# The SEARCHENGINE_URL should point to a search engine hosted by a web server -# which will return the search results when EXTERNAL_SEARCH is enabled. -# -# Doxygen ships with an example indexer (doxyindexer) and search engine -# (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: https://xapian.org/). See the section "External Indexing and -# Searching" for details. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SEARCHENGINE_URL = - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed -# search data is written to a file for indexing by an external tool. With the -# SEARCHDATA_FILE tag the name of this file can be specified. -# The default file is: searchdata.xml. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SEARCHDATA_FILE = searchdata.xml - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the -# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is -# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple -# projects and redirect the results back to the right project. -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTERNAL_SEARCH_ID = - -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen -# projects other than the one defined by this configuration file, but that are -# all added to the same external search index. Each project needs to have a -# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of -# to a relative location where the documentation can be found. The format is: -# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTRA_SEARCH_MAPPINGS = - -#--------------------------------------------------------------------------- -# Configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. -# The default value is: YES. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: latex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. -# -# Note that when not enabling USE_PDFLATEX the default is latex when enabling -# USE_PDFLATEX the default is pdflatex and when in the later case latex is -# chosen this is overwritten by pdflatex. For specific output languages the -# default can have been set differently, this depends on the implementation of -# the output language. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate -# index for LaTeX. -# Note: This tag is used in the Makefile / make.bat. -# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file -# (.tex). -# The default file is: makeindex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -MAKEINDEX_CMD_NAME = makeindex - -# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to -# generate index for LaTeX. In case there is no backslash (\) as first character -# it will be automatically added in the LaTeX code. -# Note: This tag is used in the generated output file (.tex). -# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. -# The default value is: makeindex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_MAKEINDEX_CMD = makeindex - -# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX -# documents. This may be useful for small projects and may help to save some -# trees in general. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used by the -# printer. -# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x -# 14 inches) and executive (7.25 x 10.5 inches). -# The default value is: a4. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names -# that should be included in the LaTeX output. The package can be specified just -# by its name or with the correct syntax as to be used with the LaTeX -# \usepackage command. To get the times font for instance you can specify : -# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} -# To use the option intlimits with the amsmath package you can specify: -# EXTRA_PACKAGES=[intlimits]{amsmath} -# If left blank no extra packages will be included. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. -# -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See -# LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_FOOTER = - -# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# LaTeX style sheets that are included after the standard style sheets created -# by doxygen. Using this option one can overrule certain style aspects. Doxygen -# will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EXTRA_STYLESHEET = - -# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the LATEX_OUTPUT output -# directory. Note that the files will be copied as-is; there are no commands or -# markers available. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EXTRA_FILES = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is -# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will -# contain links (just like the HTML output) instead of page references. This -# makes the output suitable for online browsing using a PDF viewer. -# The default value is: YES. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. -# The default value is: YES. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BATCHMODE = NO - -# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the -# index chapters (such as File Index, Compound Index, etc.) in the output. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_HIDE_INDICES = NO - -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. See -# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. -# The default value is: plain. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BIB_STYLE = plain - -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_TIMESTAMP = NO - -# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) -# path from which the emoji images will be read. If a relative path is entered, -# it will be relative to the LATEX_OUTPUT directory. If left blank the -# LATEX_OUTPUT directory will be used. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EMOJI_DIRECTORY = - -#--------------------------------------------------------------------------- -# Configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The -# RTF output is optimized for Word 97 and may not look too pretty with other RTF -# readers/editors. -# The default value is: NO. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: rtf. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF -# documents. This may be useful for small projects and may help to save some -# trees in general. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will -# contain hyperlink fields. The RTF file will contain links (just like the HTML -# output) instead of page references. This makes the output suitable for online -# browsing using Word or some other Word compatible readers that support those -# fields. -# -# Note: WordPad (write) and others do not support links. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# configuration file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. -# -# See also section "Doxygen usage" for information on how to generate the -# default style sheet that doxygen normally uses. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's configuration file. A template extensions file can be -# generated using doxygen -e rtf extensionFile. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_EXTENSIONS_FILE = - -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for -# classes and files. -# The default value is: NO. - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. A directory man3 will be created inside the directory specified by -# MAN_OUTPUT. -# The default directory is: man. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to the generated -# man pages. In case the manual section does not start with a number, the number -# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is -# optional. -# The default value is: .3. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_EXTENSION = .3 - -# The MAN_SUBDIR tag determines the name of the directory created within -# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by -# MAN_EXTENSION with the initial . removed. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_SUBDIR = - -# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it -# will generate one additional man file for each entity documented in the real -# man page(s). These additional files only source the real man page, but without -# them the man command would be unable to find the correct page. -# The default value is: NO. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that -# captures the structure of the code including all documentation. -# The default value is: NO. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: xml. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_OUTPUT = xml - -# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program -# listings (including syntax highlighting and cross-referencing information) to -# the XML output. Note that enabling this will significantly increase the size -# of the XML output. -# The default value is: YES. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_PROGRAMLISTING = YES - -# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include -# namespace members in file scope as well, matching the HTML output. -# The default value is: NO. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_NS_MEMB_FILE_SCOPE = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the DOCBOOK output -#--------------------------------------------------------------------------- - -# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files -# that can be used to generate PDF. -# The default value is: NO. - -GENERATE_DOCBOOK = NO - -# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in -# front of it. -# The default directory is: docbook. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_OUTPUT = docbook - -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - -#--------------------------------------------------------------------------- -# Configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures -# the structure of the code including all documentation. Note that this feature -# is still experimental and incomplete at the moment. -# The default value is: NO. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module -# file that captures the structure of the code including all documentation. -# -# Note that this feature is still experimental and incomplete at the moment. -# The default value is: NO. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary -# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI -# output from the Perl module output. -# The default value is: NO. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely -# formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO, the -# size of the Perl module output will be much smaller and Perl will parse it -# just the same. -# The default value is: YES. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file are -# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful -# so different doxyrules.make files included by the same Makefile don't -# overwrite each other's variables. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all -# C-preprocessor directives found in the sources and include files. -# The default value is: YES. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names -# in the source code. If set to NO, only conditional compilation will be -# performed. Macro expansion can be done in a controlled way by setting -# EXPAND_ONLY_PREDEF to YES. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then -# the macro expansion is limited to the macros specified with the PREDEFINED and -# EXPAND_AS_DEFINED tags. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES, the include files in the -# INCLUDE_PATH will be searched if a #include is found. -# The default value is: YES. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by the -# preprocessor. -# This tag requires that the tag SEARCH_INCLUDES is set to YES. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will be -# used. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that are -# defined before the preprocessor is started (similar to the -D option of e.g. -# gcc). The argument of the tag is a list of macros of the form: name or -# name=definition (no spaces). If the definition and the "=" are omitted, "=1" -# is assumed. To prevent a macro definition from being undefined via #undef or -# recursively expanded use the := operator instead of the = operator. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this -# tag can be used to specify a list of macro names that should be expanded. The -# macro definition that is found in the sources will be used. Use the PREDEFINED -# tag if you want to use a different macro definition that overrules the -# definition found in the source code. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all references to function-like macros that are alone on a line, have -# an all uppercase name, and do not end with a semicolon. Such function macros -# are typically used for boiler-plate code, and will confuse the parser if not -# removed. -# The default value is: YES. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tag files. For each tag -# file the location of the external documentation should be added. The format of -# a tag file without this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where loc1 and loc2 can be relative or absolute paths or URLs. See the -# section "Linking to external documentation" for more information about the use -# of tag files. -# Note: Each tag file must have a unique name (where the name does NOT include -# the path). If a tag file is not located in the directory in which doxygen is -# run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create a -# tag file that is based on the input files it reads. See section "Linking to -# external documentation" for more information about the usage of tag files. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. -# The default value is: NO. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be -# listed. -# The default value is: YES. - -EXTERNAL_GROUPS = YES - -# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in -# the related pages index. If set to NO, only the current project's pages will -# be listed. -# The default value is: YES. - -EXTERNAL_PAGES = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - -# If set to YES the inheritance and collaboration graphs will hide inheritance -# and usage relations if the target is undocumented or is not a class. -# The default value is: YES. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent -# Bell Labs. The other options in this section have no effect if this option is -# set to NO -# The default value is: NO. - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed -# to run in parallel. When set to 0 doxygen will base this on the number of -# processors available in the system. You can set it explicitly to a value -# larger than 0 to get control over the balance between CPU load and processing -# speed. -# Minimum value: 0, maximum value: 32, default value: 0. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_NUM_THREADS = 0 - -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTPATH = - -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a -# graph for each documented class showing the direct and indirect implementation -# dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -UML_LOOK = NO - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside the -# class node. If there are many fields or methods and many nodes the graph may -# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the -# number of items for each type to make the size more manageable. Set this to 0 -# for no limit. Note that the threshold may be exceeded by 50% before the limit -# is enforced. So when you set the threshold to 10, up to 15 fields may appear, -# but if the number exceeds 15, the total amount of fields shown is limited to -# 10. -# Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. - -UML_LIMIT_NUM_FIELDS = 10 - -# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and -# collaboration graphs will show the relations between templates and their -# instances. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -TEMPLATE_RELATIONS = NO - -# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to -# YES then doxygen will generate a graph for each documented file showing the -# direct and indirect include dependencies of the file with other documented -# files. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -INCLUDE_GRAPH = YES - -# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are -# set to YES then doxygen will generate a graph for each documented file showing -# the direct and indirect include dependencies of the file with other documented -# files. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH tag is set to YES then doxygen will generate a call -# dependency graph for every global function or class method. -# -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. Disabling a call graph can be -# accomplished by means of the command \hidecallgraph. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller -# dependency graph for every global function or class method. -# -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. Disabling a caller graph can be -# accomplished by means of the command \hidecallergraph. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical -# hierarchy of all classes instead of a textual one. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the -# dependencies a directory has on other directories in a graphical way. The -# dependency relations are determined by the #include relations between the -# files in the directories. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. For an explanation of the image formats see the section -# output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). -# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order -# to make the SVG files visible in IE 9+ (other browsers do not have this -# requirement). -# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, -# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and -# png:gdiplus:gdiplus. -# The default value is: png. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# -# Note that this requires a modern browser other than Internet Explorer. Tested -# and working are Firefox, Chrome, Safari, and Opera. -# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make -# the SVG files visible. Older versions of IE do not have SVG support. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -INTERACTIVE_SVG = NO - -# The DOT_PATH tag can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the \dotfile -# command). -# This tag requires that the tag HAVE_DOT is set to YES. - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). - -MSCFILE_DIRS = - -# The DIAFILE_DIRS tag can be used to specify one or more directories that -# contain dia files that are included in the documentation (see the \diafile -# command). - -DIAFILE_DIRS = - -# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. - -PLANTUML_JAR_PATH = - -# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a -# configuration file for plantuml. - -PLANTUML_CFG_FILE = - -# When using plantuml, the specified paths are searched for files specified by -# the !include statement in a plantuml block. - -PLANTUML_INCLUDE_PATH = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes -# that will be shown in the graph. If the number of nodes in a graph becomes -# larger than this value, doxygen will truncate the graph, which is visualized -# by representing a node as a red box. Note that doxygen if the number of direct -# children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that -# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. -# Minimum value: 0, maximum value: 10000, default value: 50. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs -# generated by dot. A depth value of 3 means that only nodes reachable from the -# root by following a path via at most 3 edges will be shown. Nodes that lay -# further from the root node will be omitted. Note that setting this option to 1 -# or 2 may greatly reduce the computation time needed for large code bases. Also -# note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. -# Minimum value: 0, maximum value: 1000, default value: 0. -# This tag requires that the tag HAVE_DOT is set to YES. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) support -# this, this feature is disabled by default. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page -# explaining the meaning of the various boxes and arrows in the dot generated -# graphs. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot -# files that are used to generate the various graphs. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_CLEANUP = YES diff --git a/FastLED/docs/mainpage.dox b/FastLED/docs/mainpage.dox deleted file mode 100644 index 415bbe4f0ce3049d5967ce98cb8a705f8803c093..0000000000000000000000000000000000000000 --- a/FastLED/docs/mainpage.dox +++ /dev/null @@ -1,10 +0,0 @@ -/** -@brief Documentation file for FastLED -@author dgarcia at fastled dot io -@file -*/ -/** @defgroup FastLED Sources */ -/** -@mainpage FastLED - let there be light! -*/ -EOF diff --git a/FastLED/examples/AnalogOutput/AnalogOutput.ino b/FastLED/examples/AnalogOutput/AnalogOutput.ino deleted file mode 100644 index 33733102a58c31cb64cbbccde024389324595e5c..0000000000000000000000000000000000000000 --- a/FastLED/examples/AnalogOutput/AnalogOutput.ino +++ /dev/null @@ -1,65 +0,0 @@ -#include <FastLED.h> - -// Example showing how to use FastLED color functions -// even when you're NOT using a "pixel-addressible" smart LED strip. -// -// This example is designed to control an "analog" RGB LED strip -// (or a single RGB LED) being driven by Arduino PWM output pins. -// So this code never calls FastLED.addLEDs() or FastLED.show(). -// -// This example illustrates one way you can use just the portions -// of FastLED that you need. In this case, this code uses just the -// fast HSV color conversion code. -// -// In this example, the RGB values are output on three separate -// 'analog' PWM pins, one for red, one for green, and one for blue. - -#define REDPIN 5 -#define GREENPIN 6 -#define BLUEPIN 3 - -// showAnalogRGB: this is like FastLED.show(), but outputs on -// analog PWM output pins instead of sending data to an intelligent, -// pixel-addressable LED strip. -// -// This function takes the incoming RGB values and outputs the values -// on three analog PWM output pins to the r, g, and b values respectively. -void showAnalogRGB( const CRGB& rgb) -{ - analogWrite(REDPIN, rgb.r ); - analogWrite(GREENPIN, rgb.g ); - analogWrite(BLUEPIN, rgb.b ); -} - - - -// colorBars: flashes Red, then Green, then Blue, then Black. -// Helpful for diagnosing if you've mis-wired which is which. -void colorBars() -{ - showAnalogRGB( CRGB::Red ); delay(500); - showAnalogRGB( CRGB::Green ); delay(500); - showAnalogRGB( CRGB::Blue ); delay(500); - showAnalogRGB( CRGB::Black ); delay(500); -} - -void loop() -{ - static uint8_t hue; - hue = hue + 1; - // Use FastLED automatic HSV->RGB conversion - showAnalogRGB( CHSV( hue, 255, 255) ); - - delay(20); -} - - -void setup() { - pinMode(REDPIN, OUTPUT); - pinMode(GREENPIN, OUTPUT); - pinMode(BLUEPIN, OUTPUT); - - // Flash the "hello" color sequence: R, G, B, black. - colorBars(); -} - diff --git a/FastLED/examples/Blink/Blink.ino b/FastLED/examples/Blink/Blink.ino deleted file mode 100644 index 443896ec072b68a3f70536f93715b49573c5a2c9..0000000000000000000000000000000000000000 --- a/FastLED/examples/Blink/Blink.ino +++ /dev/null @@ -1,69 +0,0 @@ -#include <FastLED.h> - -// How many leds in your strip? -#define NUM_LEDS 1 - -// For led chips like WS2812, which have a data line, ground, and power, you just -// need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, -// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN -// Clock pin only needed for SPI based chipsets when not using hardware SPI -#define DATA_PIN 3 -#define CLOCK_PIN 13 - -// Define the array of leds -CRGB leds[NUM_LEDS]; - -void setup() { - // Uncomment/edit one of the following lines for your leds arrangement. - // ## Clockless types ## - FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); // GRB ordering is assumed - // FastLED.addLeds<SM16703, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1829, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1812, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1904, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS2903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2852, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<GS1903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SK6812, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<APA106, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2813, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GE8822, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<LPD1886, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<LPD1886_8BIT, DATA_PIN, RGB>(leds, NUM_LEDS); - // ## Clocked (SPI) types ## - // FastLED.addLeds<LPD6803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<SK9822, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical -} - -void loop() { - // Turn the LED on, then pause - leds[0] = CRGB::Red; - FastLED.show(); - delay(500); - // Now turn the LED off, then pause - leds[0] = CRGB::Black; - FastLED.show(); - delay(500); -} diff --git a/FastLED/examples/ColorPalette/ColorPalette.ino b/FastLED/examples/ColorPalette/ColorPalette.ino deleted file mode 100644 index 6ccd5c1b64445a45827f603c974b8738fd177581..0000000000000000000000000000000000000000 --- a/FastLED/examples/ColorPalette/ColorPalette.ino +++ /dev/null @@ -1,188 +0,0 @@ -#include <FastLED.h> - -#define LED_PIN 5 -#define NUM_LEDS 50 -#define BRIGHTNESS 64 -#define LED_TYPE WS2811 -#define COLOR_ORDER GRB -CRGB leds[NUM_LEDS]; - -#define UPDATES_PER_SECOND 100 - -// This example shows several ways to set up and use 'palettes' of colors -// with FastLED. -// -// These compact palettes provide an easy way to re-colorize your -// animation on the fly, quickly, easily, and with low overhead. -// -// USING palettes is MUCH simpler in practice than in theory, so first just -// run this sketch, and watch the pretty lights as you then read through -// the code. Although this sketch has eight (or more) different color schemes, -// the entire sketch compiles down to about 6.5K on AVR. -// -// FastLED provides a few pre-configured color palettes, and makes it -// extremely easy to make up your own color schemes with palettes. -// -// Some notes on the more abstract 'theory and practice' of -// FastLED compact palettes are at the bottom of this file. - - - -CRGBPalette16 currentPalette; -TBlendType currentBlending; - -extern CRGBPalette16 myRedWhiteBluePalette; -extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM; - - -void setup() { - delay( 3000 ); // power-up safety delay - FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); - FastLED.setBrightness( BRIGHTNESS ); - - currentPalette = RainbowColors_p; - currentBlending = LINEARBLEND; -} - - -void loop() -{ - ChangePalettePeriodically(); - - static uint8_t startIndex = 0; - startIndex = startIndex + 1; /* motion speed */ - - FillLEDsFromPaletteColors( startIndex); - - FastLED.show(); - FastLED.delay(1000 / UPDATES_PER_SECOND); -} - -void FillLEDsFromPaletteColors( uint8_t colorIndex) -{ - uint8_t brightness = 255; - - for( int i = 0; i < NUM_LEDS; ++i) { - leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending); - colorIndex += 3; - } -} - - -// There are several different palettes of colors demonstrated here. -// -// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, -// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. -// -// Additionally, you can manually define your own color palettes, or you can write -// code that creates color palettes on the fly. All are shown here. - -void ChangePalettePeriodically() -{ - uint8_t secondHand = (millis() / 1000) % 60; - static uint8_t lastSecond = 99; - - if( lastSecond != secondHand) { - lastSecond = secondHand; - if( secondHand == 0) { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; } - if( secondHand == 10) { currentPalette = RainbowStripeColors_p; currentBlending = NOBLEND; } - if( secondHand == 15) { currentPalette = RainbowStripeColors_p; currentBlending = LINEARBLEND; } - if( secondHand == 20) { SetupPurpleAndGreenPalette(); currentBlending = LINEARBLEND; } - if( secondHand == 25) { SetupTotallyRandomPalette(); currentBlending = LINEARBLEND; } - if( secondHand == 30) { SetupBlackAndWhiteStripedPalette(); currentBlending = NOBLEND; } - if( secondHand == 35) { SetupBlackAndWhiteStripedPalette(); currentBlending = LINEARBLEND; } - if( secondHand == 40) { currentPalette = CloudColors_p; currentBlending = LINEARBLEND; } - if( secondHand == 45) { currentPalette = PartyColors_p; currentBlending = LINEARBLEND; } - if( secondHand == 50) { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND; } - if( secondHand == 55) { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; } - } -} - -// This function fills the palette with totally random colors. -void SetupTotallyRandomPalette() -{ - for( int i = 0; i < 16; ++i) { - currentPalette[i] = CHSV( random8(), 255, random8()); - } -} - -// This function sets up a palette of black and white stripes, -// using code. Since the palette is effectively an array of -// sixteen CRGB colors, the various fill_* functions can be used -// to set them up. -void SetupBlackAndWhiteStripedPalette() -{ - // 'black out' all 16 palette entries... - fill_solid( currentPalette, 16, CRGB::Black); - // and set every fourth one to white. - currentPalette[0] = CRGB::White; - currentPalette[4] = CRGB::White; - currentPalette[8] = CRGB::White; - currentPalette[12] = CRGB::White; - -} - -// This function sets up a palette of purple and green stripes. -void SetupPurpleAndGreenPalette() -{ - CRGB purple = CHSV( HUE_PURPLE, 255, 255); - CRGB green = CHSV( HUE_GREEN, 255, 255); - CRGB black = CRGB::Black; - - currentPalette = CRGBPalette16( - green, green, black, black, - purple, purple, black, black, - green, green, black, black, - purple, purple, black, black ); -} - - -// This example shows how to set up a static color palette -// which is stored in PROGMEM (flash), which is almost always more -// plentiful than RAM. A static PROGMEM palette like this -// takes up 64 bytes of flash. -const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = -{ - CRGB::Red, - CRGB::Gray, // 'white' is too bright compared to red and blue - CRGB::Blue, - CRGB::Black, - - CRGB::Red, - CRGB::Gray, - CRGB::Blue, - CRGB::Black, - - CRGB::Red, - CRGB::Red, - CRGB::Gray, - CRGB::Gray, - CRGB::Blue, - CRGB::Blue, - CRGB::Black, - CRGB::Black -}; - - - -// Additional notes on FastLED compact palettes: -// -// Normally, in computer graphics, the palette (or "color lookup table") -// has 256 entries, each containing a specific 24-bit RGB color. You can then -// index into the color palette using a simple 8-bit (one byte) value. -// A 256-entry color palette takes up 768 bytes of RAM, which on Arduino -// is quite possibly "too many" bytes. -// -// FastLED does offer traditional 256-element palettes, for setups that -// can afford the 768-byte cost in RAM. -// -// However, FastLED also offers a compact alternative. FastLED offers -// palettes that store 16 distinct entries, but can be accessed AS IF -// they actually have 256 entries; this is accomplished by interpolating -// between the 16 explicit entries to create fifteen intermediate palette -// entries between each pair. -// -// So for example, if you set the first two explicit entries of a compact -// palette to Green (0,255,0) and Blue (0,0,255), and then retrieved -// the first sixteen entries from the virtual palette (of 256), you'd get -// Green, followed by a smooth gradient from green-to-blue, and then Blue. diff --git a/FastLED/examples/ColorTemperature/ColorTemperature.ino b/FastLED/examples/ColorTemperature/ColorTemperature.ino deleted file mode 100644 index 66093e06f5618be51b5fa3b7268c109550a57a07..0000000000000000000000000000000000000000 --- a/FastLED/examples/ColorTemperature/ColorTemperature.ino +++ /dev/null @@ -1,85 +0,0 @@ -#include <FastLED.h> - -#define LED_PIN 3 - -// Information about the LED strip itself -#define NUM_LEDS 60 -#define CHIPSET WS2811 -#define COLOR_ORDER GRB -CRGB leds[NUM_LEDS]; - -#define BRIGHTNESS 128 - - -// FastLED v2.1 provides two color-management controls: -// (1) color correction settings for each LED strip, and -// (2) master control of the overall output 'color temperature' -// -// THIS EXAMPLE demonstrates the second, "color temperature" control. -// It shows a simple rainbow animation first with one temperature profile, -// and a few seconds later, with a different temperature profile. -// -// The first pixel of the strip will show the color temperature. -// -// HELPFUL HINTS for "seeing" the effect in this demo: -// * Don't look directly at the LED pixels. Shine the LEDs aganst -// a white wall, table, or piece of paper, and look at the reflected light. -// -// * If you watch it for a bit, and then walk away, and then come back -// to it, you'll probably be able to "see" whether it's currently using -// the 'redder' or the 'bluer' temperature profile, even not counting -// the lowest 'indicator' pixel. -// -// -// FastLED provides these pre-conigured incandescent color profiles: -// Candle, Tungsten40W, Tungsten100W, Halogen, CarbonArc, -// HighNoonSun, DirectSunlight, OvercastSky, ClearBlueSky, -// FastLED provides these pre-configured gaseous-light color profiles: -// WarmFluorescent, StandardFluorescent, CoolWhiteFluorescent, -// FullSpectrumFluorescent, GrowLightFluorescent, BlackLightFluorescent, -// MercuryVapor, SodiumVapor, MetalHalide, HighPressureSodium, -// FastLED also provides an "Uncorrected temperature" profile -// UncorrectedTemperature; - -#define TEMPERATURE_1 Tungsten100W -#define TEMPERATURE_2 OvercastSky - -// How many seconds to show each temperature before switching -#define DISPLAYTIME 20 -// How many seconds to show black between switches -#define BLACKTIME 3 - -void loop() -{ - // draw a generic, no-name rainbow - static uint8_t starthue = 0; - fill_rainbow( leds + 5, NUM_LEDS - 5, --starthue, 20); - - // Choose which 'color temperature' profile to enable. - uint8_t secs = (millis() / 1000) % (DISPLAYTIME * 2); - if( secs < DISPLAYTIME) { - FastLED.setTemperature( TEMPERATURE_1 ); // first temperature - leds[0] = TEMPERATURE_1; // show indicator pixel - } else { - FastLED.setTemperature( TEMPERATURE_2 ); // second temperature - leds[0] = TEMPERATURE_2; // show indicator pixel - } - - // Black out the LEDs for a few secnds between color changes - // to let the eyes and brains adjust - if( (secs % DISPLAYTIME) < BLACKTIME) { - memset8( leds, 0, NUM_LEDS * sizeof(CRGB)); - } - - FastLED.show(); - FastLED.delay(8); -} - -void setup() { - delay( 3000 ); // power-up safety delay - // It's important to set the color correction for your LED strip here, - // so that colors can be more accurately rendered through the 'temperature' profiles - FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalSMD5050 ); - FastLED.setBrightness( BRIGHTNESS ); -} - diff --git a/FastLED/examples/Cylon/Cylon.ino b/FastLED/examples/Cylon/Cylon.ino deleted file mode 100644 index f51c34871e8088ed6e3429d0e309a23e5b2a7dad..0000000000000000000000000000000000000000 --- a/FastLED/examples/Cylon/Cylon.ino +++ /dev/null @@ -1,53 +0,0 @@ -#include <FastLED.h> - -// How many leds in your strip? -#define NUM_LEDS 64 - -// For led chips like Neopixels, which have a data line, ground, and power, you just -// need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, -// ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN -#define DATA_PIN 7 -#define CLOCK_PIN 13 - -// Define the array of leds -CRGB leds[NUM_LEDS]; - -void setup() { - Serial.begin(57600); - Serial.println("resetting"); - LEDS.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS); - LEDS.setBrightness(84); -} - -void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } } - -void loop() { - static uint8_t hue = 0; - Serial.print("x"); - // First slide the led in one direction - for(int i = 0; i < NUM_LEDS; i++) { - // Set the i'th led to red - leds[i] = CHSV(hue++, 255, 255); - // Show the leds - FastLED.show(); - // now that we've shown the leds, reset the i'th led to black - // leds[i] = CRGB::Black; - fadeall(); - // Wait a little bit before we loop around and do it again - delay(10); - } - Serial.print("x"); - - // Now go in the other direction. - for(int i = (NUM_LEDS)-1; i >= 0; i--) { - // Set the i'th led to red - leds[i] = CHSV(hue++, 255, 255); - // Show the leds - FastLED.show(); - // now that we've shown the leds, reset the i'th led to black - // leds[i] = CRGB::Black; - fadeall(); - // Wait a little bit before we loop around and do it again - delay(10); - } -} diff --git a/FastLED/examples/DemoReel100/DemoReel100.ino b/FastLED/examples/DemoReel100/DemoReel100.ino deleted file mode 100644 index b4478735b514dfd2e1823ed433fe699af639b7cf..0000000000000000000000000000000000000000 --- a/FastLED/examples/DemoReel100/DemoReel100.ino +++ /dev/null @@ -1,126 +0,0 @@ -#include <FastLED.h> - -FASTLED_USING_NAMESPACE - -// FastLED "100-lines-of-code" demo reel, showing just a few -// of the kinds of animation patterns you can quickly and easily -// compose using FastLED. -// -// This example also shows one easy way to define multiple -// animations patterns and have them automatically rotate. -// -// -Mark Kriegsman, December 2014 - -#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) -#warning "Requires FastLED 3.1 or later; check github for latest code." -#endif - -#define DATA_PIN 3 -//#define CLK_PIN 4 -#define LED_TYPE WS2811 -#define COLOR_ORDER GRB -#define NUM_LEDS 64 -CRGB leds[NUM_LEDS]; - -#define BRIGHTNESS 96 -#define FRAMES_PER_SECOND 120 - -void setup() { - delay(3000); // 3 second delay for recovery - - // tell FastLED about the LED strip configuration - FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); - //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); - - // set master brightness control - FastLED.setBrightness(BRIGHTNESS); -} - - -// List of patterns to cycle through. Each is defined as a separate function below. -typedef void (*SimplePatternList[])(); -SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm }; - -uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current -uint8_t gHue = 0; // rotating "base color" used by many of the patterns - -void loop() -{ - // Call the current pattern function once, updating the 'leds' array - gPatterns[gCurrentPatternNumber](); - - // send the 'leds' array out to the actual LED strip - FastLED.show(); - // insert a delay to keep the framerate modest - FastLED.delay(1000/FRAMES_PER_SECOND); - - // do some periodic updates - EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow - EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically -} - -#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) - -void nextPattern() -{ - // add one to the current pattern number, and wrap around at the end - gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); -} - -void rainbow() -{ - // FastLED's built-in rainbow generator - fill_rainbow( leds, NUM_LEDS, gHue, 7); -} - -void rainbowWithGlitter() -{ - // built-in FastLED rainbow, plus some random sparkly glitter - rainbow(); - addGlitter(80); -} - -void addGlitter( fract8 chanceOfGlitter) -{ - if( random8() < chanceOfGlitter) { - leds[ random16(NUM_LEDS) ] += CRGB::White; - } -} - -void confetti() -{ - // random colored speckles that blink in and fade smoothly - fadeToBlackBy( leds, NUM_LEDS, 10); - int pos = random16(NUM_LEDS); - leds[pos] += CHSV( gHue + random8(64), 200, 255); -} - -void sinelon() -{ - // a colored dot sweeping back and forth, with fading trails - fadeToBlackBy( leds, NUM_LEDS, 20); - int pos = beatsin16( 13, 0, NUM_LEDS-1 ); - leds[pos] += CHSV( gHue, 255, 192); -} - -void bpm() -{ - // colored stripes pulsing at a defined Beats-Per-Minute (BPM) - uint8_t BeatsPerMinute = 62; - CRGBPalette16 palette = PartyColors_p; - uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); - for( int i = 0; i < NUM_LEDS; i++) { //9948 - leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); - } -} - -void juggle() { - // eight colored dots, weaving in and out of sync with each other - fadeToBlackBy( leds, NUM_LEDS, 20); - byte dothue = 0; - for( int i = 0; i < 8; i++) { - leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255); - dothue += 32; - } -} - diff --git a/FastLED/examples/Fire2012/Fire2012.ino b/FastLED/examples/Fire2012/Fire2012.ino deleted file mode 100644 index dec5cd7febbbb6eb30efe30158632b0f60eb474d..0000000000000000000000000000000000000000 --- a/FastLED/examples/Fire2012/Fire2012.ino +++ /dev/null @@ -1,105 +0,0 @@ -#include <FastLED.h> - -#define LED_PIN 5 -#define COLOR_ORDER GRB -#define CHIPSET WS2811 -#define NUM_LEDS 30 - -#define BRIGHTNESS 200 -#define FRAMES_PER_SECOND 60 - -bool gReverseDirection = false; - -CRGB leds[NUM_LEDS]; - -void setup() { - delay(3000); // sanity delay - FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); - FastLED.setBrightness( BRIGHTNESS ); -} - -void loop() -{ - // Add entropy to random number generator; we use a lot of it. - // random16_add_entropy( random()); - - Fire2012(); // run simulation frame - - FastLED.show(); // display this frame - FastLED.delay(1000 / FRAMES_PER_SECOND); -} - - -// Fire2012 by Mark Kriegsman, July 2012 -// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY -//// -// This basic one-dimensional 'fire' simulation works roughly as follows: -// There's a underlying array of 'heat' cells, that model the temperature -// at each point along the line. Every cycle through the simulation, -// four steps are performed: -// 1) All cells cool down a little bit, losing heat to the air -// 2) The heat from each cell drifts 'up' and diffuses a little -// 3) Sometimes randomly new 'sparks' of heat are added at the bottom -// 4) The heat from each cell is rendered as a color into the leds array -// The heat-to-color mapping uses a black-body radiation approximation. -// -// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot). -// -// This simulation scales it self a bit depending on NUM_LEDS; it should look -// "OK" on anywhere from 20 to 100 LEDs without too much tweaking. -// -// I recommend running this simulation at anywhere from 30-100 frames per second, -// meaning an interframe delay of about 10-35 milliseconds. -// -// Looks best on a high-density LED setup (60+ pixels/meter). -// -// -// There are two main parameters you can play with to control the look and -// feel of your fire: COOLING (used in step 1 above), and SPARKING (used -// in step 3 above). -// -// COOLING: How much does the air cool as it rises? -// Less cooling = taller flames. More cooling = shorter flames. -// Default 50, suggested range 20-100 -#define COOLING 55 - -// SPARKING: What chance (out of 255) is there that a new spark will be lit? -// Higher chance = more roaring fire. Lower chance = more flickery fire. -// Default 120, suggested range 50-200. -#define SPARKING 120 - - -void Fire2012() -{ -// Array of temperature readings at each simulation cell - static byte heat[NUM_LEDS]; - - // Step 1. Cool down every cell a little - for( int i = 0; i < NUM_LEDS; i++) { - heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); - } - - // Step 2. Heat from each cell drifts 'up' and diffuses a little - for( int k= NUM_LEDS - 1; k >= 2; k--) { - heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; - } - - // Step 3. Randomly ignite new 'sparks' of heat near the bottom - if( random8() < SPARKING ) { - int y = random8(7); - heat[y] = qadd8( heat[y], random8(160,255) ); - } - - // Step 4. Map from heat cells to LED colors - for( int j = 0; j < NUM_LEDS; j++) { - CRGB color = HeatColor( heat[j]); - int pixelnumber; - if( gReverseDirection ) { - pixelnumber = (NUM_LEDS-1) - j; - } else { - pixelnumber = j; - } - leds[pixelnumber] = color; - } -} - diff --git a/FastLED/examples/Fire2012WithPalette/Fire2012WithPalette.ino b/FastLED/examples/Fire2012WithPalette/Fire2012WithPalette.ino deleted file mode 100644 index e65a87fb0357df4f4c6e7ad1746eb048e4e38f8f..0000000000000000000000000000000000000000 --- a/FastLED/examples/Fire2012WithPalette/Fire2012WithPalette.ino +++ /dev/null @@ -1,164 +0,0 @@ -#include <FastLED.h> - -#define LED_PIN 5 -#define COLOR_ORDER GRB -#define CHIPSET WS2811 -#define NUM_LEDS 30 - -#define BRIGHTNESS 200 -#define FRAMES_PER_SECOND 60 - -bool gReverseDirection = false; - -CRGB leds[NUM_LEDS]; - -// Fire2012 with programmable Color Palette -// -// This code is the same fire simulation as the original "Fire2012", -// but each heat cell's temperature is translated to color through a FastLED -// programmable color palette, instead of through the "HeatColor(...)" function. -// -// Four different static color palettes are provided here, plus one dynamic one. -// -// The three static ones are: -// 1. the FastLED built-in HeatColors_p -- this is the default, and it looks -// pretty much exactly like the original Fire2012. -// -// To use any of the other palettes below, just "uncomment" the corresponding code. -// -// 2. a gradient from black to red to yellow to white, which is -// visually similar to the HeatColors_p, and helps to illustrate -// what the 'heat colors' palette is actually doing, -// 3. a similar gradient, but in blue colors rather than red ones, -// i.e. from black to blue to aqua to white, which results in -// an "icy blue" fire effect, -// 4. a simplified three-step gradient, from black to red to white, just to show -// that these gradients need not have four components; two or -// three are possible, too, even if they don't look quite as nice for fire. -// -// The dynamic palette shows how you can change the basic 'hue' of the -// color palette every time through the loop, producing "rainbow fire". - -CRGBPalette16 gPal; - -void setup() { - delay(3000); // sanity delay - FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); - FastLED.setBrightness( BRIGHTNESS ); - - // This first palette is the basic 'black body radiation' colors, - // which run from black to red to bright yellow to white. - gPal = HeatColors_p; - - // These are other ways to set up the color palette for the 'fire'. - // First, a gradient from black to red to yellow to white -- similar to HeatColors_p - // gPal = CRGBPalette16( CRGB::Black, CRGB::Red, CRGB::Yellow, CRGB::White); - - // Second, this palette is like the heat colors, but blue/aqua instead of red/yellow - // gPal = CRGBPalette16( CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White); - - // Third, here's a simpler, three-step gradient, from black to red to white - // gPal = CRGBPalette16( CRGB::Black, CRGB::Red, CRGB::White); - -} - -void loop() -{ - // Add entropy to random number generator; we use a lot of it. - random16_add_entropy( random()); - - // Fourth, the most sophisticated: this one sets up a new palette every - // time through the loop, based on a hue that changes every time. - // The palette is a gradient from black, to a dark color based on the hue, - // to a light color based on the hue, to white. - // - // static uint8_t hue = 0; - // hue++; - // CRGB darkcolor = CHSV(hue,255,192); // pure hue, three-quarters brightness - // CRGB lightcolor = CHSV(hue,128,255); // half 'whitened', full brightness - // gPal = CRGBPalette16( CRGB::Black, darkcolor, lightcolor, CRGB::White); - - - Fire2012WithPalette(); // run simulation frame, using palette colors - - FastLED.show(); // display this frame - FastLED.delay(1000 / FRAMES_PER_SECOND); -} - - -// Fire2012 by Mark Kriegsman, July 2012 -// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY -//// -// This basic one-dimensional 'fire' simulation works roughly as follows: -// There's a underlying array of 'heat' cells, that model the temperature -// at each point along the line. Every cycle through the simulation, -// four steps are performed: -// 1) All cells cool down a little bit, losing heat to the air -// 2) The heat from each cell drifts 'up' and diffuses a little -// 3) Sometimes randomly new 'sparks' of heat are added at the bottom -// 4) The heat from each cell is rendered as a color into the leds array -// The heat-to-color mapping uses a black-body radiation approximation. -// -// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot). -// -// This simulation scales it self a bit depending on NUM_LEDS; it should look -// "OK" on anywhere from 20 to 100 LEDs without too much tweaking. -// -// I recommend running this simulation at anywhere from 30-100 frames per second, -// meaning an interframe delay of about 10-35 milliseconds. -// -// Looks best on a high-density LED setup (60+ pixels/meter). -// -// -// There are two main parameters you can play with to control the look and -// feel of your fire: COOLING (used in step 1 above), and SPARKING (used -// in step 3 above). -// -// COOLING: How much does the air cool as it rises? -// Less cooling = taller flames. More cooling = shorter flames. -// Default 55, suggested range 20-100 -#define COOLING 55 - -// SPARKING: What chance (out of 255) is there that a new spark will be lit? -// Higher chance = more roaring fire. Lower chance = more flickery fire. -// Default 120, suggested range 50-200. -#define SPARKING 120 - - -void Fire2012WithPalette() -{ -// Array of temperature readings at each simulation cell - static byte heat[NUM_LEDS]; - - // Step 1. Cool down every cell a little - for( int i = 0; i < NUM_LEDS; i++) { - heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); - } - - // Step 2. Heat from each cell drifts 'up' and diffuses a little - for( int k= NUM_LEDS - 1; k >= 2; k--) { - heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; - } - - // Step 3. Randomly ignite new 'sparks' of heat near the bottom - if( random8() < SPARKING ) { - int y = random8(7); - heat[y] = qadd8( heat[y], random8(160,255) ); - } - - // Step 4. Map from heat cells to LED colors - for( int j = 0; j < NUM_LEDS; j++) { - // Scale the heat value from 0-255 down to 0-240 - // for best results with color palettes. - byte colorindex = scale8( heat[j], 240); - CRGB color = ColorFromPalette( gPal, colorindex); - int pixelnumber; - if( gReverseDirection ) { - pixelnumber = (NUM_LEDS-1) - j; - } else { - pixelnumber = j; - } - leds[pixelnumber] = color; - } -} - diff --git a/FastLED/examples/FirstLight/FirstLight.ino b/FastLED/examples/FirstLight/FirstLight.ino deleted file mode 100644 index 8eaf4e231bf9030826e933867e7cd23fe344e892..0000000000000000000000000000000000000000 --- a/FastLED/examples/FirstLight/FirstLight.ino +++ /dev/null @@ -1,92 +0,0 @@ -// Use if you want to force the software SPI subsystem to be used for some reason (generally, you don't) -// #define FASTLED_FORCE_SOFTWARE_SPI -// Use if you want to force non-accelerated pin access (hint: you really don't, it breaks lots of things) -// #define FASTLED_FORCE_SOFTWARE_SPI -// #define FASTLED_FORCE_SOFTWARE_PINS -#include <FastLED.h> - -/////////////////////////////////////////////////////////////////////////////////////////// -// -// Move a white dot along the strip of leds. This program simply shows how to configure the leds, -// and then how to turn a single pixel white and then off, moving down the line of pixels. -// - -// How many leds are in the strip? -#define NUM_LEDS 60 - -// For led chips like WS2812, which have a data line, ground, and power, you just -// need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, -// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN -// Clock pin only needed for SPI based chipsets when not using hardware SPI -#define DATA_PIN 3 -#define CLOCK_PIN 13 - -// This is an array of leds. One item for each led in your strip. -CRGB leds[NUM_LEDS]; - -// This function sets up the ledsand tells the controller about them -void setup() { - // sanity check delay - allows reprogramming if accidently blowing power w/leds - delay(2000); - - // Uncomment/edit one of the following lines for your leds arrangement. - // ## Clockless types ## - // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); // GRB ordering is assumed - // FastLED.addLeds<SM16703, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1829, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1812, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1904, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS2903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2852, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<GS1903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SK6812, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<APA106, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS); - FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2813, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GE8822, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<LPD1886, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<LPD1886_8BIT, DATA_PIN, RGB>(leds, NUM_LEDS); - // ## Clocked (SPI) types ## - // FastLED.addLeds<LPD6803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<SK9822, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical -} - -// This function runs over and over, and is where you do the magic to light -// your leds. -void loop() { - // Move a single white led - for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) { - // Turn our current led on to white, then show the leds - leds[whiteLed] = CRGB::White; - - // Show the leds (only one of which is set to white, from above) - FastLED.show(); - - // Wait a little bit - delay(100); - - // Turn our current led back to black for the next loop around - leds[whiteLed] = CRGB::Black; - } -} diff --git a/FastLED/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino b/FastLED/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino deleted file mode 100644 index 3b7a9c79dc89d7fcfe1f663d9a558753ab7f73fb..0000000000000000000000000000000000000000 --- a/FastLED/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino +++ /dev/null @@ -1,37 +0,0 @@ -// ArrayOfLedArrays - see https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples for more info on -// using multiple controllers. In this example, we're going to set up three NEOPIXEL strips on three -// different pins, each strip getting its own CRGB array to be played with, only this time they're going -// to be all parts of an array of arrays. - -#include <FastLED.h> - -#define NUM_STRIPS 3 -#define NUM_LEDS_PER_STRIP 60 -CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP]; - -// For mirroring strips, all the "special" stuff happens just in setup. We -// just addLeds multiple times, once for each strip -void setup() { - // tell FastLED there's 60 NEOPIXEL leds on pin 10 - FastLED.addLeds<NEOPIXEL, 10>(leds[0], NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 11 - FastLED.addLeds<NEOPIXEL, 11>(leds[1], NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 12 - FastLED.addLeds<NEOPIXEL, 12>(leds[2], NUM_LEDS_PER_STRIP); - -} - -void loop() { - // This outer loop will go over each strip, one at a time - for(int x = 0; x < NUM_STRIPS; x++) { - // This inner loop will go over each led in the current strip, one at a time - for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) { - leds[x][i] = CRGB::Red; - FastLED.show(); - leds[x][i] = CRGB::Black; - delay(100); - } - } -} diff --git a/FastLED/examples/Multiple/MirroringSample/MirroringSample.ino b/FastLED/examples/Multiple/MirroringSample/MirroringSample.ino deleted file mode 100644 index a6d63121edcb7db29372ad7babd6ac9ed65aa319..0000000000000000000000000000000000000000 --- a/FastLED/examples/Multiple/MirroringSample/MirroringSample.ino +++ /dev/null @@ -1,44 +0,0 @@ -// MirroringSample - see https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples for more info on -// using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on four -// different pins, and show the same thing on all four of them, a simple bouncing dot/cyclon type pattern - -#include <FastLED.h> - -#define NUM_LEDS_PER_STRIP 60 -CRGB leds[NUM_LEDS_PER_STRIP]; - -// For mirroring strips, all the "special" stuff happens just in setup. We -// just addLeds multiple times, once for each strip -void setup() { - // tell FastLED there's 60 NEOPIXEL leds on pin 4 - FastLED.addLeds<NEOPIXEL, 4>(leds, NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 5 - FastLED.addLeds<NEOPIXEL, 5>(leds, NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 6 - FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 7 - FastLED.addLeds<NEOPIXEL, 7>(leds, NUM_LEDS_PER_STRIP); -} - -void loop() { - for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) { - // set our current dot to red - leds[i] = CRGB::Red; - FastLED.show(); - // clear our current dot before we move on - leds[i] = CRGB::Black; - delay(100); - } - - for(int i = NUM_LEDS_PER_STRIP-1; i >= 0; i--) { - // set our current dot to red - leds[i] = CRGB::Red; - FastLED.show(); - // clear our current dot before we move on - leds[i] = CRGB::Black; - delay(100); - } -} diff --git a/FastLED/examples/Multiple/MultiArrays/MultiArrays.ino b/FastLED/examples/Multiple/MultiArrays/MultiArrays.ino deleted file mode 100644 index 9d3cbb6b7fd858e55b51556e3b700ab3a3292dc8..0000000000000000000000000000000000000000 --- a/FastLED/examples/Multiple/MultiArrays/MultiArrays.ino +++ /dev/null @@ -1,52 +0,0 @@ -// MultiArrays - see https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples for more info on -// using multiple controllers. In this example, we're going to set up three NEOPIXEL strips on three -// different pins, each strip getting its own CRGB array to be played with - -#include <FastLED.h> - -#define NUM_LEDS_PER_STRIP 60 -CRGB redLeds[NUM_LEDS_PER_STRIP]; -CRGB greenLeds[NUM_LEDS_PER_STRIP]; -CRGB blueLeds[NUM_LEDS_PER_STRIP]; - -// For mirroring strips, all the "special" stuff happens just in setup. We -// just addLeds multiple times, once for each strip -void setup() { - // tell FastLED there's 60 NEOPIXEL leds on pin 10 - FastLED.addLeds<NEOPIXEL, 10>(redLeds, NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 11 - FastLED.addLeds<NEOPIXEL, 11>(greenLeds, NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 12 - FastLED.addLeds<NEOPIXEL, 12>(blueLeds, NUM_LEDS_PER_STRIP); - -} - -void loop() { - for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) { - // set our current dot to red, green, and blue - redLeds[i] = CRGB::Red; - greenLeds[i] = CRGB::Green; - blueLeds[i] = CRGB::Blue; - FastLED.show(); - // clear our current dot before we move on - redLeds[i] = CRGB::Black; - greenLeds[i] = CRGB::Black; - blueLeds[i] = CRGB::Black; - delay(100); - } - - for(int i = NUM_LEDS_PER_STRIP-1; i >= 0; i--) { - // set our current dot to red, green, and blue - redLeds[i] = CRGB::Red; - greenLeds[i] = CRGB::Green; - blueLeds[i] = CRGB::Blue; - FastLED.show(); - // clear our current dot before we move on - redLeds[i] = CRGB::Black; - greenLeds[i] = CRGB::Black; - blueLeds[i] = CRGB::Black; - delay(100); - } -} diff --git a/FastLED/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino b/FastLED/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino deleted file mode 100644 index 15d58bcb947900bac2fb891f666e2834e29b219e..0000000000000000000000000000000000000000 --- a/FastLED/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino +++ /dev/null @@ -1,34 +0,0 @@ -// MultipleStripsInOneArray - see https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples for more info on -// using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on three -// different pins, each strip will be referring to a different part of the single led array - -#include <FastLED.h> - -#define NUM_STRIPS 3 -#define NUM_LEDS_PER_STRIP 60 -#define NUM_LEDS NUM_LEDS_PER_STRIP * NUM_STRIPS - -CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP]; - -// For mirroring strips, all the "special" stuff happens just in setup. We -// just addLeds multiple times, once for each strip -void setup() { - // tell FastLED there's 60 NEOPIXEL leds on pin 10, starting at index 0 in the led array - FastLED.addLeds<NEOPIXEL, 10>(leds, 0, NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 11, starting at index 60 in the led array - FastLED.addLeds<NEOPIXEL, 11>(leds, NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP); - - // tell FastLED there's 60 NEOPIXEL leds on pin 12, starting at index 120 in the led array - FastLED.addLeds<NEOPIXEL, 12>(leds, 2 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP); - -} - -void loop() { - for(int i = 0; i < NUM_LEDS; i++) { - leds[i] = CRGB::Red; - FastLED.show(); - leds[i] = CRGB::Black; - delay(100); - } -} diff --git a/FastLED/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino b/FastLED/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino deleted file mode 100644 index d8d73fe27b8813d1949937ac0e214bca8fc1b399..0000000000000000000000000000000000000000 --- a/FastLED/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino +++ /dev/null @@ -1,37 +0,0 @@ -#define USE_OCTOWS2811 -#include <OctoWS2811.h> -#include <FastLED.h> - -#define NUM_LEDS_PER_STRIP 64 -#define NUM_STRIPS 8 - -CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP]; - -// Pin layouts on the teensy 3: -// OctoWS2811: 2,14,7,8,6,20,21,5 - -void setup() { - LEDS.addLeds<OCTOWS2811>(leds, NUM_LEDS_PER_STRIP); - LEDS.setBrightness(32); -} - -void loop() { - static uint8_t hue = 0; - for(int i = 0; i < NUM_STRIPS; i++) { - for(int j = 0; j < NUM_LEDS_PER_STRIP; j++) { - leds[(i*NUM_LEDS_PER_STRIP) + j] = CHSV((32*i) + hue+j,192,255); - } - } - - // Set the first n leds on each strip to show which strip it is - for(int i = 0; i < NUM_STRIPS; i++) { - for(int j = 0; j <= i; j++) { - leds[(i*NUM_LEDS_PER_STRIP) + j] = CRGB::Red; - } - } - - hue++; - - LEDS.show(); - LEDS.delay(10); -} diff --git a/FastLED/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino b/FastLED/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino deleted file mode 100644 index 8c447b54d6881f9748838d8c7052782ca92f37e0..0000000000000000000000000000000000000000 --- a/FastLED/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino +++ /dev/null @@ -1,56 +0,0 @@ -#include <FastLED.h> - -#define NUM_LEDS_PER_STRIP 16 -// Note: this can be 12 if you're using a teensy 3 and don't mind soldering the pads on the back -#define NUM_STRIPS 16 - -CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP]; - -// Pin layouts on the teensy 3/3.1: -// WS2811_PORTD: 2,14,7,8,6,20,21,5 -// WS2811_PORTC: 15,22,23,9,10,13,11,12,28,27,29,30 (these last 4 are pads on the bottom of the teensy) -// WS2811_PORTDC: 2,14,7,8,6,20,21,5,15,22,23,9,10,13,11,12 - 16 way parallel -// -// Pin layouts on the due -// WS2811_PORTA: 69,68,61,60,59,100,58,31 (note: pin 100 only available on the digix) -// WS2811_PORTB: 90,91,92,93,94,95,96,97 (note: only available on the digix) -// WS2811_PORTD: 25,26,27,28,14,15,29,11 -// - - -// IBCC<WS2811, 1, 16> outputs; - -void setup() { - delay(5000); - Serial.begin(57600); - Serial.println("Starting..."); - // LEDS.addLeds<WS2811_PORTA,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP); - // LEDS.addLeds<WS2811_PORTB,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP); - // LEDS.addLeds<WS2811_PORTD,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip); - LEDS.addLeds<WS2811_PORTDC,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP); - - // Teensy 4 parallel output example - // LEDS.addLeds<NUM_STRIPS, WS2811, 1>(leds,NUM_LEDS_PER_STRIP); -} - -void loop() { - Serial.println("Loop...."); - static uint8_t hue = 0; - for(int i = 0; i < NUM_STRIPS; i++) { - for(int j = 0; j < NUM_LEDS_PER_STRIP; j++) { - leds[(i*NUM_LEDS_PER_STRIP) + j] = CHSV((32*i) + hue+j,192,255); - } - } - - // Set the first n leds on each strip to show which strip it is - for(int i = 0; i < NUM_STRIPS; i++) { - for(int j = 0; j <= i; j++) { - leds[(i*NUM_LEDS_PER_STRIP) + j] = CRGB::Red; - } - } - - hue++; - - LEDS.show(); - // LEDS.delay(100); -} diff --git a/FastLED/examples/Noise/Noise.ino b/FastLED/examples/Noise/Noise.ino deleted file mode 100644 index e196e6bb4158c4d55b320cd56e55b21a7b4ac62e..0000000000000000000000000000000000000000 --- a/FastLED/examples/Noise/Noise.ino +++ /dev/null @@ -1,112 +0,0 @@ -#include <FastLED.h> - -// -// Mark's xy coordinate mapping code. See the XYMatrix for more information on it. -// - -// Params for width and height -const uint8_t kMatrixWidth = 16; -const uint8_t kMatrixHeight = 16; -#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) -#define NUM_LEDS (kMatrixWidth * kMatrixHeight) -// Param for different pixel layouts -const bool kMatrixSerpentineLayout = true; - - -uint16_t XY( uint8_t x, uint8_t y) -{ - uint16_t i; - - if( kMatrixSerpentineLayout == false) { - i = (y * kMatrixWidth) + x; - } - - if( kMatrixSerpentineLayout == true) { - if( y & 0x01) { - // Odd rows run backwards - uint8_t reverseX = (kMatrixWidth - 1) - x; - i = (y * kMatrixWidth) + reverseX; - } else { - // Even rows run forwards - i = (y * kMatrixWidth) + x; - } - } - - return i; -} - -// The leds -CRGB leds[kMatrixWidth * kMatrixHeight]; - -// The 32bit version of our coordinates -static uint16_t x; -static uint16_t y; -static uint16_t z; - -// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll -// use the z-axis for "time". speed determines how fast time moves forward. Try -// 1 for a very slow moving effect, or 60 for something that ends up looking like -// water. -// uint16_t speed = 1; // almost looks like a painting, moves very slowly -uint16_t speed = 20; // a nice starting speed, mixes well with a scale of 100 -// uint16_t speed = 33; -// uint16_t speed = 100; // wicked fast! - -// Scale determines how far apart the pixels in our noise matrix are. Try -// changing these values around to see how it affects the motion of the display. The -// higher the value of scale, the more "zoomed out" the noise iwll be. A value -// of 1 will be so zoomed in, you'll mostly see solid colors. - -// uint16_t scale = 1; // mostly just solid colors -// uint16_t scale = 4011; // very zoomed out and shimmery -uint16_t scale = 311; - -// This is the array that we keep our computed noise values in -uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; - -void setup() { - // uncomment the following lines if you want to see FPS count information - // Serial.begin(38400); - // Serial.println("resetting!"); - delay(3000); - LEDS.addLeds<WS2811,5,RGB>(leds,NUM_LEDS); - LEDS.setBrightness(96); - - // Initialize our coordinates to some random values - x = random16(); - y = random16(); - z = random16(); -} - -// Fill the x/y array of 8-bit noise values using the inoise8 function. -void fillnoise8() { - for(int i = 0; i < MAX_DIMENSION; i++) { - int ioffset = scale * i; - for(int j = 0; j < MAX_DIMENSION; j++) { - int joffset = scale * j; - noise[i][j] = inoise8(x + ioffset,y + joffset,z); - } - } - z += speed; -} - - -void loop() { - static uint8_t ihue=0; - fillnoise8(); - for(int i = 0; i < kMatrixWidth; i++) { - for(int j = 0; j < kMatrixHeight; j++) { - // We use the value at the (i,j) coordinate in the noise - // array for our brightness, and the flipped value from (j,i) - // for our pixel's hue. - leds[XY(i,j)] = CHSV(noise[j][i],255,noise[i][j]); - - // You can also explore other ways to constrain the hue used, like below - // leds[XY(i,j)] = CHSV(ihue + (noise[j][i]>>2),255,noise[i][j]); - } - } - ihue+=1; - - LEDS.show(); - // delay(10); -} diff --git a/FastLED/examples/NoisePlayground/NoisePlayground.ino b/FastLED/examples/NoisePlayground/NoisePlayground.ino deleted file mode 100644 index e2c7cb3154c0a163bd35b69f4283b2f6336aa988..0000000000000000000000000000000000000000 --- a/FastLED/examples/NoisePlayground/NoisePlayground.ino +++ /dev/null @@ -1,73 +0,0 @@ -#include <FastLED.h> - -#define kMatrixWidth 16 -#define kMatrixHeight 16 - -#define NUM_LEDS (kMatrixWidth * kMatrixHeight) -// Param for different pixel layouts -#define kMatrixSerpentineLayout true - -// led array -CRGB leds[kMatrixWidth * kMatrixHeight]; - -// x,y, & time values -uint32_t x,y,v_time,hue_time,hxy; - -// Play with the values of the variables below and see what kinds of effects they -// have! More octaves will make things slower. - -// how many octaves to use for the brightness and hue functions -uint8_t octaves=1; -uint8_t hue_octaves=3; - -// the 'distance' between points on the x and y axis -int xscale=57771; -int yscale=57771; - -// the 'distance' between x/y points for the hue noise -int hue_scale=1; - -// how fast we move through time & hue noise -int time_speed=1111; -int hue_speed=31; - -// adjust these values to move along the x or y axis between frames -int x_speed=331; -int y_speed=1111; - -void loop() { - // fill the led array 2/16-bit noise values - fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, - octaves,x,xscale,y,yscale,v_time, - hue_octaves,hxy,hue_scale,hxy,hue_scale,hue_time, false); - - LEDS.show(); - - // adjust the intra-frame time values - x += x_speed; - y += y_speed; - v_time += time_speed; - hue_time += hue_speed; - // delay(50); -} - - -void setup() { - // initialize the x/y and time values - random16_set_seed(8934); - random16_add_entropy(analogRead(3)); - - Serial.begin(57600); - Serial.println("resetting!"); - - delay(3000); - LEDS.addLeds<WS2811,6,GRB>(leds,NUM_LEDS); - LEDS.setBrightness(96); - - hxy = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); - x = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); - y = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); - v_time = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); - hue_time = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); - -} diff --git a/FastLED/examples/NoisePlusPalette/NoisePlusPalette.ino b/FastLED/examples/NoisePlusPalette/NoisePlusPalette.ino deleted file mode 100644 index e95e4128d7517dacd33bcd1acbef6c2971cb8490..0000000000000000000000000000000000000000 --- a/FastLED/examples/NoisePlusPalette/NoisePlusPalette.ino +++ /dev/null @@ -1,273 +0,0 @@ -#include <FastLED.h> - -#define LED_PIN 3 -#define BRIGHTNESS 96 -#define LED_TYPE WS2811 -#define COLOR_ORDER GRB - -const uint8_t kMatrixWidth = 16; -const uint8_t kMatrixHeight = 16; -const bool kMatrixSerpentineLayout = true; - - -// This example combines two features of FastLED to produce a remarkable range of -// effects from a relatively small amount of code. This example combines FastLED's -// color palette lookup functions with FastLED's Perlin/simplex noise generator, and -// the combination is extremely powerful. -// -// You might want to look at the "ColorPalette" and "Noise" examples separately -// if this example code seems daunting. -// -// -// The basic setup here is that for each frame, we generate a new array of -// 'noise' data, and then map it onto the LED matrix through a color palette. -// -// Periodically, the color palette is changed, and new noise-generation parameters -// are chosen at the same time. In this example, specific noise-generation -// values have been selected to match the given color palettes; some are faster, -// or slower, or larger, or smaller than others, but there's no reason these -// parameters can't be freely mixed-and-matched. -// -// In addition, this example includes some fast automatic 'data smoothing' at -// lower noise speeds to help produce smoother animations in those cases. -// -// The FastLED built-in color palettes (Forest, Clouds, Lava, Ocean, Party) are -// used, as well as some 'hand-defined' ones, and some proceedurally generated -// palettes. - - -#define NUM_LEDS (kMatrixWidth * kMatrixHeight) -#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) - -// The leds -CRGB leds[kMatrixWidth * kMatrixHeight]; - -// The 16 bit version of our coordinates -static uint16_t x; -static uint16_t y; -static uint16_t z; - -// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll -// use the z-axis for "time". speed determines how fast time moves forward. Try -// 1 for a very slow moving effect, or 60 for something that ends up looking like -// water. -uint16_t speed = 20; // speed is set dynamically once we've started up - -// Scale determines how far apart the pixels in our noise matrix are. Try -// changing these values around to see how it affects the motion of the display. The -// higher the value of scale, the more "zoomed out" the noise iwll be. A value -// of 1 will be so zoomed in, you'll mostly see solid colors. -uint16_t scale = 30; // scale is set dynamically once we've started up - -// This is the array that we keep our computed noise values in -uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; - -CRGBPalette16 currentPalette( PartyColors_p ); -uint8_t colorLoop = 1; - -void setup() { - delay(3000); - LEDS.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,NUM_LEDS); - LEDS.setBrightness(BRIGHTNESS); - - // Initialize our coordinates to some random values - x = random16(); - y = random16(); - z = random16(); -} - - - -// Fill the x/y array of 8-bit noise values using the inoise8 function. -void fillnoise8() { - // If we're runing at a low "speed", some 8-bit artifacts become visible - // from frame-to-frame. In order to reduce this, we can do some fast data-smoothing. - // The amount of data smoothing we're doing depends on "speed". - uint8_t dataSmoothing = 0; - if( speed < 50) { - dataSmoothing = 200 - (speed * 4); - } - - for(int i = 0; i < MAX_DIMENSION; i++) { - int ioffset = scale * i; - for(int j = 0; j < MAX_DIMENSION; j++) { - int joffset = scale * j; - - uint8_t data = inoise8(x + ioffset,y + joffset,z); - - // The range of the inoise8 function is roughly 16-238. - // These two operations expand those values out to roughly 0..255 - // You can comment them out if you want the raw noise data. - data = qsub8(data,16); - data = qadd8(data,scale8(data,39)); - - if( dataSmoothing ) { - uint8_t olddata = noise[i][j]; - uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing); - data = newdata; - } - - noise[i][j] = data; - } - } - - z += speed; - - // apply slow drift to X and Y, just for visual variation. - x += speed / 8; - y -= speed / 16; -} - -void mapNoiseToLEDsUsingPalette() -{ - static uint8_t ihue=0; - - for(int i = 0; i < kMatrixWidth; i++) { - for(int j = 0; j < kMatrixHeight; j++) { - // We use the value at the (i,j) coordinate in the noise - // array for our brightness, and the flipped value from (j,i) - // for our pixel's index into the color palette. - - uint8_t index = noise[j][i]; - uint8_t bri = noise[i][j]; - - // if this palette is a 'loop', add a slowly-changing base value - if( colorLoop) { - index += ihue; - } - - // brighten up, as the color palette itself often contains the - // light/dark dynamic range desired - if( bri > 127 ) { - bri = 255; - } else { - bri = dim8_raw( bri * 2); - } - - CRGB color = ColorFromPalette( currentPalette, index, bri); - leds[XY(i,j)] = color; - } - } - - ihue+=1; -} - -void loop() { - // Periodically choose a new palette, speed, and scale - ChangePaletteAndSettingsPeriodically(); - - // generate noise data - fillnoise8(); - - // convert the noise data to colors in the LED array - // using the current palette - mapNoiseToLEDsUsingPalette(); - - LEDS.show(); - // delay(10); -} - - - -// There are several different palettes of colors demonstrated here. -// -// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, -// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. -// -// Additionally, you can manually define your own color palettes, or you can write -// code that creates color palettes on the fly. - -// 1 = 5 sec per palette -// 2 = 10 sec per palette -// etc -#define HOLD_PALETTES_X_TIMES_AS_LONG 1 - -void ChangePaletteAndSettingsPeriodically() -{ - uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60; - static uint8_t lastSecond = 99; - - if( lastSecond != secondHand) { - lastSecond = secondHand; - if( secondHand == 0) { currentPalette = RainbowColors_p; speed = 20; scale = 30; colorLoop = 1; } - if( secondHand == 5) { SetupPurpleAndGreenPalette(); speed = 10; scale = 50; colorLoop = 1; } - if( secondHand == 10) { SetupBlackAndWhiteStripedPalette(); speed = 20; scale = 30; colorLoop = 1; } - if( secondHand == 15) { currentPalette = ForestColors_p; speed = 8; scale =120; colorLoop = 0; } - if( secondHand == 20) { currentPalette = CloudColors_p; speed = 4; scale = 30; colorLoop = 0; } - if( secondHand == 25) { currentPalette = LavaColors_p; speed = 8; scale = 50; colorLoop = 0; } - if( secondHand == 30) { currentPalette = OceanColors_p; speed = 20; scale = 90; colorLoop = 0; } - if( secondHand == 35) { currentPalette = PartyColors_p; speed = 20; scale = 30; colorLoop = 1; } - if( secondHand == 40) { SetupRandomPalette(); speed = 20; scale = 20; colorLoop = 1; } - if( secondHand == 45) { SetupRandomPalette(); speed = 50; scale = 50; colorLoop = 1; } - if( secondHand == 50) { SetupRandomPalette(); speed = 90; scale = 90; colorLoop = 1; } - if( secondHand == 55) { currentPalette = RainbowStripeColors_p; speed = 30; scale = 20; colorLoop = 1; } - } -} - -// This function generates a random palette that's a gradient -// between four different colors. The first is a dim hue, the second is -// a bright hue, the third is a bright pastel, and the last is -// another bright hue. This gives some visual bright/dark variation -// which is more interesting than just a gradient of different hues. -void SetupRandomPalette() -{ - currentPalette = CRGBPalette16( - CHSV( random8(), 255, 32), - CHSV( random8(), 255, 255), - CHSV( random8(), 128, 255), - CHSV( random8(), 255, 255)); -} - -// This function sets up a palette of black and white stripes, -// using code. Since the palette is effectively an array of -// sixteen CRGB colors, the various fill_* functions can be used -// to set them up. -void SetupBlackAndWhiteStripedPalette() -{ - // 'black out' all 16 palette entries... - fill_solid( currentPalette, 16, CRGB::Black); - // and set every fourth one to white. - currentPalette[0] = CRGB::White; - currentPalette[4] = CRGB::White; - currentPalette[8] = CRGB::White; - currentPalette[12] = CRGB::White; - -} - -// This function sets up a palette of purple and green stripes. -void SetupPurpleAndGreenPalette() -{ - CRGB purple = CHSV( HUE_PURPLE, 255, 255); - CRGB green = CHSV( HUE_GREEN, 255, 255); - CRGB black = CRGB::Black; - - currentPalette = CRGBPalette16( - green, green, black, black, - purple, purple, black, black, - green, green, black, black, - purple, purple, black, black ); -} - - -// -// Mark's xy coordinate mapping code. See the XYMatrix for more information on it. -// -uint16_t XY( uint8_t x, uint8_t y) -{ - uint16_t i; - if( kMatrixSerpentineLayout == false) { - i = (y * kMatrixWidth) + x; - } - if( kMatrixSerpentineLayout == true) { - if( y & 0x01) { - // Odd rows run backwards - uint8_t reverseX = (kMatrixWidth - 1) - x; - i = (y * kMatrixWidth) + reverseX; - } else { - // Even rows run forwards - i = (y * kMatrixWidth) + x; - } - } - return i; -} - diff --git a/FastLED/examples/Pacifica/Pacifica.ino b/FastLED/examples/Pacifica/Pacifica.ino deleted file mode 100644 index 29ac9fcc748f7da9177db4beeea5c07e25904282..0000000000000000000000000000000000000000 --- a/FastLED/examples/Pacifica/Pacifica.ino +++ /dev/null @@ -1,152 +0,0 @@ -// -// "Pacifica" -// Gentle, blue-green ocean waves. -// December 2019, Mark Kriegsman and Mary Corey March. -// For Dan. -// - -#define FASTLED_ALLOW_INTERRUPTS 0 -#include <FastLED.h> -FASTLED_USING_NAMESPACE - -#define DATA_PIN 3 -#define NUM_LEDS 60 -#define MAX_POWER_MILLIAMPS 500 -#define LED_TYPE WS2812B -#define COLOR_ORDER GRB - -////////////////////////////////////////////////////////////////////////// - -CRGB leds[NUM_LEDS]; - -void setup() { - delay( 3000); // 3 second delay for boot recovery, and a moment of silence - FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS) - .setCorrection( TypicalLEDStrip ); - FastLED.setMaxPowerInVoltsAndMilliamps( 5, MAX_POWER_MILLIAMPS); -} - -void loop() -{ - EVERY_N_MILLISECONDS( 20) { - pacifica_loop(); - FastLED.show(); - } -} - -////////////////////////////////////////////////////////////////////////// -// -// The code for this animation is more complicated than other examples, and -// while it is "ready to run", and documented in general, it is probably not -// the best starting point for learning. Nevertheless, it does illustrate some -// useful techniques. -// -////////////////////////////////////////////////////////////////////////// -// -// In this animation, there are four "layers" of waves of light. -// -// Each layer moves independently, and each is scaled separately. -// -// All four wave layers are added together on top of each other, and then -// another filter is applied that adds "whitecaps" of brightness where the -// waves line up with each other more. Finally, another pass is taken -// over the led array to 'deepen' (dim) the blues and greens. -// -// The speed and scale and motion each layer varies slowly within independent -// hand-chosen ranges, which is why the code has a lot of low-speed 'beatsin8' functions -// with a lot of oddly specific numeric ranges. -// -// These three custom blue-green color palettes were inspired by the colors found in -// the waters off the southern coast of California, https://goo.gl/maps/QQgd97jjHesHZVxQ7 -// -CRGBPalette16 pacifica_palette_1 = - { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, - 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 }; -CRGBPalette16 pacifica_palette_2 = - { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, - 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F }; -CRGBPalette16 pacifica_palette_3 = - { 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33, - 0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF }; - - -void pacifica_loop() -{ - // Increment the four "color index start" counters, one for each wave layer. - // Each is incremented at a different speed, and the speeds vary over time. - static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4; - static uint32_t sLastms = 0; - uint32_t ms = GET_MILLIS(); - uint32_t deltams = ms - sLastms; - sLastms = ms; - uint16_t speedfactor1 = beatsin16(3, 179, 269); - uint16_t speedfactor2 = beatsin16(4, 179, 269); - uint32_t deltams1 = (deltams * speedfactor1) / 256; - uint32_t deltams2 = (deltams * speedfactor2) / 256; - uint32_t deltams21 = (deltams1 + deltams2) / 2; - sCIStart1 += (deltams1 * beatsin88(1011,10,13)); - sCIStart2 -= (deltams21 * beatsin88(777,8,11)); - sCIStart3 -= (deltams1 * beatsin88(501,5,7)); - sCIStart4 -= (deltams2 * beatsin88(257,4,6)); - - // Clear out the LED array to a dim background blue-green - fill_solid( leds, NUM_LEDS, CRGB( 2, 6, 10)); - - // Render each of four layers, with different scales and speeds, that vary over time - pacifica_one_layer( pacifica_palette_1, sCIStart1, beatsin16( 3, 11 * 256, 14 * 256), beatsin8( 10, 70, 130), 0-beat16( 301) ); - pacifica_one_layer( pacifica_palette_2, sCIStart2, beatsin16( 4, 6 * 256, 9 * 256), beatsin8( 17, 40, 80), beat16( 401) ); - pacifica_one_layer( pacifica_palette_3, sCIStart3, 6 * 256, beatsin8( 9, 10,38), 0-beat16(503)); - pacifica_one_layer( pacifica_palette_3, sCIStart4, 5 * 256, beatsin8( 8, 10,28), beat16(601)); - - // Add brighter 'whitecaps' where the waves lines up more - pacifica_add_whitecaps(); - - // Deepen the blues and greens a bit - pacifica_deepen_colors(); -} - -// Add one layer of waves into the led array -void pacifica_one_layer( CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) -{ - uint16_t ci = cistart; - uint16_t waveangle = ioff; - uint16_t wavescale_half = (wavescale / 2) + 20; - for( uint16_t i = 0; i < NUM_LEDS; i++) { - waveangle += 250; - uint16_t s16 = sin16( waveangle ) + 32768; - uint16_t cs = scale16( s16 , wavescale_half ) + wavescale_half; - ci += cs; - uint16_t sindex16 = sin16( ci) + 32768; - uint8_t sindex8 = scale16( sindex16, 240); - CRGB c = ColorFromPalette( p, sindex8, bri, LINEARBLEND); - leds[i] += c; - } -} - -// Add extra 'white' to areas where the four layers of light have lined up brightly -void pacifica_add_whitecaps() -{ - uint8_t basethreshold = beatsin8( 9, 55, 65); - uint8_t wave = beat8( 7 ); - - for( uint16_t i = 0; i < NUM_LEDS; i++) { - uint8_t threshold = scale8( sin8( wave), 20) + basethreshold; - wave += 7; - uint8_t l = leds[i].getAverageLight(); - if( l > threshold) { - uint8_t overage = l - threshold; - uint8_t overage2 = qadd8( overage, overage); - leds[i] += CRGB( overage, overage2, qadd8( overage2, overage2)); - } - } -} - -// Deepen the blues and greens -void pacifica_deepen_colors() -{ - for( uint16_t i = 0; i < NUM_LEDS; i++) { - leds[i].blue = scale8( leds[i].blue, 145); - leds[i].green= scale8( leds[i].green, 200); - leds[i] |= CRGB( 2, 5, 7); - } -} diff --git a/FastLED/examples/Pintest/Pintest.ino b/FastLED/examples/Pintest/Pintest.ino deleted file mode 100644 index a8141520a71651d0aa44d75d198f3d5174bdcf3a..0000000000000000000000000000000000000000 --- a/FastLED/examples/Pintest/Pintest.ino +++ /dev/null @@ -1,199 +0,0 @@ - -#include <FastLED.h> - -char fullstrBuffer[64]; - -const char *getPort(void *portPtr) { -// AVR port checks -#ifdef PORTA - if(portPtr == (void*)&PORTA) { return "PORTA"; } -#endif -#ifdef PORTB - if(portPtr == (void*)&PORTB) { return "PORTB"; } -#endif -#ifdef PORTC - if(portPtr == (void*)&PORTC) { return "PORTC"; } -#endif -#ifdef PORTD - if(portPtr == (void*)&PORTD) { return "PORTD"; } -#endif -#ifdef PORTE - if(portPtr == (void*)&PORTE) { return "PORTE"; } -#endif -#ifdef PORTF - if(portPtr == (void*)&PORTF) { return "PORTF"; } -#endif -#ifdef PORTG - if(portPtr == (void*)&PORTG) { return "PORTG"; } -#endif -#ifdef PORTH - if(portPtr == (void*)&PORTH) { return "PORTH"; } -#endif -#ifdef PORTI - if(portPtr == (void*)&PORTI) { return "PORTI"; } -#endif -#ifdef PORTJ - if(portPtr == (void*)&PORTJ) { return "PORTJ"; } -#endif -#ifdef PORTK - if(portPtr == (void*)&PORTK) { return "PORTK"; } -#endif -#ifdef PORTL - if(portPtr == (void*)&PORTL) { return "PORTL"; } -#endif - -// Teensy 3.x port checks -#ifdef GPIO_A_PDOR - if(portPtr == (void*)&GPIO_A_PDOR) { return "GPIO_A_PDOR"; } -#endif -#ifdef GPIO_B_PDOR - if(portPtr == (void*)&GPIO_B_PDOR) { return "GPIO_B_PDOR"; } -#endif -#ifdef GPIO_C_PDOR - if(portPtr == (void*)&GPIO_C_PDOR) { return "GPIO_C_PDOR"; } -#endif -#ifdef GPIO_D_PDOR - if(portPtr == (void*)&GPIO_D_PDOR) { return "GPIO_D_PDOR"; } -#endif -#ifdef GPIO_E_PDOR - if(portPtr == (void*)&GPIO_E_PDOR) { return "GPIO_E_PDOR"; } -#endif -#ifdef REG_PIO_A_ODSR - if(portPtr == (void*)®_PIO_A_ODSR) { return "REG_PIO_A_ODSR"; } -#endif -#ifdef REG_PIO_B_ODSR - if(portPtr == (void*)®_PIO_B_ODSR) { return "REG_PIO_B_ODSR"; } -#endif -#ifdef REG_PIO_C_ODSR - if(portPtr == (void*)®_PIO_C_ODSR) { return "REG_PIO_C_ODSR"; } -#endif -#ifdef REG_PIO_D_ODSR - if(portPtr == (void*)®_PIO_D_ODSR) { return "REG_PIO_D_ODSR"; } -#endif - -// Teensy 4 port checks -#ifdef GPIO1_DR - if(portPtr == (void*)&GPIO1_DR) { return "GPIO1_DR"; } -#endif -#ifdef GPIO2_DR -if(portPtr == (void*)&GPIO2_DR) { return "GPIO21_DR"; } -#endif -#ifdef GPIO3_DR -if(portPtr == (void*)&GPIO3_DR) { return "GPIO3_DR"; } -#endif -#ifdef GPIO4_DR -if(portPtr == (void*)&GPIO4_DR) { return "GPIO4_DR"; } -#endif - String unknown_str = "Unknown: " + String((size_t)portPtr, HEX); - strncpy(fullstrBuffer, unknown_str.c_str(), unknown_str.length()); - fullstrBuffer[sizeof(fullstrBuffer)-1] = '\0'; - return fullstrBuffer; -} - -template<uint8_t PIN> void CheckPin() -{ - CheckPin<PIN - 1>(); - - void *systemThinksPortIs = (void*)portOutputRegister(digitalPinToPort(PIN)); - RwReg systemThinksMaskIs = digitalPinToBitMask(PIN); - - Serial.print("Pin "); Serial.print(PIN); Serial.print(": Port "); - - if(systemThinksPortIs == (void*)FastPin<PIN>::port()) { - Serial.print("valid & mask "); - } else { - Serial.print("invalid, is "); Serial.print(getPort((void*)FastPin<PIN>::port())); Serial.print(" should be "); - Serial.print(getPort((void*)systemThinksPortIs)); - Serial.print(" & mask "); - } - - if(systemThinksMaskIs == FastPin<PIN>::mask()) { - Serial.println("valid."); - } else { - Serial.print("invalid, is "); Serial.print(FastPin<PIN>::mask()); Serial.print(" should be "); Serial.println(systemThinksMaskIs); - } -} - -template<> void CheckPin<255> () {} - - -template<uint8_t _PORT> const char *_GetPinPort(void *ptr) { - if (__FL_PORT_INFO<_PORT>::hasPort() && (ptr == (void*)__FL_PORT_INFO<_PORT>::portAddr())) { - return __FL_PORT_INFO<_PORT>::portName(); - } else { - return _GetPinPort<_PORT - 1>(ptr); - } -} -template<> const char *_GetPinPort<-1>(void *ptr) { - return NULL; -} - -const char *GetPinPort(void *ptr) { - return _GetPinPort<'Z'>(ptr); -} - -static uint8_t pcount = 0; - - -template<uint8_t PIN> void PrintPins() { - PrintPins<PIN - 1>(); - - RwReg *systemThinksPortIs = portOutputRegister(digitalPinToPort(PIN)); - RwReg systemThinksMaskIs = digitalPinToBitMask(PIN); - - int maskBit = 0; - while(systemThinksMaskIs > 1) { systemThinksMaskIs >>= 1; maskBit++; } - - const char *pinport = GetPinPort((void*)systemThinksPortIs); - if (pinport) { - Serial.print("__FL_DEFPIN("); Serial.print(PIN); - Serial.print(","); Serial.print(maskBit); - Serial.print(","); Serial.print(pinport); - Serial.print("); "); - pcount++; - if(pcount == 4) { pcount = 0; Serial.println(""); } - } else { - // Serial.print("Not found for pin "); Serial.println(PIN); - } -} - -template<> void PrintPins<0>() { - RwReg *systemThinksPortIs = portOutputRegister(digitalPinToPort(0)); - RwReg systemThinksMaskIs = digitalPinToBitMask(0); - - int maskBit = 0; - while(systemThinksMaskIs > 1) { systemThinksMaskIs >>= 1; maskBit++; } - - const char *pinport = GetPinPort((void*)systemThinksPortIs); - if (pinport) { - Serial.print("__FL_DEFPIN("); Serial.print(0); - Serial.print(","); Serial.print(maskBit); - Serial.print(","); Serial.print(pinport); - Serial.print("); "); - pcount++; - if(pcount == 4) { pcount = 0; Serial.println(""); } - } -} - -int counter = 0; -void setup() { - delay(5000); - Serial.begin(38400); - Serial.println("resetting!"); -} - -void loop() { - Serial.println(counter); - -#ifdef MAX_PIN - CheckPin<MAX_PIN>(); -#endif - - Serial.println("-----"); -#ifdef NUM_DIGITAL_PINS - PrintPins<NUM_DIGITAL_PINS>(); -#endif - Serial.println("------"); - - delay(100000); -} diff --git a/FastLED/examples/Ports/PJRCSpectrumAnalyzer/PJRCSpectrumAnalyzer.ino b/FastLED/examples/Ports/PJRCSpectrumAnalyzer/PJRCSpectrumAnalyzer.ino deleted file mode 100644 index 24f2394e7059faff6dc05c132f0b2900da5109ce..0000000000000000000000000000000000000000 --- a/FastLED/examples/Ports/PJRCSpectrumAnalyzer/PJRCSpectrumAnalyzer.ino +++ /dev/null @@ -1,136 +0,0 @@ -// LED Audio Spectrum Analyzer Display -// -// Creates an impressive LED light show to music input -// using Teensy 3.1 with the OctoWS2811 adaptor board -// http://www.pjrc.com/store/teensy31.html -// http://www.pjrc.com/store/octo28_adaptor.html -// -// Line Level Audio Input connects to analog pin A3 -// Recommended input circuit: -// http://www.pjrc.com/teensy/gui/?info=AudioInputAnalog -// -// This example code is in the public domain. - -#define USE_OCTOWS2811 -#include <OctoWS2811.h> -#include <FastLED.h> -#include <Audio.h> -#include <Wire.h> -#include <SD.h> -#include <SPI.h> - -// The display size and color to use -const unsigned int matrix_width = 60; -const unsigned int matrix_height = 32; -const unsigned int myColor = 0x400020; - -// These parameters adjust the vertical thresholds -const float maxLevel = 0.5; // 1.0 = max, lower is more "sensitive" -const float dynamicRange = 40.0; // total range to display, in decibels -const float linearBlend = 0.3; // useful range is 0 to 0.7 - -CRGB leds[matrix_width * matrix_height]; - -// Audio library objects -AudioInputAnalog adc1(A3); //xy=99,55 -AudioAnalyzeFFT1024 fft; //xy=265,75 -AudioConnection patchCord1(adc1, fft); - - -// This array holds the volume level (0 to 1.0) for each -// vertical pixel to turn on. Computed in setup() using -// the 3 parameters above. -float thresholdVertical[matrix_height]; - -// This array specifies how many of the FFT frequency bin -// to use for each horizontal pixel. Because humans hear -// in octaves and FFT bins are linear, the low frequencies -// use a small number of bins, higher frequencies use more. -int frequencyBinsHorizontal[matrix_width] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, - 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, - 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, - 15, 16, 17, 18, 19, 20, 22, 23, 24, 25 -}; - - - -// Run setup once -void setup() { - // the audio library needs to be given memory to start working - AudioMemory(12); - - // compute the vertical thresholds before starting - computeVerticalLevels(); - - // turn on the display - FastLED.addLeds<OCTOWS2811>(leds,(matrix_width * matrix_height) / 8); -} - -// A simple xy() function to turn display matrix coordinates -// into the index numbers OctoWS2811 requires. If your LEDs -// are arranged differently, edit this code... -unsigned int xy(unsigned int x, unsigned int y) { - if ((y & 1) == 0) { - // even numbered rows (0, 2, 4...) are left to right - return y * matrix_width + x; - } else { - // odd numbered rows (1, 3, 5...) are right to left - return y * matrix_width + matrix_width - 1 - x; - } -} - -// Run repetitively -void loop() { - unsigned int x, y, freqBin; - float level; - - if (fft.available()) { - // freqBin counts which FFT frequency data has been used, - // starting at low frequency - freqBin = 0; - - for (x=0; x < matrix_width; x++) { - // get the volume for each horizontal pixel position - level = fft.read(freqBin, freqBin + frequencyBinsHorizontal[x] - 1); - - // uncomment to see the spectrum in Arduino's Serial Monitor - // Serial.print(level); - // Serial.print(" "); - - for (y=0; y < matrix_height; y++) { - // for each vertical pixel, check if above the threshold - // and turn the LED on or off - if (level >= thresholdVertical[y]) { - leds[xy(x,y)] = CRGB(myColor); - } else { - leds[xy(x,y)] = CRGB::Black; - } - } - // increment the frequency bin count, so we display - // low to higher frequency from left to right - freqBin = freqBin + frequencyBinsHorizontal[x]; - } - // after all pixels set, show them all at the same instant - FastLED.show(); - // Serial.println(); - } -} - - -// Run once from setup, the compute the vertical levels -void computeVerticalLevels() { - unsigned int y; - float n, logLevel, linearLevel; - - for (y=0; y < matrix_height; y++) { - n = (float)y / (float)(matrix_height - 1); - logLevel = pow10f(n * -1.0 * (dynamicRange / 20.0)); - linearLevel = 1.0 - n; - linearLevel = linearLevel * linearBlend; - logLevel = logLevel * (1.0 - linearBlend); - thresholdVertical[y] = (logLevel + linearLevel) * maxLevel; - } -} diff --git a/FastLED/examples/Pride2015/Pride2015.ino b/FastLED/examples/Pride2015/Pride2015.ino deleted file mode 100644 index 0fbd3a5bcee329198e131ae899a1772c0152eab3..0000000000000000000000000000000000000000 --- a/FastLED/examples/Pride2015/Pride2015.ino +++ /dev/null @@ -1,82 +0,0 @@ -#include "FastLED.h" - -// Pride2015 -// Animated, ever-changing rainbows. -// by Mark Kriegsman - -#if FASTLED_VERSION < 3001000 -#error "Requires FastLED 3.1 or later; check github for latest code." -#endif - -#define DATA_PIN 3 -//#define CLK_PIN 4 -#define LED_TYPE WS2811 -#define COLOR_ORDER GRB -#define NUM_LEDS 200 -#define BRIGHTNESS 255 - -CRGB leds[NUM_LEDS]; - - -void setup() { - delay(3000); // 3 second delay for recovery - - // tell FastLED about the LED strip configuration - FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS) - .setCorrection(TypicalLEDStrip) - .setDither(BRIGHTNESS < 255); - - // set master brightness control - FastLED.setBrightness(BRIGHTNESS); -} - - -void loop() -{ - pride(); - FastLED.show(); -} - - -// This function draws rainbows with an ever-changing, -// widely-varying set of parameters. -void pride() -{ - static uint16_t sPseudotime = 0; - static uint16_t sLastMillis = 0; - static uint16_t sHue16 = 0; - - uint8_t sat8 = beatsin88( 87, 220, 250); - uint8_t brightdepth = beatsin88( 341, 96, 224); - uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256)); - uint8_t msmultiplier = beatsin88(147, 23, 60); - - uint16_t hue16 = sHue16;//gHue * 256; - uint16_t hueinc16 = beatsin88(113, 1, 3000); - - uint16_t ms = millis(); - uint16_t deltams = ms - sLastMillis ; - sLastMillis = ms; - sPseudotime += deltams * msmultiplier; - sHue16 += deltams * beatsin88( 400, 5,9); - uint16_t brightnesstheta16 = sPseudotime; - - for( uint16_t i = 0 ; i < NUM_LEDS; i++) { - hue16 += hueinc16; - uint8_t hue8 = hue16 / 256; - - brightnesstheta16 += brightnessthetainc16; - uint16_t b16 = sin16( brightnesstheta16 ) + 32768; - - uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536; - uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; - bri8 += (255 - brightdepth); - - CRGB newcolor = CHSV( hue8, sat8, bri8); - - uint16_t pixelnumber = i; - pixelnumber = (NUM_LEDS-1) - pixelnumber; - - nblend( leds[pixelnumber], newcolor, 64); - } -} diff --git a/FastLED/examples/RGBCalibrate/RGBCalibrate.ino b/FastLED/examples/RGBCalibrate/RGBCalibrate.ino deleted file mode 100644 index 5ff33805a26c8d8751d674f7dd3c09c7aba33100..0000000000000000000000000000000000000000 --- a/FastLED/examples/RGBCalibrate/RGBCalibrate.ino +++ /dev/null @@ -1,95 +0,0 @@ -#include "FastLED.h" - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// RGB Calibration code -// -// Use this sketch to determine what the RGB ordering for your chipset should be. Steps for setting up to use: - -// * Uncomment the line in setup that corresponds to the LED chipset that you are using. (Note that they -// all explicitly specify the RGB order as RGB) -// * Define DATA_PIN to the pin that data is connected to. -// * (Optional) if using software SPI for chipsets that are SPI based, define CLOCK_PIN to the clock pin -// * Compile/upload/run the sketch - -// You should see six leds on. If the RGB ordering is correct, you should see 1 red led, 2 green -// leds, and 3 blue leds. If you see different colors, the count of each color tells you what the -// position for that color in the rgb orering should be. So, for example, if you see 1 Blue, and 2 -// Red, and 3 Green leds then the rgb ordering should be BRG (Blue, Red, Green). - -// You can then test this ordering by setting the RGB ordering in the addLeds line below to the new ordering -// and it should come out correctly, 1 red, 2 green, and 3 blue. -// -////////////////////////////////////////////////// - -#define NUM_LEDS 7 - -// For led chips like WS2812, which have a data line, ground, and power, you just -// need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, -// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN -// Clock pin only needed for SPI based chipsets when not using hardware SPI -#define DATA_PIN 3 -#define CLOCK_PIN 13 - -CRGB leds[NUM_LEDS]; - -void setup() { - // sanity check delay - allows reprogramming if accidently blowing power w/leds - delay(2000); - - // Uncomment/edit one of the following lines for your leds arrangement. - // ## Clockless types ## - // FastLED.addLeds<SM16703, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1829, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1812, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS1904, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<UCS2903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2852, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<GS1903, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SK6812, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<APA106, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2813, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GE8822, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<LPD1886, DATA_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<LPD1886_8BIT, DATA_PIN, RGB>(leds, NUM_LEDS); - // ## Clocked (SPI) types ## - // FastLED.addLeds<LPD6803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical - // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<WS2803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - // FastLED.addLeds<SK9822, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // BGR ordering is typical - - // FastLED.setBrightness(CRGB(255,255,255)); -} - -void loop() { - leds[0] = CRGB(255,0,0); - leds[1] = CRGB(0,255,0); - leds[2] = CRGB(0,255,0); - leds[3] = CRGB(0,0,255); - leds[4] = CRGB(0,0,255); - leds[5] = CRGB(0,0,255); - leds[6] = CRGB(0,0,0); - FastLED.show(); - delay(1000); -} diff --git a/FastLED/examples/RGBSetDemo/RGBSetDemo.ino b/FastLED/examples/RGBSetDemo/RGBSetDemo.ino deleted file mode 100644 index 455fdccc4d80d595f46a4b409dd9e08b09fb4af1..0000000000000000000000000000000000000000 --- a/FastLED/examples/RGBSetDemo/RGBSetDemo.ino +++ /dev/null @@ -1,22 +0,0 @@ -#include <FastLED.h> -#define NUM_LEDS 40 - -CRGBArray<NUM_LEDS> leds; - -void setup() { FastLED.addLeds<NEOPIXEL,6>(leds, NUM_LEDS); } - -void loop(){ - static uint8_t hue; - for(int i = 0; i < NUM_LEDS/2; i++) { - // fade everything out - leds.fadeToBlackBy(40); - - // let's set an led value - leds[i] = CHSV(hue++,255,255); - - // now, let's first 20 leds to the top 20 leds, - leds(NUM_LEDS/2,NUM_LEDS-1) = leds(NUM_LEDS/2 - 1 ,0); - FastLED.delay(33); - } -} - diff --git a/FastLED/examples/SmartMatrix/SmartMatrix.ino b/FastLED/examples/SmartMatrix/SmartMatrix.ino deleted file mode 100644 index 50bcb811290bb14151245d8393b56f19697b7e96..0000000000000000000000000000000000000000 --- a/FastLED/examples/SmartMatrix/SmartMatrix.ino +++ /dev/null @@ -1,121 +0,0 @@ -#include <SmartMatrix.h> -#include <FastLED.h> - -#define kMatrixWidth 32 -#define kMatrixHeight 32 -const bool kMatrixSerpentineLayout = false; - -#define NUM_LEDS (kMatrixWidth * kMatrixHeight) - -CRGB leds[kMatrixWidth * kMatrixHeight]; - - -uint16_t XY( uint8_t x, uint8_t y) -{ - uint16_t i; - - if( kMatrixSerpentineLayout == false) { - i = (y * kMatrixWidth) + x; - } - - if( kMatrixSerpentineLayout == true) { - if( y & 0x01) { - // Odd rows run backwards - uint8_t reverseX = (kMatrixWidth - 1) - x; - i = (y * kMatrixWidth) + reverseX; - } else { - // Even rows run forwards - i = (y * kMatrixWidth) + x; - } - } - - return i; -} - -// The 32bit version of our coordinates -static uint16_t x; -static uint16_t y; -static uint16_t z; - -// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll -// use the z-axis for "time". speed determines how fast time moves forward. Try -// 1 for a very slow moving effect, or 60 for something that ends up looking like -// water. -// uint16_t speed = 1; // almost looks like a painting, moves very slowly -uint16_t speed = 20; // a nice starting speed, mixes well with a scale of 100 -// uint16_t speed = 33; -// uint16_t speed = 100; // wicked fast! - -// Scale determines how far apart the pixels in our noise matrix are. Try -// changing these values around to see how it affects the motion of the display. The -// higher the value of scale, the more "zoomed out" the noise iwll be. A value -// of 1 will be so zoomed in, you'll mostly see solid colors. - -// uint16_t scale = 1; // mostly just solid colors -// uint16_t scale = 4011; // very zoomed out and shimmery -uint16_t scale = 31; - -// This is the array that we keep our computed noise values in -uint8_t noise[kMatrixWidth][kMatrixHeight]; - -void setup() { - // uncomment the following lines if you want to see FPS count information - // Serial.begin(38400); - // Serial.println("resetting!"); - delay(3000); - LEDS.addLeds<SMART_MATRIX>(leds,NUM_LEDS); - LEDS.setBrightness(96); - - // Initialize our coordinates to some random values - x = random16(); - y = random16(); - z = random16(); - - // Show off smart matrix scrolling text - pSmartMatrix->setScrollMode(wrapForward); - pSmartMatrix->setScrollColor({0xff, 0xff, 0xff}); - pSmartMatrix->setScrollSpeed(15); - pSmartMatrix->setScrollFont(font6x10); - pSmartMatrix->scrollText("Smart Matrix & FastLED", -1); - pSmartMatrix->setScrollOffsetFromEdge(10); -} - -// Fill the x/y array of 8-bit noise values using the inoise8 function. -void fillnoise8() { - for(int i = 0; i < kMatrixWidth; i++) { - int ioffset = scale * i; - for(int j = 0; j < kMatrixHeight; j++) { - int joffset = scale * j; - noise[i][j] = inoise8(x + ioffset,y + joffset,z); - } - } - z += speed; -} - - -void loop() { - static uint8_t circlex = 0; - static uint8_t circley = 0; - - static uint8_t ihue=0; - fillnoise8(); - for(int i = 0; i < kMatrixWidth; i++) { - for(int j = 0; j < kMatrixHeight; j++) { - // We use the value at the (i,j) coordinate in the noise - // array for our brightness, and the flipped value from (j,i) - // for our pixel's hue. - leds[XY(i,j)] = CHSV(noise[j][i],255,noise[i][j]); - - // You can also explore other ways to constrain the hue used, like below - // leds[XY(i,j)] = CHSV(ihue + (noise[j][i]>>2),255,noise[i][j]); - } - } - ihue+=1; - - // N.B. this requires SmartMatrix modified w/triple buffering support - pSmartMatrix->fillCircle(circlex % 32,circley % 32,6,CRGB(CHSV(ihue+128,255,255))); - circlex += random16(2); - circley += random16(2); - LEDS.show(); - // delay(10); -} diff --git a/FastLED/examples/TwinkleFox/TwinkleFox.ino b/FastLED/examples/TwinkleFox/TwinkleFox.ino deleted file mode 100644 index 4821139bd619fd2381478db5e312dae172589513..0000000000000000000000000000000000000000 --- a/FastLED/examples/TwinkleFox/TwinkleFox.ino +++ /dev/null @@ -1,383 +0,0 @@ -#include "FastLED.h" - -#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) -#warning "Requires FastLED 3.1 or later; check github for latest code." -#endif - - -#define NUM_LEDS 100 -#define LED_TYPE WS2811 -#define COLOR_ORDER GRB -#define DATA_PIN 3 -//#define CLK_PIN 4 -#define VOLTS 12 -#define MAX_MA 4000 - -// TwinkleFOX: Twinkling 'holiday' lights that fade in and out. -// Colors are chosen from a palette; a few palettes are provided. -// -// This December 2015 implementation improves on the December 2014 version -// in several ways: -// - smoother fading, compatible with any colors and any palettes -// - easier control of twinkle speed and twinkle density -// - supports an optional 'background color' -// - takes even less RAM: zero RAM overhead per pixel -// - illustrates a couple of interesting techniques (uh oh...) -// -// The idea behind this (new) implementation is that there's one -// basic, repeating pattern that each pixel follows like a waveform: -// The brightness rises from 0..255 and then falls back down to 0. -// The brightness at any given point in time can be determined as -// as a function of time, for example: -// brightness = sine( time ); // a sine wave of brightness over time -// -// So the way this implementation works is that every pixel follows -// the exact same wave function over time. In this particular case, -// I chose a sawtooth triangle wave (triwave8) rather than a sine wave, -// but the idea is the same: brightness = triwave8( time ). -// -// Of course, if all the pixels used the exact same wave form, and -// if they all used the exact same 'clock' for their 'time base', all -// the pixels would brighten and dim at once -- which does not look -// like twinkling at all. -// -// So to achieve random-looking twinkling, each pixel is given a -// slightly different 'clock' signal. Some of the clocks run faster, -// some run slower, and each 'clock' also has a random offset from zero. -// The net result is that the 'clocks' for all the pixels are always out -// of sync from each other, producing a nice random distribution -// of twinkles. -// -// The 'clock speed adjustment' and 'time offset' for each pixel -// are generated randomly. One (normal) approach to implementing that -// would be to randomly generate the clock parameters for each pixel -// at startup, and store them in some arrays. However, that consumes -// a great deal of precious RAM, and it turns out to be totally -// unnessary! If the random number generate is 'seeded' with the -// same starting value every time, it will generate the same sequence -// of values every time. So the clock adjustment parameters for each -// pixel are 'stored' in a pseudo-random number generator! The PRNG -// is reset, and then the first numbers out of it are the clock -// adjustment parameters for the first pixel, the second numbers out -// of it are the parameters for the second pixel, and so on. -// In this way, we can 'store' a stable sequence of thousands of -// random clock adjustment parameters in literally two bytes of RAM. -// -// There's a little bit of fixed-point math involved in applying the -// clock speed adjustments, which are expressed in eighths. Each pixel's -// clock speed ranges from 8/8ths of the system clock (i.e. 1x) to -// 23/8ths of the system clock (i.e. nearly 3x). -// -// On a basic Arduino Uno or Leonardo, this code can twinkle 300+ pixels -// smoothly at over 50 updates per seond. -// -// -Mark Kriegsman, December 2015 - -CRGBArray<NUM_LEDS> leds; - -// Overall twinkle speed. -// 0 (VERY slow) to 8 (VERY fast). -// 4, 5, and 6 are recommended, default is 4. -#define TWINKLE_SPEED 4 - -// Overall twinkle density. -// 0 (NONE lit) to 8 (ALL lit at once). -// Default is 5. -#define TWINKLE_DENSITY 5 - -// How often to change color palettes. -#define SECONDS_PER_PALETTE 30 -// Also: toward the bottom of the file is an array -// called "ActivePaletteList" which controls which color -// palettes are used; you can add or remove color palettes -// from there freely. - -// Background color for 'unlit' pixels -// Can be set to CRGB::Black if desired. -CRGB gBackgroundColor = CRGB::Black; -// Example of dim incandescent fairy light background color -// CRGB gBackgroundColor = CRGB(CRGB::FairyLight).nscale8_video(16); - -// If AUTO_SELECT_BACKGROUND_COLOR is set to 1, -// then for any palette where the first two entries -// are the same, a dimmed version of that color will -// automatically be used as the background color. -#define AUTO_SELECT_BACKGROUND_COLOR 0 - -// If COOL_LIKE_INCANDESCENT is set to 1, colors will -// fade out slighted 'reddened', similar to how -// incandescent bulbs change color as they get dim down. -#define COOL_LIKE_INCANDESCENT 1 - - -CRGBPalette16 gCurrentPalette; -CRGBPalette16 gTargetPalette; - -void setup() { - delay( 3000 ); //safety startup delay - FastLED.setMaxPowerInVoltsAndMilliamps( VOLTS, MAX_MA); - FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS) - .setCorrection(TypicalLEDStrip); - - chooseNextColorPalette(gTargetPalette); -} - - -void loop() -{ - EVERY_N_SECONDS( SECONDS_PER_PALETTE ) { - chooseNextColorPalette( gTargetPalette ); - } - - EVERY_N_MILLISECONDS( 10 ) { - nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 12); - } - - drawTwinkles( leds); - - FastLED.show(); -} - - -// This function loops over each pixel, calculates the -// adjusted 'clock' that this pixel should use, and calls -// "CalculateOneTwinkle" on each pixel. It then displays -// either the twinkle color of the background color, -// whichever is brighter. -void drawTwinkles( CRGBSet& L) -{ - // "PRNG16" is the pseudorandom number generator - // It MUST be reset to the same starting value each time - // this function is called, so that the sequence of 'random' - // numbers that it generates is (paradoxically) stable. - uint16_t PRNG16 = 11337; - - uint32_t clock32 = millis(); - - // Set up the background color, "bg". - // if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of - // the current palette are identical, then a deeply faded version of - // that color is used for the background color - CRGB bg; - if( (AUTO_SELECT_BACKGROUND_COLOR == 1) && - (gCurrentPalette[0] == gCurrentPalette[1] )) { - bg = gCurrentPalette[0]; - uint8_t bglight = bg.getAverageLight(); - if( bglight > 64) { - bg.nscale8_video( 16); // very bright, so scale to 1/16th - } else if( bglight > 16) { - bg.nscale8_video( 64); // not that bright, so scale to 1/4th - } else { - bg.nscale8_video( 86); // dim, scale to 1/3rd. - } - } else { - bg = gBackgroundColor; // just use the explicitly defined background color - } - - uint8_t backgroundBrightness = bg.getAverageLight(); - - for( CRGB& pixel: L) { - PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number - uint16_t myclockoffset16= PRNG16; // use that number as clock offset - PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number - // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths) - uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF)>>4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08; - uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16; - uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel - - // We now have the adjusted 'clock' for this pixel, now we call - // the function that computes what color the pixel should be based - // on the "brightness = f( time )" idea. - CRGB c = computeOneTwinkle( myclock30, myunique8); - - uint8_t cbright = c.getAverageLight(); - int16_t deltabright = cbright - backgroundBrightness; - if( deltabright >= 32 || (!bg)) { - // If the new pixel is significantly brighter than the background color, - // use the new color. - pixel = c; - } else if( deltabright > 0 ) { - // If the new pixel is just slightly brighter than the background color, - // mix a blend of the new color and the background color - pixel = blend( bg, c, deltabright * 8); - } else { - // if the new pixel is not at all brighter than the background color, - // just use the background color. - pixel = bg; - } - } -} - - -// This function takes a time in pseudo-milliseconds, -// figures out brightness = f( time ), and also hue = f( time ) -// The 'low digits' of the millisecond time are used as -// input to the brightness wave function. -// The 'high digits' are used to select a color, so that the color -// does not change over the course of the fade-in, fade-out -// of one cycle of the brightness wave function. -// The 'high digits' are also used to determine whether this pixel -// should light at all during this cycle, based on the TWINKLE_DENSITY. -CRGB computeOneTwinkle( uint32_t ms, uint8_t salt) -{ - uint16_t ticks = ms >> (8-TWINKLE_SPEED); - uint8_t fastcycle8 = ticks; - uint16_t slowcycle16 = (ticks >> 8) + salt; - slowcycle16 += sin8( slowcycle16); - slowcycle16 = (slowcycle16 * 2053) + 1384; - uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8); - - uint8_t bright = 0; - if( ((slowcycle8 & 0x0E)/2) < TWINKLE_DENSITY) { - bright = attackDecayWave8( fastcycle8); - } - - uint8_t hue = slowcycle8 - salt; - CRGB c; - if( bright > 0) { - c = ColorFromPalette( gCurrentPalette, hue, bright, NOBLEND); - if( COOL_LIKE_INCANDESCENT == 1 ) { - coolLikeIncandescent( c, fastcycle8); - } - } else { - c = CRGB::Black; - } - return c; -} - - -// This function is like 'triwave8', which produces a -// symmetrical up-and-down triangle sawtooth waveform, except that this -// function produces a triangle wave with a faster attack and a slower decay: -// -// / \ -// / \ -// / \ -// / \ -// - -uint8_t attackDecayWave8( uint8_t i) -{ - if( i < 86) { - return i * 3; - } else { - i -= 86; - return 255 - (i + (i/2)); - } -} - -// This function takes a pixel, and if its in the 'fading down' -// part of the cycle, it adjusts the color a little bit like the -// way that incandescent bulbs fade toward 'red' as they dim. -void coolLikeIncandescent( CRGB& c, uint8_t phase) -{ - if( phase < 128) return; - - uint8_t cooling = (phase - 128) >> 4; - c.g = qsub8( c.g, cooling); - c.b = qsub8( c.b, cooling * 2); -} - -// A mostly red palette with green accents and white trim. -// "CRGB::Gray" is used as white to keep the brightness more uniform. -const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM = -{ CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, - CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, - CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, - CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green }; - -// A mostly (dark) green palette with red berries. -#define Holly_Green 0x00580c -#define Holly_Red 0xB00402 -const TProgmemRGBPalette16 Holly_p FL_PROGMEM = -{ Holly_Green, Holly_Green, Holly_Green, Holly_Green, - Holly_Green, Holly_Green, Holly_Green, Holly_Green, - Holly_Green, Holly_Green, Holly_Green, Holly_Green, - Holly_Green, Holly_Green, Holly_Green, Holly_Red -}; - -// A red and white striped palette -// "CRGB::Gray" is used as white to keep the brightness more uniform. -const TProgmemRGBPalette16 RedWhite_p FL_PROGMEM = -{ CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, - CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray, - CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, - CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray }; - -// A mostly blue palette with white accents. -// "CRGB::Gray" is used as white to keep the brightness more uniform. -const TProgmemRGBPalette16 BlueWhite_p FL_PROGMEM = -{ CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, - CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, - CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, - CRGB::Blue, CRGB::Gray, CRGB::Gray, CRGB::Gray }; - -// A pure "fairy light" palette with some brightness variations -#define HALFFAIRY ((CRGB::FairyLight & 0xFEFEFE) / 2) -#define QUARTERFAIRY ((CRGB::FairyLight & 0xFCFCFC) / 4) -const TProgmemRGBPalette16 FairyLight_p FL_PROGMEM = -{ CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, - HALFFAIRY, HALFFAIRY, CRGB::FairyLight, CRGB::FairyLight, - QUARTERFAIRY, QUARTERFAIRY, CRGB::FairyLight, CRGB::FairyLight, - CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight }; - -// A palette of soft snowflakes with the occasional bright one -const TProgmemRGBPalette16 Snow_p FL_PROGMEM = -{ 0x304048, 0x304048, 0x304048, 0x304048, - 0x304048, 0x304048, 0x304048, 0x304048, - 0x304048, 0x304048, 0x304048, 0x304048, - 0x304048, 0x304048, 0x304048, 0xE0F0FF }; - -// A palette reminiscent of large 'old-school' C9-size tree lights -// in the five classic colors: red, orange, green, blue, and white. -#define C9_Red 0xB80400 -#define C9_Orange 0x902C02 -#define C9_Green 0x046002 -#define C9_Blue 0x070758 -#define C9_White 0x606820 -const TProgmemRGBPalette16 RetroC9_p FL_PROGMEM = -{ C9_Red, C9_Orange, C9_Red, C9_Orange, - C9_Orange, C9_Red, C9_Orange, C9_Red, - C9_Green, C9_Green, C9_Green, C9_Green, - C9_Blue, C9_Blue, C9_Blue, - C9_White -}; - -// A cold, icy pale blue palette -#define Ice_Blue1 0x0C1040 -#define Ice_Blue2 0x182080 -#define Ice_Blue3 0x5080C0 -const TProgmemRGBPalette16 Ice_p FL_PROGMEM = -{ - Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, - Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, - Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, - Ice_Blue2, Ice_Blue2, Ice_Blue2, Ice_Blue3 -}; - - -// Add or remove palette names from this list to control which color -// palettes are used, and in what order. -const TProgmemRGBPalette16* ActivePaletteList[] = { - &RetroC9_p, - &BlueWhite_p, - &RainbowColors_p, - &FairyLight_p, - &RedGreenWhite_p, - &PartyColors_p, - &RedWhite_p, - &Snow_p, - &Holly_p, - &Ice_p -}; - - -// Advance to the next color palette in the list (above). -void chooseNextColorPalette( CRGBPalette16& pal) -{ - const uint8_t numberOfPalettes = sizeof(ActivePaletteList) / sizeof(ActivePaletteList[0]); - static uint8_t whichPalette = -1; - whichPalette = addmod8( whichPalette, 1, numberOfPalettes); - - pal = *(ActivePaletteList[whichPalette]); -} diff --git a/FastLED/examples/XYMatrix/XYMatrix.ino b/FastLED/examples/XYMatrix/XYMatrix.ino deleted file mode 100644 index 010ffe7cf1a0d3081557af21f6224720a9b2be1d..0000000000000000000000000000000000000000 --- a/FastLED/examples/XYMatrix/XYMatrix.ino +++ /dev/null @@ -1,209 +0,0 @@ -#include <FastLED.h> - -#define LED_PIN 3 - -#define COLOR_ORDER GRB -#define CHIPSET WS2811 - -#define BRIGHTNESS 64 - -// Helper functions for an two-dimensional XY matrix of pixels. -// Simple 2-D demo code is included as well. -// -// XY(x,y) takes x and y coordinates and returns an LED index number, -// for use like this: leds[ XY(x,y) ] == CRGB::Red; -// No error checking is performed on the ranges of x and y. -// -// XYsafe(x,y) takes x and y coordinates and returns an LED index number, -// for use like this: leds[ XY(x,y) ] == CRGB::Red; -// Error checking IS performed on the ranges of x and y, and an -// index of "-1" is returned. Special instructions below -// explain how to use this without having to do your own error -// checking every time you use this function. -// This is a slightly more advanced technique, and -// it REQUIRES SPECIAL ADDITIONAL setup, described below. - - -// Params for width and height -const uint8_t kMatrixWidth = 16; -const uint8_t kMatrixHeight = 16; - -// Param for different pixel layouts -const bool kMatrixSerpentineLayout = true; -const bool kMatrixVertical = false; -// Set 'kMatrixSerpentineLayout' to false if your pixels are -// laid out all running the same way, like this: -// -// 0 > 1 > 2 > 3 > 4 -// | -// .----<----<----<----' -// | -// 5 > 6 > 7 > 8 > 9 -// | -// .----<----<----<----' -// | -// 10 > 11 > 12 > 13 > 14 -// | -// .----<----<----<----' -// | -// 15 > 16 > 17 > 18 > 19 -// -// Set 'kMatrixSerpentineLayout' to true if your pixels are -// laid out back-and-forth, like this: -// -// 0 > 1 > 2 > 3 > 4 -// | -// | -// 9 < 8 < 7 < 6 < 5 -// | -// | -// 10 > 11 > 12 > 13 > 14 -// | -// | -// 19 < 18 < 17 < 16 < 15 -// -// Bonus vocabulary word: anything that goes one way -// in one row, and then backwards in the next row, and so on -// is call "boustrophedon", meaning "as the ox plows." - - -// This function will return the right 'led index number' for -// a given set of X and Y coordinates on your matrix. -// IT DOES NOT CHECK THE COORDINATE BOUNDARIES. -// That's up to you. Don't pass it bogus values. -// -// Use the "XY" function like this: -// -// for( uint8_t x = 0; x < kMatrixWidth; x++) { -// for( uint8_t y = 0; y < kMatrixHeight; y++) { -// -// // Here's the x, y to 'led index' in action: -// leds[ XY( x, y) ] = CHSV( random8(), 255, 255); -// -// } -// } -// -// -uint16_t XY( uint8_t x, uint8_t y) -{ - uint16_t i; - - if( kMatrixSerpentineLayout == false) { - if (kMatrixVertical == false) { - i = (y * kMatrixWidth) + x; - } else { - i = kMatrixHeight * (kMatrixWidth - (x+1))+y; - } - } - - if( kMatrixSerpentineLayout == true) { - if (kMatrixVertical == false) { - if( y & 0x01) { - // Odd rows run backwards - uint8_t reverseX = (kMatrixWidth - 1) - x; - i = (y * kMatrixWidth) + reverseX; - } else { - // Even rows run forwards - i = (y * kMatrixWidth) + x; - } - } else { // vertical positioning - if ( x & 0x01) { - i = kMatrixHeight * (kMatrixWidth - (x+1))+y; - } else { - i = kMatrixHeight * (kMatrixWidth - x) - (y+1); - } - } - } - - return i; -} - - -// Once you've gotten the basics working (AND NOT UNTIL THEN!) -// here's a helpful technique that can be tricky to set up, but -// then helps you avoid the needs for sprinkling array-bound-checking -// throughout your code. -// -// It requires a careful attention to get it set up correctly, but -// can potentially make your code smaller and faster. -// -// Suppose you have an 8 x 5 matrix of 40 LEDs. Normally, you'd -// delcare your leds array like this: -// CRGB leds[40]; -// But instead of that, declare an LED buffer with one extra pixel in -// it, "leds_plus_safety_pixel". Then declare "leds" as a pointer to -// that array, but starting with the 2nd element (id=1) of that array: -// CRGB leds_with_safety_pixel[41]; -// CRGB* const leds( leds_plus_safety_pixel + 1); -// Then you use the "leds" array as you normally would. -// Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]", -// AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0]. -// leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel". -// -// Now instead of using the XY function above, use the one below, "XYsafe". -// -// If the X and Y values are 'in bounds', this function will return an index -// into the visible led array, same as "XY" does. -// HOWEVER -- and this is the trick -- if the X or Y values -// are out of bounds, this function will return an index of -1. -// And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0], -// it's a totally safe and legal place to access. And since the 'safety pixel' -// falls 'outside' the visible part of the LED array, anything you write -// there is hidden from view automatically. -// Thus, this line of code is totally safe, regardless of the actual size of -// your matrix: -// leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255); -// -// The only catch here is that while this makes it safe to read from and -// write to 'any pixel', there's really only ONE 'safety pixel'. No matter -// what out-of-bounds coordinates you write to, you'll really be writing to -// that one safety pixel. And if you try to READ from the safety pixel, -// you'll read whatever was written there last, reglardless of what coordinates -// were supplied. - -#define NUM_LEDS (kMatrixWidth * kMatrixHeight) -CRGB leds_plus_safety_pixel[ NUM_LEDS + 1]; -CRGB* const leds( leds_plus_safety_pixel + 1); - -uint16_t XYsafe( uint8_t x, uint8_t y) -{ - if( x >= kMatrixWidth) return -1; - if( y >= kMatrixHeight) return -1; - return XY(x,y); -} - - -// Demo that USES "XY" follows code below - -void loop() -{ - uint32_t ms = millis(); - int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth)); - int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight)); - DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768); - if( ms < 5000 ) { - FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000)); - } else { - FastLED.setBrightness(BRIGHTNESS); - } - FastLED.show(); -} - -void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8) -{ - byte lineStartHue = startHue8; - for( byte y = 0; y < kMatrixHeight; y++) { - lineStartHue += yHueDelta8; - byte pixelHue = lineStartHue; - for( byte x = 0; x < kMatrixWidth; x++) { - pixelHue += xHueDelta8; - leds[ XY(x, y)] = CHSV( pixelHue, 255, 255); - } - } -} - - -void setup() { - FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050); - FastLED.setBrightness( BRIGHTNESS ); -} diff --git a/FastLED/extras/AppleII.s65 b/FastLED/extras/AppleII.s65 deleted file mode 100644 index 98e4e4b182decae868a6f8c8c972ea72645ade9a..0000000000000000000000000000000000000000 --- a/FastLED/extras/AppleII.s65 +++ /dev/null @@ -1,40 +0,0 @@ -KBD = $C000 ;Read keydown -KBDSTRB = $C010 ;Reset keybd - -SPKR = $C030 ;Toggle speaker - -; TTL digital output pins on -; 16-pin DIP game connector -SETAN0 = $C058 -CLRAN0 = $C059 -SETAN1 = $C05A -CLRAN1 = $C05B -SETAN2 = $C05C -CLRAN2 = $C05D -SETAN3 = $C05E -CLRAN3 = $C05F - -PIN12ON = CLRAN3 -PIN12OFF= SETAN3 -PIN13ON = CLRAN2 -PIN13OFF= SETAN2 -PIN14ON = CLRAN1 -PIN14OFF= SETAN1 -PIN15ON = CLRAN0 -PIN15OFF= SETAN0 - -;Special for pin 5, except on //gs -C040STROBE = $C040 -PIN5STROBE = C040STROBE - -SolidApple = $C062 ; read SW1 or SA -OpenApple = $C061 ; read SW0 or OA - -VBL = $C019 ; vertical blanking - -WAIT = $FCA8 ; wait a little while - -CROUT = $FD8E ; print a CR -PRBYTE = $FDDA ; print a hex byte - - diff --git a/FastLED/extras/FastLED6502.s65 b/FastLED/extras/FastLED6502.s65 deleted file mode 100644 index 3d1a4fe68fe6bb12ff79e2a5a70adbb86dc51357..0000000000000000000000000000000000000000 --- a/FastLED/extras/FastLED6502.s65 +++ /dev/null @@ -1,633 +0,0 @@ -///////////////////////////////// -// -// FastLED6502 -// by Mark Kriegsman -// -// Device driver and animation -// library for connecting addressable -// LED strips to an Apple II. -// The full "FastLED" library is -// available for Arduino and related -// microcontrollers. -// -///////////////////////////////// -// -// HOST COMPATIBILITY: -// Apples with 16-pin DIP "game ports" -// are fully supported; Apples with only -// 9-pin "game ports" are NOT supported. -// -// Apple ][ fully supported -// Apple ][+ fully supported -// Apple //e fully supported -// -// Apple //c and //c+ NOT supported -// as they lack the required 16-pin -// DIP game port for digital I/O. -// -// Apple //gs: -// motherboard game port IS supported -// back panel connector NOT supported -// See Notes section below. -// -// C64, PET, VIC-20, Atari400/800, -// NES, SYM, KIM-1, and other 6502 -// systems are NOT supported at this -// time, but porting should be -// relatively easy for someone familiar -// with each target platform. -// -// -// LED STRIP COMPATIBILITY: -// In general, "four-wire" (clocked) -// LED strips can be supported, but -// "three-wire" (clockless) LED strips -// cannot be supported. -// -// APA102 tested & working -// Adafruit DotStar tested & working -// LPD8806 should work (untested) -// WS2801 should work (untested) -// -// WS2811/WS2812/NeoPixel can NOT work -// due to timing incompatibilities, -// namely that the 1MHz Apple is far -// too slow to drive them correctly. -// -// -// USAGE - HARDWARE: -// Connect an external power source to -// +5 and GND on the LED strip. -// Connect GND on the LED strip to GND -// on the game port connector (pin 8) -// Connect DATA IN on the LED strip to -// pin 12, 13, or 14 on the game port. -// Connect CLOCK IN on the LED strip to -// pin 5 (preferred), 12, 13, or 14 on -// the game port. Note: Apple //gs users -// cannot use pin 5. -// -// -// USAGE - SOFTWARE: -// At build time provide definitions for -// CHIPSET, DATA_PIN, CLOCK_PIN, -// NUM_LEDS, & BRIGHTNESS. -// Inside "Setup": -// Store LED count into -// FastLED_NumPixels, -// Store brightness into -// FastLED_Brightness -// Inside "Loop": -// Update the leds array, found in -// ledsR, ledsG, and ledsB -// Call FastLED_Show -// Jump back to top of "Loop" -// -// -// REFERENCE: -// FastLED_Show: -// display led array on LED strip -// FastLED_FillBlack: -// fill led array to black -// FastLED_FillSolid_RGB_AXY: -// fill led array with RGB color -// FastLED_FillSolid_Hue_X: -// fill led array with solid HSV Hue -// FastLED_Random8: -// return a pseudorandom number in A -// FastLED_FillRainbow_XY: -// fill led array with HSV rainbow -// starting at hue X, incrementing by -// huedelta Y each pixel. -// FastLED_SetHue_XY: -// set pixel Y to HSV hue X -// FastLED_Beat8: -// takes a speed increment in A, and -// returns a triangle wave in A. -// -// -// NOTES: -// For speed and size, there IS some -// self-modifying code in this -// library, so it cannot be burned -// into ROM without modification. -// Brightness control only works on -// APA102 at this point. -// Pin 15 is currently used as a -// 'frame start' signal for protocol -// diagnostics - makes frames more -// visible with an oscilloscope. -// If Pin 5 is specified for the CLOCK -// output pin, FastLED6502 will -// automatically use the high speed -// C040STROBE signal for clock. Note -// that the Apple //gs lacks this -// signal, even on the motherboard -// game port. -// The Apple joystick/mouse port on the -// rear of the //c, //c+, and //gs -// can NOT be used for LED connections -// because it lacks the necessary -// digital output pins. -// This library can drive 100 LED pixels -// at more than 30 frames per second. -// -// -// VERSION HISTORY -// 2015-02-07 - first version, by MEK -// assembled with xa65 -// www.floodgap.com/retrotech/xa/ - - -///////////////////////////////// -// -// ENTRY POINT -// - -FastLED_Entry - jsr FastLED_FillBlack - jmp Setup - - -///////////////////////////////// -// -// FASTLED6502 GLOBALS -// - -FastLED_NumPixels .byt NUM_LEDS -FastLED_Brightness .byt BRIGHTNESS - -FastLED_RandomState .byt 17 -FastLED_BeatState .byt 0 - - -///////////////////////////////// -// -// API FUNCTIONS -// - -FastLED_FillBlack - lda FastLED_NumPixels - pha - lda #255 - sta FastLED_NumPixels - lda #0 - tax - tay - jsr FastLED_FillSolid_RGB_AXY - jsr FastLED_Show - pla - sta FastLED_NumPixels - rts - - -FastLED_FillRainbow_XY - sty rbHueDelta - ldy #0 -FR1 - lda FastLED_RainbowR,x - sta ledsR,y - lda FastLED_RainbowG,x - sta ledsG,y - lda FastLED_RainbowB,x - sta ledsB,y - - txa - clc - adc rbHueDelta - tax - - iny - cpy FastLED_NumPixels - bne FR1 - rts - -rbHueDelta .byt 0 - - -FastLED_SetHue_XY - lda FastLED_RainbowR,x - sta ledsR,y - lda FastLED_RainbowG,x - sta ledsG,y - lda FastLED_RainbowB,x - sta ledsB,y - rts - - -FastLED_FillSolid_RGB_AXY - sta ledsR - stx ledsG - sty ledsB - ldy #0 -FillSolidRGBAXY1 - lda ledsR - sta ledsR,y - lda ledsG - sta ledsG,y - lda ledsB - sta ledsB,y - iny - cpy FastLED_NumPixels - bne FillSolidRGBAXY1 - rts - -FastLED_FillSolid_Hue_X - ldy #0 -FillSolidHX1 - lda FastLED_RainbowR,x - sta ledsR,y - lda FastLED_RainbowG,x - sta ledsG,y - lda FastLED_RainbowB,x - sta ledsB,y - iny - cpy FastLED_NumPixels - bne FillSolidHX1 - rts - - -; NOTE: USES SELF-MODIFYING CODE -FastLED_Random8 - inc Random8GetLo - bne Random8Get - inc Random8GetHi - bne Random8Get - lda #$F8 - sta Random8GetHi - lda #03 - sta Random8GetLo -Random8Get -Random8GetLo = Random8Get + 1 -Random8GetHi = Random8Get + 2 - lda $F803 - adc FastLED_RandomState - sta FastLED_RandomState - rts - - -FastLED_Beat8 - clc - adc FastLED_BeatState - sta FastLED_BeatState - bit FastLED_BeatState - bmi FastLED_Beat8Neg - asl - rts -FastLED_Beat8Neg - lda #$ff - sec - sbc FastLED_BeatState - sbc FastLED_BeatState - rts - - -FastLED_Show - jmp CHIPSET - - -///////////////////////////////// -// -// HARDWARE INTERFACING -// - -PINOFF_BASE = PIN15OFF -PINON_BASE = PIN15ON - -#define PINON(P) PINON_BASE+((15-P)*2) -#define PINOFF(P) PINOFF_BASE+((15-P)*2) - -DATAOFF = PINOFF(DATA_PIN) -DATAON = PINON(DATA_PIN) -CLKOFF = PINOFF(CLOCK_PIN) -CLKON = PINON(CLOCK_PIN) - -// Special handling if CLOCK_PIN -// is 5: the C040STROBE line. -#if CLOCK_PIN = 5 -#define CLOCK_ON bit PIN5STROBE -#define CLOCK_OFF -#else -#define CLOCK_ON bit CLKON -#define CLOCK_OFF bit CLKOFF -#endif - -FRAMEON = PINON(15) -FRAMEOFF = PINOFF(15) - -///////////////////////////////// -APA102 - bit FRAMEON - jsr FastLED_Send00 - jsr FastLED_Send00 - jsr FastLED_Send00 - jsr FastLED_Send00 - - lda FastLED_Brightness - lsr - lsr - lsr - ora #$E0 - tax - - ldy FastLED_NumPixels -APA102PX - txa - jsr FastLED_SendA - lda ledsB,y - jsr FastLED_SendA - lda ledsG,y - jsr FastLED_SendA - lda ledsR,y - jsr FastLED_SendA - dey - bne APA102PX - - lda FastLED_NumPixels - lsr - lsr - lsr - lsr - lsr - lsr - tay - iny -APA102CL - jsr FastLED_SendFF - jsr FastLED_Send00 - jsr FastLED_Send00 - jsr FastLED_Send00 - dey - bne APA102CL - bit FRAMEOFF - rts - -///////////////////////////////// -LPD8806 - bit FRAMEON - ldy FastLED_NumPixels -LPD8806PX - lda ledsG,y - lsr - ora #$80 - jsr FastLED_SendA - lda ledsR,y - lsr - ora #$80 - jsr FastLED_SendA - lda ledsB,y - lsr - ora #$80 - jsr FastLED_SendA - dey - bne LPD8806PX - - bit FRAMEOFF - rts - - -///////////////////////////////// -WS2801 - bit FRAMEON - ldy FastLED_NumPixels -WS2801PX - lda ledsG,y - jsr FastLED_SendA - lda ledsR,y - jsr FastLED_SendA - lda ledsB,y - jsr FastLED_SendA - dey - bne WS2801PX - - bit FRAMEOFF - rts - - -///////////////////////////////// -FastLED_SendFF - bit DATAON - jmp FastLED_SendXX - ; -FastLED_Send00 - bit DATAOFF - ; -FastLED_SendXX - CLOCK_ON - CLOCK_OFF - CLOCK_ON - CLOCK_OFF - - CLOCK_ON - CLOCK_OFF - CLOCK_ON - CLOCK_OFF - - CLOCK_ON - CLOCK_OFF - CLOCK_ON - CLOCK_OFF - - CLOCK_ON - CLOCK_OFF - CLOCK_ON - CLOCK_OFF - - rts - -FastLED_SendA - cmp #0 - beq FastLED_Send00 - cmp #$FF - beq FastLED_SendFF - - asl - bcc S0x0 -S0x1 bit DATAON - bcs S0xK -S0x0 bit DATAOFF -S0xK CLOCK_ON - CLOCK_OFF - - asl - bcc S1x0 -S1x1 bit DATAON - bcs S1xK -S1x0 bit DATAOFF -S1xK CLOCK_ON - CLOCK_OFF - - asl - bcc S2x0 -S2x1 bit DATAON - bcs S2xK -S2x0 bit DATAOFF -S2xK CLOCK_ON - CLOCK_OFF - - asl - bcc S3x0 -S3x1 bit DATAON - bcs S3xK -S3x0 bit DATAOFF -S3xK CLOCK_ON - CLOCK_OFF - - asl - bcc S4x0 -S4x1 bit DATAON - bcs S4xK -S4x0 bit DATAOFF -S4xK CLOCK_ON - CLOCK_OFF - - asl - bcc S5x0 -S5x1 bit DATAON - bcs S5xK -S5x0 bit DATAOFF -S5xK CLOCK_ON - CLOCK_OFF - - asl - bcc S6x0 -S6x1 bit DATAON - bcs S6xK -S6x0 bit DATAOFF -S6xK CLOCK_ON - CLOCK_OFF - - asl - bcc S7x0 -S7x1 bit DATAON - bcs S7xK -S7x0 bit DATAOFF -S7xK CLOCK_ON - CLOCK_OFF - - rts - - -///////////////////////////////// -// -// Force page allignment for speed -// for leds array and Rainbow table -// - .dsb 256-(* & $FF),0 - - -///////////////////////////////// -// -// LED ARRAY -// - -ledsR .dsb 256,0 -ledsG .dsb 256,0 -ledsB .dsb 256,0 - -///////////////////////////////// -// -// HSV RAINBOW DEFINITION -// -// Generated directly from FastLED. -// - -FastLED_RainbowR - .byt $FF,$FD,$FA,$F8,$F5,$F2,$F0,$ED - .byt $EA,$E8,$E5,$E2,$E0,$DD,$DA,$D8 - .byt $D5,$D2,$D0,$CD,$CA,$C8,$C5,$C2 - .byt $C0,$BD,$BA,$B8,$B5,$B2,$B0,$AD - .byt $AB,$AB,$AB,$AB,$AB,$AB,$AB,$AB - .byt $AB,$AB,$AB,$AB,$AB,$AB,$AB,$AB - .byt $AB,$AB,$AB,$AB,$AB,$AB,$AB,$AB - .byt $AB,$AB,$AB,$AB,$AB,$AB,$AB,$AB - .byt $AB,$A6,$A1,$9C,$96,$91,$8C,$86 - .byt $81,$7C,$76,$71,$6C,$66,$61,$5C - .byt $56,$51,$4C,$47,$41,$3C,$37,$31 - .byt $2C,$27,$21,$1C,$17,$11,$0C,$07 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$02,$05,$07,$0A,$0D,$0F,$12 - .byt $15,$17,$1A,$1D,$1F,$22,$25,$27 - .byt $2A,$2D,$2F,$32,$35,$37,$3A,$3D - .byt $3F,$42,$45,$47,$4A,$4D,$4F,$52 - .byt $55,$57,$5A,$5C,$5F,$62,$64,$67 - .byt $6A,$6C,$6F,$72,$74,$77,$7A,$7C - .byt $7F,$82,$84,$87,$8A,$8C,$8F,$92 - .byt $94,$97,$9A,$9C,$9F,$A2,$A4,$A7 - .byt $AB,$AD,$B0,$B2,$B5,$B8,$BA,$BD - .byt $C0,$C2,$C5,$C8,$CA,$CD,$D0,$D2 - .byt $D5,$D8,$DA,$DD,$E0,$E2,$E5,$E8 - .byt $EA,$ED,$F0,$F2,$F5,$F8,$FA,$FD -FastLED_RainbowG - .byt $00,$02,$05,$07,$0A,$0D,$0F,$12 - .byt $15,$17,$1A,$1D,$1F,$22,$25,$27 - .byt $2A,$2D,$2F,$32,$35,$37,$3A,$3D - .byt $3F,$42,$45,$47,$4A,$4D,$4F,$52 - .byt $55,$57,$5A,$5C,$5F,$62,$64,$67 - .byt $6A,$6C,$6F,$72,$74,$77,$7A,$7C - .byt $7F,$82,$84,$87,$8A,$8C,$8F,$92 - .byt $94,$97,$9A,$9C,$9F,$A2,$A4,$A7 - .byt $AB,$AD,$B0,$B2,$B5,$B8,$BA,$BD - .byt $C0,$C2,$C5,$C8,$CA,$CD,$D0,$D2 - .byt $D5,$D8,$DA,$DD,$E0,$E2,$E5,$E8 - .byt $EA,$ED,$F0,$F2,$F5,$F8,$FA,$FD - .byt $FF,$FD,$FA,$F8,$F5,$F2,$F0,$ED - .byt $EA,$E8,$E5,$E2,$E0,$DD,$DA,$D8 - .byt $D5,$D2,$D0,$CD,$CA,$C8,$C5,$C2 - .byt $C0,$BD,$BA,$B8,$B5,$B2,$B0,$AD - .byt $AB,$A6,$A1,$9C,$96,$91,$8C,$86 - .byt $81,$7C,$76,$71,$6C,$66,$61,$5C - .byt $56,$51,$4C,$47,$41,$3C,$37,$31 - .byt $2C,$27,$21,$1C,$17,$11,$0C,$07 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 -FastLED_RainbowB - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$00,$00,$00,$00,$00,$00,$00 - .byt $00,$02,$05,$07,$0A,$0D,$0F,$12 - .byt $15,$17,$1A,$1D,$1F,$22,$25,$27 - .byt $2A,$2D,$2F,$32,$35,$37,$3A,$3D - .byt $3F,$42,$45,$47,$4A,$4D,$4F,$52 - .byt $55,$5A,$5F,$64,$6A,$6F,$74,$7A - .byt $7F,$84,$8A,$8F,$94,$9A,$9F,$A4 - .byt $AA,$AF,$B4,$B9,$BF,$C4,$C9,$CF - .byt $D4,$D9,$DF,$E4,$E9,$EF,$F4,$F9 - .byt $FF,$FD,$FA,$F8,$F5,$F2,$F0,$ED - .byt $EA,$E8,$E5,$E2,$E0,$DD,$DA,$D8 - .byt $D5,$D2,$D0,$CD,$CA,$C8,$C5,$C2 - .byt $C0,$BD,$BA,$B8,$B5,$B2,$B0,$AD - .byt $AB,$A9,$A6,$A4,$A1,$9E,$9C,$99 - .byt $96,$94,$91,$8E,$8C,$89,$86,$84 - .byt $81,$7E,$7C,$79,$76,$74,$71,$6E - .byt $6C,$69,$66,$64,$61,$5E,$5C,$59 - .byt $55,$53,$50,$4E,$4B,$48,$46,$43 - .byt $40,$3E,$3B,$38,$36,$33,$30,$2E - .byt $2B,$28,$26,$23,$20,$1E,$1B,$18 - .byt $16,$13,$10,$0E,$0B,$08,$06,$03 diff --git a/FastLED/extras/RainbowDemo.bin.zip b/FastLED/extras/RainbowDemo.bin.zip deleted file mode 100644 index 853c38e2500acc4ac2fea295af8f98f3e4de6c38..0000000000000000000000000000000000000000 Binary files a/FastLED/extras/RainbowDemo.bin.zip and /dev/null differ diff --git a/FastLED/extras/RainbowDemo.s65 b/FastLED/extras/RainbowDemo.s65 deleted file mode 100644 index 2de6233ba0a5f6f9aa02f8b84f1bb4ffca9f99af..0000000000000000000000000000000000000000 --- a/FastLED/extras/RainbowDemo.s65 +++ /dev/null @@ -1,89 +0,0 @@ -; "Rainbow with glitter" demo -; for "FastLED6502" -; -; Runs on an Apple ][, ][+, //e, or //gs -; -; Supports APA102, Adafruit DotStar, -; LPD8806, and WS2801 LED strips. -; -; LED strip connects to game port pins, -; see FastLED6502.s65 for details. -; -; Mark Kriegsman, February 2015 - -#define NUM_LEDS 100 -#define BRIGHTNESS 64 -#define CHIPSET APA102 -#define DATA_PIN 14 -#define CLOCK_PIN 5 - - * = $6000 - -#include "FastLED6502.s65" -#include "AppleII.s65" - -gHue .byt 0 -gHueDelta .byt 17 -gHueSpeed .byt 7 - - -Setup - lda #0 - sta gHue - -Loop - lda gHue - clc - adc gHueSpeed - sta gHue - ldx gHue - ldy gHueDelta -; Fill RGB array with HSV rainbow - jsr FastLED_FillRainbow_XY -; Use master brightness control - lda #BRIGHTNESS - sta FastLED_Brightness -CheckOpenApple - bit OpenApple - bpl CheckSolidApple -; Add glitter if requested - jsr AddGlitter -CheckSolidApple - bit SolidApple - bpl DoDisplay -; Pulse brightness if requested - jsr PulseBrightness -DoDisplay -; This is where the magic happens - jsr FastLED_Show - jmp Loop - - -AddGlitter - ldy #3 -MaybeAdd1Glitter - jsr FastLED_Random8 - cmp FastLED_NumPixels - bcs SkipThis1Glitter - tax - lda #$FF - sta ledsR,x - sta ledsG,x - sta ledsB,x -SkipThis1Glitter - dey - bne MaybeAdd1Glitter - rts - - -PulseBrightness - lda #13 - jsr FastLED_Beat8 - clc - adc #12 - bcc PulseBright1 - lda #$FF -PulseBright1 - sta FastLED_Brightness - rts - \ No newline at end of file diff --git a/FastLED/keywords.txt b/FastLED/keywords.txt deleted file mode 100644 index 75df500ca05dfb49ef8cb807bb374a89f61315c0..0000000000000000000000000000000000000000 --- a/FastLED/keywords.txt +++ /dev/null @@ -1,395 +0,0 @@ -####################################### -# Syntax Coloring Map For FastLED -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -CFastLED KEYWORD1 -CHSV KEYWORD1 -CRGB KEYWORD1 -CRGBArray KEYWORD1 -LEDS KEYWORD1 -FastLED KEYWORD1 -FastPin KEYWORD1 -FastSPI KEYWORD1 -FastSPI_LED2 KEYWORD1 - -CRGBPalette16 KEYWORD1 -CRGBPalette256 KEYWORD1 -CHSVPalette16 KEYWORD1 -CHSVPalette256 KEYWORD1 -CHSVPalette16 KEYWORD1 -CHSVPalette256 KEYWORD1 -CRGBPalette16 KEYWORD1 -CRGBPalette256 KEYWORD1 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -# FastLED methods -addLeds KEYWORD2 -setBrightness KEYWORD2 -getBrightness KEYWORD2 -show KEYWORD2 -clear KEYWORD2 -clearData KEYWORD2 -showColor KEYWORD2 -setTemperature KEYWORD2 -setCorrection KEYWORD2 -setDither KEYWORD2 -setMaxPowerInMilliWatts KEYWORD2 -setMaxPowerInVoltsAndMilliamps KEYWORD2 -setMaxRefreshRate KEYWORD2 -countFPS KEYWORD2 -getFPS KEYWORD2 - -# Noise methods -inoise16_raw KEYWORD2 -inoise8_raw KEYWORD2 -inoise16 KEYWORD2 -inoise8 KEYWORD2 -fill_2dnoise16 KEYWORD2 -fill_2dnoise8 KEYWORD2 -fill_noise16 KEYWORD2 -fill_noise8 KEYWORD2 -fill_raw_2dnoise16 KEYWORD2 -fill_raw_2dnoise16into8 KEYWORD2 -fill_raw_2dnoise8 KEYWORD2 -fill_raw_noise16into8 KEYWORD2 -fill_raw_noise8 KEYWORD2 - -# Lib8tion methods -qadd8 KEYWORD2 -qadd7 KEYWORD2 -qsub8 KEYWORD2 -add8 KEYWORD2 -sub8 KEYWORD2 -scale8 KEYWORD2 -scale8_video KEYWORD2 -cleanup_R1 KEYWORD2 -nscale8x3 KEYWORD2 -nscale8x3_video KEYWORD2 -nscale8x2 KEYWORD2 -nscale8x2_video KEYWORD2 -scale16by8 KEYWORD2 -scale16by8 KEYWORD2 -scale16 KEYWORD2 -mul8 KEYWORD2 -qmul8 KEYWORD2 -abs8 KEYWORD2 -dim8_raw KEYWORD2 -dim8_video KEYWORD2 -dim8_lin KEYWORD2 -brighten8_raw KEYWORD2 -brighten8_video KEYWORD2 -brighten8_lin KEYWORD2 -random8 KEYWORD2 -random16 KEYWORD2 -random8 KEYWORD2 -random8 KEYWORD2 -random16 KEYWORD2 -random16 KEYWORD2 -random16_set_seed KEYWORD2 -random16_get_seed KEYWORD2 -random16_add_entropy KEYWORD2 -sin16_avr KEYWORD2 -sin16 KEYWORD2 -cos16 KEYWORD2 -sin8 KEYWORD2 -cos8 KEYWORD2 -lerp8by8 KEYWORD2 -lerp16by16 KEYWORD2 -lerp16by8 KEYWORD2 -lerp15by8 KEYWORD2 -lerp15by16 KEYWORD2 -map8 KEYWORD2 -ease8InOutQuad KEYWORD2 -ease8InOutCubic KEYWORD2 -ease8InOutApprox KEYWORD2 -ease8InOutApprox KEYWORD2 -triwave8 KEYWORD2 -quadwave8 KEYWORD2 -cubicwave8 KEYWORD2 -sqrt16 KEYWORD2 -blend8 KEYWORD2 - -# Color util methods -blend KEYWORD2 -nblend KEYWORD2 -ColorFromPalette KEYWORD2 -HeatColor KEYWORD2 -UpscalePalette KEYWORD2 -blend KEYWORD2 -fadeLightBy KEYWORD2 -fadeToBlackBy KEYWORD2 -fade_raw KEYWORD2 -fade_video KEYWORD2 -fill_gradient KEYWORD2 -fill_gradient_RGB KEYWORD2 -fill_palette KEYWORD2 -fill_rainbow KEYWORD2 -fill_solid KEYWORD2 -map_data_into_colors_through_palette KEYWORD2 -nblend KEYWORD2 -nscale8 KEYWORD2 -nscale8_video KEYWORD2 - -# HSV methods -hsv2grb_rainbow KEYWORD2 -hsv2rgb_spectrum KEYWORD2 -hsv2rgb_raw KEYWORD2 -fill_solid KEYWORD2 -fill_rainbow KEYWORD2 - -# Colors -CRGB::AliceBlue KEYWORD2 -CRGB::Amethyst KEYWORD2 -CRGB::AntiqueWhite KEYWORD2 -CRGB::Aqua KEYWORD2 -CRGB::Aquamarine KEYWORD2 -CRGB::Azure KEYWORD2 -CRGB::Beige KEYWORD2 -CRGB::Bisque KEYWORD2 -CRGB::Black KEYWORD2 -CRGB::BlanchedAlmond KEYWORD2 -CRGB::Blue KEYWORD2 -CRGB::BlueViolet KEYWORD2 -CRGB::Brown KEYWORD2 -CRGB::BurlyWood KEYWORD2 -CRGB::CadetBlue KEYWORD2 -CRGB::Chartreuse KEYWORD2 -CRGB::Chocolate KEYWORD2 -CRGB::Coral KEYWORD2 -CRGB::CornflowerBlue KEYWORD2 -CRGB::Cornsilk KEYWORD2 -CRGB::Crimson KEYWORD2 -CRGB::Cyan KEYWORD2 -CRGB::DarkBlue KEYWORD2 -CRGB::DarkCyan KEYWORD2 -CRGB::DarkGoldenrod KEYWORD2 -CRGB::DarkGray KEYWORD2 -CRGB::DarkGreen KEYWORD2 -CRGB::DarkKhaki KEYWORD2 -CRGB::DarkMagenta KEYWORD2 -CRGB::DarkOliveGreen KEYWORD2 -CRGB::DarkOrange KEYWORD2 -CRGB::DarkOrchid KEYWORD2 -CRGB::DarkRed KEYWORD2 -CRGB::DarkSalmon KEYWORD2 -CRGB::DarkSeaGreen KEYWORD2 -CRGB::DarkSlateBlue KEYWORD2 -CRGB::DarkSlateGray KEYWORD2 -CRGB::DarkTurquoise KEYWORD2 -CRGB::DarkViolet KEYWORD2 -CRGB::DeepPink KEYWORD2 -CRGB::DeepSkyBlue KEYWORD2 -CRGB::DimGray KEYWORD2 -CRGB::DodgerBlue KEYWORD2 -CRGB::FireBrick KEYWORD2 -CRGB::FloralWhite KEYWORD2 -CRGB::ForestGreen KEYWORD2 -CRGB::Fuchsia KEYWORD2 -CRGB::Gainsboro KEYWORD2 -CRGB::GhostWhite KEYWORD2 -CRGB::Gold KEYWORD2 -CRGB::Goldenrod KEYWORD2 -CRGB::Gray KEYWORD2 -CRGB::Green KEYWORD2 -CRGB::GreenYellow KEYWORD2 -CRGB::Honeydew KEYWORD2 -CRGB::HotPink KEYWORD2 -CRGB::IndianRed KEYWORD2 -CRGB::Indigo KEYWORD2 -CRGB::Ivory KEYWORD2 -CRGB::Khaki KEYWORD2 -CRGB::Lavender KEYWORD2 -CRGB::LavenderBlush KEYWORD2 -CRGB::LawnGreen KEYWORD2 -CRGB::LemonChiffon KEYWORD2 -CRGB::LightBlue KEYWORD2 -CRGB::LightCoral KEYWORD2 -CRGB::LightCyan KEYWORD2 -CRGB::LightGoldenrodYellow KEYWORD2 -CRGB::LightGreen KEYWORD2 -CRGB::LightGrey KEYWORD2 -CRGB::LightPink KEYWORD2 -CRGB::LightSalmon KEYWORD2 -CRGB::LightSeaGreen KEYWORD2 -CRGB::LightSkyBlue KEYWORD2 -CRGB::LightSlateGray KEYWORD2 -CRGB::LightSteelBlue KEYWORD2 -CRGB::LightYellow KEYWORD2 -CRGB::Lime KEYWORD2 -CRGB::LimeGreen KEYWORD2 -CRGB::Linen KEYWORD2 -CRGB::Magenta KEYWORD2 -CRGB::Maroon KEYWORD2 -CRGB::MediumAquamarine KEYWORD2 -CRGB::MediumBlue KEYWORD2 -CRGB::MediumOrchid KEYWORD2 -CRGB::MediumPurple KEYWORD2 -CRGB::MediumSeaGreen KEYWORD2 -CRGB::MediumSlateBlue KEYWORD2 -CRGB::MediumSpringGreen KEYWORD2 -CRGB::MediumTurquoise KEYWORD2 -CRGB::MediumVioletRed KEYWORD2 -CRGB::MidnightBlue KEYWORD2 -CRGB::MintCream KEYWORD2 -CRGB::MistyRose KEYWORD2 -CRGB::Moccasin KEYWORD2 -CRGB::NavajoWhite KEYWORD2 -CRGB::Navy KEYWORD2 -CRGB::OldLace KEYWORD2 -CRGB::Olive KEYWORD2 -CRGB::OliveDrab KEYWORD2 -CRGB::Orange KEYWORD2 -CRGB::OrangeRed KEYWORD2 -CRGB::Orchid KEYWORD2 -CRGB::PaleGoldenrod KEYWORD2 -CRGB::PaleGreen KEYWORD2 -CRGB::PaleTurquoise KEYWORD2 -CRGB::PaleVioletRed KEYWORD2 -CRGB::PapayaWhip KEYWORD2 -CRGB::PeachPuff KEYWORD2 -CRGB::Peru KEYWORD2 -CRGB::Pink KEYWORD2 -CRGB::Plaid KEYWORD2 -CRGB::Plum KEYWORD2 -CRGB::PowderBlue KEYWORD2 -CRGB::Purple KEYWORD2 -CRGB::Red KEYWORD2 -CRGB::RosyBrown KEYWORD2 -CRGB::RoyalBlue KEYWORD2 -CRGB::SaddleBrown KEYWORD2 -CRGB::Salmon KEYWORD2 -CRGB::SandyBrown KEYWORD2 -CRGB::SeaGreen KEYWORD2 -CRGB::Seashell KEYWORD2 -CRGB::Sienna KEYWORD2 -CRGB::Silver KEYWORD2 -CRGB::SkyBlue KEYWORD2 -CRGB::SlateBlue KEYWORD2 -CRGB::SlateGray KEYWORD2 -CRGB::Snow KEYWORD2 -CRGB::SpringGreen KEYWORD2 -CRGB::SteelBlue KEYWORD2 -CRGB::Tan KEYWORD2 -CRGB::Teal KEYWORD2 -CRGB::Thistle KEYWORD2 -CRGB::Tomato KEYWORD2 -CRGB::Turquoise KEYWORD2 -CRGB::Violet KEYWORD2 -CRGB::Wheat KEYWORD2 -CRGB::White KEYWORD2 -CRGB::WhiteSmoke KEYWORD2 -CRGB::Yellow KEYWORD2 -CRGB::YellowGreen KEYWORD2 - - -####################################### -# Constants (LITERAL1) -####################################### - -# Chipsets -APA102 LITERAL1 -APA104 LITERAL1 -APA106 LITERAL1 -DMXSERIAL LITERAL1 -DMXSIMPLE LITERAL1 -DOTSTAR LITERAL1 -GE8822 LITERAL1 -GS1903 LITERAL1 -GW6205 LITERAL1 -GW6205B LITERAL1 -GW6205_400 LITERAL1 -LPD1886 LITERAL1 -LPD1886_8BIT LITERAL1 -LPD6803 LITERAL1 -LPD8806 LITERAL1 -NEOPIXEL LITERAL1 -OCTOWS2811 LITERAL1 -OCTOWS2811_400 LITERAL1 -OCTOWS2813 LITERAL1 -P9813 LITERAL1 -PIXIE LITERAL1 -PL9823 LITERAL1 -SK6812 LITERAL1 -SK6822 LITERAL1 -SK9822 LITERAL1 -SM16703 LITERAL1 -SM16716 LITERAL1 -SMART_MATRIX LITERAL1 -TM1803 LITERAL1 -TM1804 LITERAL1 -TM1809 LITERAL1 -TM1812 LITERAL1 -TM1829 LITERAL1 -UCS1903 LITERAL1 -UCS1903B LITERAL1 -UCS1904 LITERAL1 -UCS2903 LITERAL1 -WS2801 LITERAL1 -WS2803 LITERAL1 -WS2811 LITERAL1 -WS2811_400 LITERAL1 -WS2812 LITERAL1 -WS2812B LITERAL1 -WS2812SERIAL LITERAL1 -WS2813 LITERAL1 -WS2852 LITERAL1 - -# RGB orderings -RGB LITERAL1 -RBG LITERAL1 -GRB LITERAL1 -GBR LITERAL1 -BRG LITERAL1 -BGR LITERAL1 - -# hue literals -HUE_RED LITERAL1 -HUE_ORANGE LITERAL1 -HUE_YELLOW LITERAL1 -HUE_GREEN LITERAL1 -HUE_AQUA LITERAL1 -HUE_BLUE LITERAL1 -HUE_PURPLE LITERAL1 -HUE_PINK LITERAL1 - -# Color correction values -TypicalSMD5050 LITERAL1 -TypicalLEDStrip LITERAL1 -Typical8mmPixel LITERAL1 -TypicalPixelString LITERAL1 -UncorrectedColor LITERAL1 -Candle LITERAL1 -Tungsten40W LITERAL1 -Tungsten100W LITERAL1 -Halogen LITERAL1 -CarbonArc LITERAL1 -HighNoonSun LITERAL1 -DirectSunlight LITERAL1 -OvercastSky LITERAL1 -ClearBlueSky LITERAL1 -WarmFluorescent LITERAL1 -StandardFluorescent LITERAL1 -CoolWhiteFluorescent LITERAL1 -FullSpectrumFluorescent LITERAL1 -GrowLightFluorescent LITERAL1 -BlackLightFluorescent LITERAL1 -MercuryVapor LITERAL1 -SodiumVapor LITERAL1 -MetalHalide LITERAL1 -HighPressureSodium LITERAL1 -UncorrectedTemperature LITERAL1 - -# Color util literals -FORWARD_HUES LITERAL1 -BACKWARD_HUES LITERAL1 -SHORTEST_HUES LITERAL1 -LONGEST_HUES LITERAL1 -LINEARBLEND LITERAL1 -NOBLEND LITERAL1 diff --git a/FastLED/library.json b/FastLED/library.json deleted file mode 100644 index 9e3302040fa35a465f681f90d5187c51883827ca..0000000000000000000000000000000000000000 --- a/FastLED/library.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "FastLED", - "description": "FastLED is a library for programming addressable rgb led strips (APA102/Dotstar, WS2812/Neopixel, LPD8806, and a dozen others) acting both as a driver and as a library for color management and fast math.", - "keywords": "led,noise,rgb,math,fast", - "authors": [ - { - "name": "Daniel Garcia", - "url": "https://github.com/focalintent", - "maintainer": true - }, - { - "name": "Mark Kriegsman", - "url": "https://github.com/kriegsman", - "maintainer": true - }, - { - "name": "Sam Guyer", - "url": "https://github.com/samguyer", - "maintainer": true - }, - { - "name": "Jason Coon", - "url": "https://github.com/jasoncoon", - "maintainer": true - }, - { - "name": "Josh Huber", - "url": "https://github.com/uberjay", - "maintainer": true - } - ], - "repository": { - "type": "git", - "url": "https://github.com/FastLED/FastLED.git" - }, - "version": "3.4.0", - "license": "MIT", - "homepage": "http://fastled.io", - "frameworks": "arduino", - "platforms": "atmelavr, atmelsam, freescalekinetis, nordicnrf51, nxplpc, ststm32, teensy, espressif8266, espressif32, nordicnrf52", - "export": { - "exclude": [ - "docs", - "extras" - ] - }, - "build": { - "srcFilter": [ - "+<*.c>", - "+<*.cpp>", - "+<*.h>", - "+<platforms/esp/32/*.cpp>" - ], - "libArchive": false - } -} diff --git a/FastLED/library.properties b/FastLED/library.properties deleted file mode 100644 index fc8d17b1fa9011ac9b5ddcd5a7a023bcc828571f..0000000000000000000000000000000000000000 --- a/FastLED/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=FastLED -version=3.4.0 -author=Daniel Garcia -maintainer=Daniel Garcia <dgarcia@fastled.io> -sentence=Multi-platform library for controlling dozens of different types of LEDs along with optimized math, effect, and noise functions. -paragraph=Multi-platform library for controlling dozens of different types of LEDs along with optimized math, effect, and noise functions. -category=Display -url=https://github.com/FastLED/FastLED -architectures=* -includes=FastLED.h diff --git a/FastLED/release_notes.md b/FastLED/release_notes.md deleted file mode 100644 index e7eb77920ffe9b66e5ea8a933586ede5abdf767c..0000000000000000000000000000000000000000 --- a/FastLED/release_notes.md +++ /dev/null @@ -1,282 +0,0 @@ -FastLED 3.4.0 -============= - -* Improved reliability on ESP32 when wifi is active -* Merged in contributed support for Adafruit boards: QT Py SAMD21, Circuit Playground Express, Circuit Playground Bluefruit, and ItsyBitsy nRF52840 Express -* Merged in contributed support for SparkFun Artemis boards -* Merged in contributed support for Arduino Nano Every / Arduino Uno Wifi Rev. 2 -* Merged in contributed support for Seeedstudio Odyssey and XIAO boards -* Merged in contributed support for AVR chips ATmega1284, ATmega4809, and LGT8F328 -* XYMatrix example now supports 90-degree rotated orientation -* Moved source code files into "src" subdirectory -* Many small code cleanups and bug fixes -* Released December 2020, with many thanks to everyone contributing to FastLED! - - -FastLED 3.3.3 -============= - -* Improved support for ESP32, Teensy4, ATmega16, nRF52, and ARM STM32. -* Added animation examples: "TwinkleFox" holiday lights, "Pride2015" moving rainbows, and "Pacifica" gentle ocean waves -* Fixed a few bugs including a rare divide-by-zero crash -* Cleaned up code and examples a bit -* Said our sad farwells to FastLED founder Daniel Garcia, who we lost in a tragic accident on September 2nd, 2019. Dan's beautiful code and warm kindness have been at the heart of the library, and our community, for ten years. FastLED will continue with help from all across the FastLED world, and Dan's spirit will be with us whenever the lights shine and glow. Thank you, Dan, for everything. - - -FastLED 3.3.2 -============= - -* Fix APA102 compile error #870 -* Normalize pin definition macros so that we can have an .ino file that can be used to output what pin/port mappings should be for a platform -* Add defnition for ATmega32 - -FastLED 3.3.1 -============= - -* Fix teensy build issue -* Bring in sam's RMT timing fix - -FastLED 3.3.0 -============== -* Preliminary Teensy 4 support -* Fix #861 - power computation for OctoWS2811 -* keywords and other minor changes for compilers (#854, #845) -* Fix some nrf52 issues (#856), #840 - -FastLED 3.2.10 -============== -* Adafruit Metro M4 Airlift support -* Arduino Nano 33 IOT preliminary definitions -* Bug fixes - -FastLED 3.2.9 -============= -* Update ItsyBitsy support -* Remove conflicting types courtesy of an esp8266 framework update -* Fixes to clockless M0 code to allow for more interrupt enabled environments -* ATTiny25 compilation fix -* Some STM32 fixes (the platform still seems unhappy, though) -* NRF52 support -* Updated ESP32 support - supporting up to 24-way parallel output - - - -FastLED 3.2.6 -============= - -* typo fix - -FastLED 3.2.5 -============= - -* Fix for SAMD51 based boards (a SAMD21 optimization broke the D51 builds, now D51 is a separate platform) - -FastLED 3.2.4 -============= - -* fix builds for WAV boards - -FastLED 3.2.2 -============= - -* Perf tweak for SAMD21 -* LPD6803 support -* Add atmega328pb support -* Variety of minor bug/correctness/typo fixes -* Added SM16703, GE8822, GS1903 - -FastLED 3.2.1 -============= -* ATmega644P support -* Adafruit Hallowwing (Thanks to Lady Ada) -* Improved STM 32 support -* Some user contributed cleanups -* ESP32 APA102 output fix - -FastLED3.2 -========== -* ESP32 support with improved output and parallel output options (thanks Sam Guyer!) -* various minor contributed fixes - -FastLED 3.1.8 -============= -* Added support for Adafruit Circuit Playground Express (Thanks to Lady Ada) -* Improved support for Adafruit Gemma and Trinket m0 (Thanks to Lady Ada) -* Added support for PJRC's WS2812Serial (Thanks to Paul Stoffregen) -* Added support for ATmega328 non-picopower hardware pins (Thanks to John Whittington) -* Fixes for ESP32 support (Thanks to Daniel Tullemans) -* 'Makefile' compilation fix (Thanks to Nico Hood) - -FastLED 3.1.7 (skipped) -======================= - -FastLED 3.1.6 -============= -* Preliminary support for esp32 -* Variety of random bug fixes -* 6-channel parallel output for the esp8266 -* Race condition fixes for teensy hardware SPI -* Preliminary teensy 3.6 support -* Various fixes falling out from "fixing" scale 8 adjustments -* Add gemma m0 support (thanks @ladyada!) - -FastLED 3.1.5 -============= -* Fix due parallel output build issue - -FastLED 3.1.4 -============= -* fix digispark avr build issue - -FastLED3.1.3 -=============== - -* Add SK6822 timings -* Add ESP8266 support - note, only tested w/the arduino esp8266 build environment -* Improvements to hsv2rgb, palette, and noise performance -* Improvements to rgb2hsv accuracy -* Fixed noise discontinuity -* Add wino board support -* Fix scale8 (so now, scale8(255,255) == 255, not 254!) -* Add ESP8266 parallel output support - - -FastLED3.1.1 -============ -* Enabled RFDuino/nrf51822 hardware SPI support -* Fix edge case bug w/HSV palette blending -* Fix power management issue w/parallel output -* Use static_asserts for some more useful compile time errors around bad pins -* Roll power management into FastLED.show/delay directly -* Support for adafruit pixies on arduino type platforms that have SoftwareSerial - * TODO: support hardware serial on platforms that have it available -* Add UCS2903 timings -* Preliminary CPixelView/CRGBSet code - more flexible treatment of groups of arrays - * https://github.com/FastLED/FastLED/wiki/RGBSet-Reference - - -FastLED3.1.0 -============ -* Added support for the following platforms - * Arduino Zero - * Teensy LC - * RFDuino/nrf51822 - * Spark Core -* Major internal code reoganization -* Started doxygen based documentation -* Lots of bug/performance fixes -* Parallel output on various arm platforms -* lots of new stuff - -FastLED3.0.2 -============ -* possibly fix issues #67 and #90 by fixing gcc 4.8.x support - -FastLED3.0.1 -============ -* fix issue #89 w/power management pin always being on - -FastLED3.0 -========== - -* Added support for the following platforms: - * Arduino due - * Teensy 3.1 -* Added the following LED chipsets: - * USC1903_400 - * GW6205 / GW6205_400 - * APA102 - * APA104 - * LPD1886 - * P9813 - * SmartMatrix -* Added multiple examples: - * ColorPalette - show off the color palette code - * ColorTemperature - show off the color correction code - * Fire2012 - * Fire2012WithPalette - * Multiple led controller examples - * Noise - * NoisePlayground - * NoisePlusPalette - * SmartMatrix - show off SmartMatrix support - * XYMatrix - show how to use a mtrix layout of leds -* Added color correction -* Added dithering -* Added power management support -* Added support for color palettes -* Added easing functions -* Added fast trig functions -* Added simplex noise functions -* Added color utility functions -* Fixed DMXSERIAL/DMXSIMPLE support -* Timing adjustments for existing SPI chipsets -* Cleaned up the code layout to make platform support easier -* Many bug fixes -* A number of performance/memory improvements -* Remove Squant (takes up space!) - -FastLED2 -======== - -## Full release of the library - -## Release Candidate 6 -* Rename library, offically, to FastLED, move to github -* Update keywords with all the new stuffs - -## Release Candidate 5 -* Gemma and Trinket: supported except for global "setBrightness" - -## Release Candidate 4 -* Added NEOPIXEL as a synonym for WS2811 -* Fix WS2811/WS2812B timings, bring it in line to exactly 1.25ns/bit. -* Fix handling of constant color definitions (damn you, gcc!) - -## Release Candidate 3 -* Fixed bug when Clock and Data were on the same port -* Added ability to set pixel color directly from HSV -* Added ability to retrieve current random16 seed - -## Release Candidate 2 -* mostly bug fixes -* Fix SPI macro definitions for latest teensy3 software update -* Teensy 2 compilation fix -* hsv2rgb_rainbow performance fix - -## Release Candidate 1 -* New unified/simplified API for adding/using controllers -* fleshout clockless chip support -* add hsv (spectrum and rainbow style colors) -* high speed memory management operations -* library for interpolation/easing functions -* various api changes, addition of clear and showColor functions -* scale value applied to all show methods -* bug fixes for SM16716 -* performance improvements, lpd8806 exceeds 22Mbit now -* hardware def fixes -* allow alternate rgb color orderings -* high speed math methods -* rich CRGB structure - -## Preview 3 -* True hardware SPI support for teensy (up to 20Mbit output!) -* Minor bug fixes/tweaks - -## Preview 2 -* Rename pin class to FastPin -* Replace latch with select, more accurate description of what it does -* Enforce intra-frame timing for ws2801s -* SM16716 support -* Add #define FAST_SPI_INTERRUPTS_WRITE_PINS to make sure world is ok w/interrupts and SPI -* Add #define FASTLED_FORCE_SOFTWARE_SPI for those times when you absolutely don't want to use hardware SPI, ev -en if you're using the hardware SPI pins -* Add pin definitions for the arduino megas - should fix ws2811 support -* Add pin definitions for the leonardo - should fix spi support and pin mappings -* Add warnings when pin definitions are missing -* Added google+ community for fastspi users - https://plus.google.com/communities/109127054924227823508 -# Add pin definitions for Teensy++ 2.0 - - -## Preview 1 -* Initial release diff --git a/FastLED/src/FastLED.cpp b/FastLED/src/FastLED.cpp deleted file mode 100644 index 255dcfa3e048ec547a7a07baf0a07b3bcac63b9d..0000000000000000000000000000000000000000 --- a/FastLED/src/FastLED.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#define FASTLED_INTERNAL -#include "FastLED.h" - - -#if defined(__SAM3X8E__) -volatile uint32_t fuckit; -#endif - -FASTLED_NAMESPACE_BEGIN - -void *pSmartMatrix = NULL; - -CFastLED FastLED; - -CLEDController *CLEDController::m_pHead = NULL; -CLEDController *CLEDController::m_pTail = NULL; -static uint32_t lastshow = 0; - -uint32_t _frame_cnt=0; -uint32_t _retry_cnt=0; - -// uint32_t CRGB::Squant = ((uint32_t)((__TIME__[4]-'0') * 28))<<16 | ((__TIME__[6]-'0')*50)<<8 | ((__TIME__[7]-'0')*28); - -CFastLED::CFastLED() { - // clear out the array of led controllers - // m_nControllers = 0; - m_Scale = 255; - m_nFPS = 0; - m_pPowerFunc = NULL; - m_nPowerData = 0xFFFFFFFF; -} - -CLEDController &CFastLED::addLeds(CLEDController *pLed, - struct CRGB *data, - int nLedsOrOffset, int nLedsIfOffset) { - int nOffset = (nLedsIfOffset > 0) ? nLedsOrOffset : 0; - int nLeds = (nLedsIfOffset > 0) ? nLedsIfOffset : nLedsOrOffset; - - pLed->init(); - pLed->setLeds(data + nOffset, nLeds); - FastLED.setMaxRefreshRate(pLed->getMaxRefreshRate(),true); - return *pLed; -} - -void CFastLED::show(uint8_t scale) { - // guard against showing too rapidly - while(m_nMinMicros && ((micros()-lastshow) < m_nMinMicros)); - lastshow = micros(); - - // If we have a function for computing power, use it! - if(m_pPowerFunc) { - scale = (*m_pPowerFunc)(scale, m_nPowerData); - } - - CLEDController *pCur = CLEDController::head(); - while(pCur) { - uint8_t d = pCur->getDither(); - if(m_nFPS < 100) { pCur->setDither(0); } - pCur->showLeds(scale); - pCur->setDither(d); - pCur = pCur->next(); - } - countFPS(); -} - -int CFastLED::count() { - int x = 0; - CLEDController *pCur = CLEDController::head(); - while( pCur) { - ++x; - pCur = pCur->next(); - } - return x; -} - -CLEDController & CFastLED::operator[](int x) { - CLEDController *pCur = CLEDController::head(); - while(x-- && pCur) { - pCur = pCur->next(); - } - if(pCur == NULL) { - return *(CLEDController::head()); - } else { - return *pCur; - } -} - -void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { - while(m_nMinMicros && ((micros()-lastshow) < m_nMinMicros)); - lastshow = micros(); - - // If we have a function for computing power, use it! - if(m_pPowerFunc) { - scale = (*m_pPowerFunc)(scale, m_nPowerData); - } - - CLEDController *pCur = CLEDController::head(); - while(pCur) { - uint8_t d = pCur->getDither(); - if(m_nFPS < 100) { pCur->setDither(0); } - pCur->showColor(color, scale); - pCur->setDither(d); - pCur = pCur->next(); - } - countFPS(); -} - -void CFastLED::clear(bool writeData) { - if(writeData) { - showColor(CRGB(0,0,0), 0); - } - clearData(); -} - -void CFastLED::clearData() { - CLEDController *pCur = CLEDController::head(); - while(pCur) { - pCur->clearLedData(); - pCur = pCur->next(); - } -} - -void CFastLED::delay(unsigned long ms) { - unsigned long start = millis(); - do { -#ifndef FASTLED_ACCURATE_CLOCK - // make sure to allow at least one ms to pass to ensure the clock moves - // forward - ::delay(1); -#endif - show(); - yield(); - } - while((millis()-start) < ms); -} - -void CFastLED::setTemperature(const struct CRGB & temp) { - CLEDController *pCur = CLEDController::head(); - while(pCur) { - pCur->setTemperature(temp); - pCur = pCur->next(); - } -} - -void CFastLED::setCorrection(const struct CRGB & correction) { - CLEDController *pCur = CLEDController::head(); - while(pCur) { - pCur->setCorrection(correction); - pCur = pCur->next(); - } -} - -void CFastLED::setDither(uint8_t ditherMode) { - CLEDController *pCur = CLEDController::head(); - while(pCur) { - pCur->setDither(ditherMode); - pCur = pCur->next(); - } -} - -// -// template<int m, int n> void transpose8(unsigned char A[8], unsigned char B[8]) { -// uint32_t x, y, t; -// -// // Load the array and pack it into x and y. -// y = *(unsigned int*)(A); -// x = *(unsigned int*)(A+4); -// -// // x = (A[0]<<24) | (A[m]<<16) | (A[2*m]<<8) | A[3*m]; -// // y = (A[4*m]<<24) | (A[5*m]<<16) | (A[6*m]<<8) | A[7*m]; -// - // // pre-transform x - // t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7); - // t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14); - // - // // pre-transform y - // t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7); - // t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14); - // - // // final transform - // t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F); - // y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F); - // x = t; -// -// B[7*n] = y; y >>= 8; -// B[6*n] = y; y >>= 8; -// B[5*n] = y; y >>= 8; -// B[4*n] = y; -// -// B[3*n] = x; x >>= 8; -// B[2*n] = x; x >>= 8; -// B[n] = x; x >>= 8; -// B[0] = x; -// // B[0]=x>>24; B[n]=x>>16; B[2*n]=x>>8; B[3*n]=x>>0; -// // B[4*n]=y>>24; B[5*n]=y>>16; B[6*n]=y>>8; B[7*n]=y>>0; -// } -// -// void transposeLines(Lines & out, Lines & in) { -// transpose8<1,2>(in.bytes, out.bytes); -// transpose8<1,2>(in.bytes + 8, out.bytes + 1); -// } - -extern int noise_min; -extern int noise_max; - -void CFastLED::countFPS(int nFrames) { - static int br = 0; - static uint32_t lastframe = 0; // millis(); - - if(br++ >= nFrames) { - uint32_t now = millis(); - now -= lastframe; - if(now == 0) { - now = 1; // prevent division by zero below - } - m_nFPS = (br * 1000) / now; - br = 0; - lastframe = millis(); - } -} - -void CFastLED::setMaxRefreshRate(uint16_t refresh, bool constrain) { - if(constrain) { - // if we're constraining, the new value of m_nMinMicros _must_ be higher than previously (because we're only - // allowed to slow things down if constraining) - if(refresh > 0) { - m_nMinMicros = ((1000000 / refresh) > m_nMinMicros) ? (1000000 / refresh) : m_nMinMicros; - } - } else if(refresh > 0) { - m_nMinMicros = 1000000 / refresh; - } else { - m_nMinMicros = 0; - } -} - -extern "C" int atexit(void (* /*func*/ )()) { return 0; } - -#ifdef FASTLED_NEEDS_YIELD -extern "C" void yield(void) { } -#endif - -#ifdef NEED_CXX_BITS -namespace __cxxabiv1 -{ - #if !defined(ESP8266) && !defined(ESP32) - extern "C" void __cxa_pure_virtual (void) {} - #endif - - /* guard variables */ - - /* The ABI requires a 64-bit type. */ - __extension__ typedef int __guard __attribute__((mode(__DI__))); - - extern "C" int __cxa_guard_acquire (__guard *) __attribute__((weak)); - extern "C" void __cxa_guard_release (__guard *) __attribute__((weak)); - extern "C" void __cxa_guard_abort (__guard *) __attribute__((weak)); - - extern "C" int __cxa_guard_acquire (__guard *g) - { - return !*(char *)(g); - } - - extern "C" void __cxa_guard_release (__guard *g) - { - *(char *)g = 1; - } - - extern "C" void __cxa_guard_abort (__guard *) - { - - } -} -#endif - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/FastLED.h b/FastLED/src/FastLED.h deleted file mode 100644 index 042496fca4d105d8e75850667e3967dcd564d69d..0000000000000000000000000000000000000000 --- a/FastLED/src/FastLED.h +++ /dev/null @@ -1,592 +0,0 @@ -#ifndef __INC_FASTSPI_LED2_H -#define __INC_FASTSPI_LED2_H - -///@file FastLED.h -/// central include file for FastLED, defines the CFastLED class/object - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -#define FASTLED_HAS_PRAGMA_MESSAGE -#endif - -#define FASTLED_VERSION 3004000 -#ifndef FASTLED_INTERNAL -# ifdef FASTLED_HAS_PRAGMA_MESSAGE -# pragma message "FastLED version 3.004.000" -# else -# warning FastLED version 3.004.000 (Not really a warning, just telling you here.) -# endif -#endif - -#ifndef __PROG_TYPES_COMPAT__ -#define __PROG_TYPES_COMPAT__ -#endif - -#ifdef SmartMatrix_h -#include <SmartMatrix.h> -#endif - -#ifdef DmxSimple_h -#include <DmxSimple.h> -#endif - -#ifdef DmxSerial_h -#include <DMXSerial.h> -#endif - -#include <stdint.h> - -#include "cpp_compat.h" - -#include "fastled_config.h" -#include "led_sysdefs.h" - -// Utility functions -#include "fastled_delay.h" -#include "bitswap.h" - -#include "controller.h" -#include "fastpin.h" -#include "fastspi_types.h" -#include "dmx.h" - -#include "platforms.h" -#include "fastled_progmem.h" - -#include "lib8tion.h" -#include "pixeltypes.h" -#include "hsv2rgb.h" -#include "colorutils.h" -#include "pixelset.h" -#include "colorpalettes.h" - -#include "noise.h" -#include "power_mgt.h" - -#include "fastspi.h" -#include "chipsets.h" - -FASTLED_NAMESPACE_BEGIN - -/// definitions for the spi chipset constants -enum ESPIChipsets { - LPD6803, - LPD8806, - WS2801, - WS2803, - SM16716, - P9813, - APA102, - SK9822, - DOTSTAR -}; - -enum ESM { SMART_MATRIX }; -enum OWS2811 { OCTOWS2811,OCTOWS2811_400, OCTOWS2813}; -enum SWS2812 { WS2812SERIAL }; - -#ifdef HAS_PIXIE -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class PIXIE : public PixieController<DATA_PIN, RGB_ORDER> {}; -#endif - -#ifdef FASTLED_HAS_CLOCKLESS -template<uint8_t DATA_PIN> class NEOPIXEL : public WS2812Controller800Khz<DATA_PIN, GRB> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SM16703 : public SM16703Controller<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1829 : public TM1829Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1812 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1809 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1804 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1803 : public TM1803Controller400Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1903 : public UCS1903Controller400Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1903B : public UCS1903BController800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1904 : public UCS1904Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS2903 : public UCS2903Controller<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2812 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2852 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2812B : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GS1903 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SK6812 : public SK6812Controller<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SK6822 : public SK6822Controller<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class APA106 : public SK6822Controller<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class PL9823 : public PL9823Controller<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2811 : public WS2811Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2813 : public WS2813Controller<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class APA104 : public WS2811Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2811_400 : public WS2811Controller400Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GE8822 : public GE8822Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GW6205 : public GW6205Controller800Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GW6205_400 : public GW6205Controller400Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class LPD1886 : public LPD1886Controller1250Khz<DATA_PIN, RGB_ORDER> {}; -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class LPD1886_8BIT : public LPD1886Controller1250Khz_8bit<DATA_PIN, RGB_ORDER> {}; -#ifdef DmxSimple_h -template<uint8_t DATA_PIN, EOrder RGB_ORDER> class DMXSIMPLE : public DMXSimpleController<DATA_PIN, RGB_ORDER> {}; -#endif -#ifdef DmxSerial_h -template<EOrder RGB_ORDER> class DMXSERIAL : public DMXSerialController<RGB_ORDER> {}; -#endif -#endif - -enum EBlockChipsets { -#ifdef PORTA_FIRST_PIN - WS2811_PORTA, - WS2813_PORTA, - WS2811_400_PORTA, - TM1803_PORTA, - UCS1903_PORTA, -#endif -#ifdef PORTB_FIRST_PIN - WS2811_PORTB, - WS2813_PORTB, - WS2811_400_PORTB, - TM1803_PORTB, - UCS1903_PORTB, -#endif -#ifdef PORTC_FIRST_PIN - WS2811_PORTC, - WS2813_PORTC, - WS2811_400_PORTC, - TM1803_PORTC, - UCS1903_PORTC, -#endif -#ifdef PORTD_FIRST_PIN - WS2811_PORTD, - WS2813_PORTD, - WS2811_400_PORTD, - TM1803_PORTD, - UCS1903_PORTD, -#endif -#ifdef HAS_PORTDC - WS2811_PORTDC, - WS2813_PORTDC, - WS2811_400_PORTDC, - TM1803_PORTDC, - UCS1903_PORTDC, -#endif -}; - -#if defined(LIB8_ATTINY) -#define NUM_CONTROLLERS 2 -#else -#define NUM_CONTROLLERS 8 -#endif - -typedef uint8_t (*power_func)(uint8_t scale, uint32_t data); - -/// High level controller interface for FastLED. This class manages controllers, global settings and trackings -/// such as brightness, and refresh rates, and provides access functions for driving led data to controllers -/// via the show/showColor/clear methods. -/// @nosubgrouping -class CFastLED { - // int m_nControllers; - uint8_t m_Scale; ///< The current global brightness scale setting - uint16_t m_nFPS; ///< Tracking for current FPS value - uint32_t m_nMinMicros; ///< minimum µs between frames, used for capping frame rates. - uint32_t m_nPowerData; ///< max power use parameter - power_func m_pPowerFunc; ///< function for overriding brightness when using FastLED.show(); - -public: - CFastLED(); - - - /// Add a CLEDController instance to the world. Exposed to the public to allow people to implement their own - /// CLEDController objects or instances. There are two ways to call this method (as well as the other addLeds) - /// variations. The first is with 3 arguments, in which case the arguments are the controller, a pointer to - /// led data, and the number of leds used by this controller. The second is with 4 arguments, in which case - /// the first two arguments are the same, the third argument is an offset into the CRGB data where this controller's - /// CRGB data begins, and the fourth argument is the number of leds for this controller object. - /// @param pLed - the led controller being added - /// @param data - base point to an array of CRGB data structures - /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array - /// @param nLedsIfOffset - number of leds (4 argument version) - /// @returns a reference to the added controller - static CLEDController &addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); - - /// @name Adding SPI based controllers - //@{ - /// Add an SPI based CLEDController instance to the world. - /// There are two ways to call this method (as well as the other addLeds) - /// variations. The first is with 2 arguments, in which case the arguments are a pointer to - /// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case - /// the first argument is the same, the second argument is an offset into the CRGB data where this controller's - /// CRGB data begins, and the third argument is the number of leds for this controller object. - /// - /// This method also takes a 1 to 5 template parameters for identifying the specific chipset, data and clock pins, - /// RGB ordering, and SPI data rate - /// @param data - base point to an array of CRGB data structures - /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array - /// @param nLedsIfOffset - number of leds (4 argument version) - /// @tparam CHIPSET - the chipset type - /// @tparam DATA_PIN - the optional data pin for the leds (if omitted, will default to the first hardware SPI MOSI pin) - /// @tparam CLOCK_PIN - the optional clock pin for the leds (if omitted, will default to the first hardware SPI clock pin) - /// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in) - /// @tparam SPI_DATA_RATE - the data rate to drive the SPI clock at, defined using DATA_RATE_MHZ or DATA_RATE_KHZ macros - /// @returns a reference to the added controller - template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER, uint32_t SPI_DATA_RATE > CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { - case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case DOTSTAR: - case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - } - } - - template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN > static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { - case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case DOTSTAR: - case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - } - } - - template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER > static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { - case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case DOTSTAR: - case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } - } - } - -#ifdef SPI_DATA - template<ESPIChipsets CHIPSET> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB>(data, nLedsOrOffset, nLedsIfOffset); - } - - template<ESPIChipsets CHIPSET, EOrder RGB_ORDER> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER>(data, nLedsOrOffset, nLedsIfOffset); - } - - template<ESPIChipsets CHIPSET, EOrder RGB_ORDER, uint32_t SPI_DATA_RATE> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER, SPI_DATA_RATE>(data, nLedsOrOffset, nLedsIfOffset); - } - -#endif - //@} - -#ifdef FASTLED_HAS_CLOCKLESS - /// @name Adding 3-wire led controllers - //@{ - /// Add a clockless (aka 3wire, also DMX) based CLEDController instance to the world. - /// There are two ways to call this method (as well as the other addLeds) - /// variations. The first is with 2 arguments, in which case the arguments are a pointer to - /// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case - /// the first argument is the same, the second argument is an offset into the CRGB data where this controller's - /// CRGB data begins, and the third argument is the number of leds for this controller object. - /// - /// This method also takes a 2 to 3 template parameters for identifying the specific chipset, data pin, and rgb ordering - /// RGB ordering, and SPI data rate - /// @param data - base point to an array of CRGB data structures - /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array - /// @param nLedsIfOffset - number of leds (4 argument version) - /// @tparam CHIPSET - the chipset type (required) - /// @tparam DATA_PIN - the optional data pin for the leds (required) - /// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in) - /// @returns a reference to the added controller - template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - static CHIPSET<DATA_PIN, RGB_ORDER> c; - return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); - } - - template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - static CHIPSET<DATA_PIN, RGB> c; - return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); - } - - template<template<uint8_t DATA_PIN> class CHIPSET, uint8_t DATA_PIN> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - static CHIPSET<DATA_PIN> c; - return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); - } - -#if defined(__FASTLED_HAS_FIBCC) && (__FASTLED_HAS_FIBCC == 1) - template<uint8_t NUM_LANES, template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB> - static CLEDController &addLeds(struct CRGB *data, int nLeds) { - static __FIBCC<CHIPSET, DATA_PIN, NUM_LANES, RGB_ORDER> c; - return addLeds(&c, data, nLeds); - } -#endif - - #ifdef FASTSPI_USE_DMX_SIMPLE - template<EClocklessChipsets CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) - { - switch(CHIPSET) { - case DMX: { static DMXController<DATA_PIN> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - } - } - #endif - //@} -#endif - - /// @name Adding 3rd party library controllers - //@{ - /// Add a 3rd party library based CLEDController instance to the world. - /// There are two ways to call this method (as well as the other addLeds) - /// variations. The first is with 2 arguments, in which case the arguments are a pointer to - /// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case - /// the first argument is the same, the second argument is an offset into the CRGB data where this controller's - /// CRGB data begins, and the third argument is the number of leds for this controller object. This class includes the SmartMatrix - /// and OctoWS2811 based controllers - /// - /// This method also takes a 1 to 2 template parameters for identifying the specific chipset and rgb ordering - /// RGB ordering, and SPI data rate - /// @param data - base point to an array of CRGB data structures - /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array - /// @param nLedsIfOffset - number of leds (4 argument version) - /// @tparam CHIPSET - the chipset type (required) - /// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in) - /// @returns a reference to the added controller - template<template<EOrder RGB_ORDER> class CHIPSET, EOrder RGB_ORDER> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - static CHIPSET<RGB_ORDER> c; - return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); - } - - template<template<EOrder RGB_ORDER> class CHIPSET> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - static CHIPSET<RGB> c; - return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); - } - -#ifdef USE_OCTOWS2811 - template<OWS2811 CHIPSET, EOrder RGB_ORDER> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) - { - switch(CHIPSET) { - case OCTOWS2811: { static COctoWS2811Controller<RGB_ORDER,WS2811_800kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case OCTOWS2811_400: { static COctoWS2811Controller<RGB_ORDER,WS2811_400kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } -#ifdef WS2813_800kHz - case OCTOWS2813: { static COctoWS2811Controller<RGB_ORDER,WS2813_800kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } -#endif - } - } - - template<OWS2811 CHIPSET> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) - { - return addLeds<CHIPSET,GRB>(data,nLedsOrOffset,nLedsIfOffset); - } - -#endif - -#ifdef USE_WS2812SERIAL - template<SWS2812 CHIPSET, int DATA_PIN, EOrder RGB_ORDER> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) - { - static CWS2812SerialController<DATA_PIN,RGB_ORDER> controller; - return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); - } -#endif - -#ifdef SmartMatrix_h - template<ESM CHIPSET> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) - { - switch(CHIPSET) { - case SMART_MATRIX: { static CSmartMatrixController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - } - } -#endif - //@} - - -#ifdef FASTLED_HAS_BLOCKLESS - - /// @name adding parallel output controllers - //@{ - /// Add a block based CLEDController instance to the world. - /// There are two ways to call this method (as well as the other addLeds) - /// variations. The first is with 2 arguments, in which case the arguments are a pointer to - /// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case - /// the first argument is the same, the second argument is an offset into the CRGB data where this controller's - /// CRGB data begins, and the third argument is the number of leds for this controller object. - /// - /// This method also takes a 2 to 3 template parameters for identifying the specific chipset and rgb ordering - /// RGB ordering, and SPI data rate - /// @param data - base point to an array of CRGB data structures - /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array - /// @param nLedsIfOffset - number of leds (4 argument version) - /// @tparam CHIPSET - the chipset/port type (required) - /// @tparam NUM_LANES - how many parallel lanes of output to write - /// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in) - /// @returns a reference to the added controller - template<EBlockChipsets CHIPSET, int NUM_LANES, EOrder RGB_ORDER> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { - #ifdef PORTA_FIRST_PIN - case WS2811_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2811_400_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2813_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset); - case TM1803_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case UCS1903_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - #endif - #ifdef PORTB_FIRST_PIN - case WS2811_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2811_400_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2813_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset); - case TM1803_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case UCS1903_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - #endif - #ifdef PORTC_FIRST_PIN - case WS2811_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2811_400_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2813_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset); - case TM1803_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case UCS1903_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - #endif - #ifdef PORTD_FIRST_PIN - case WS2811_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2811_400_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2813_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset); - case TM1803_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case UCS1903_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - #endif - #ifdef HAS_PORTDC - case WS2811_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2811_400_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case WS2813_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset); - case TM1803_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - case UCS1903_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); - #endif - } - } - - template<EBlockChipsets CHIPSET, int NUM_LANES> - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - return addLeds<CHIPSET,NUM_LANES,GRB>(data,nLedsOrOffset,nLedsIfOffset); - } - //@} -#endif - - /// Set the global brightness scaling - /// @param scale a 0-255 value for how much to scale all leds before writing them out - void setBrightness(uint8_t scale) { m_Scale = scale; } - - /// Get the current global brightness setting - /// @returns the current global brightness value - uint8_t getBrightness() { return m_Scale; } - - /// Set the maximum power to be used, given in volts and milliamps. - /// @param volts - how many volts the leds are being driven at (usually 5) - /// @param milliamps - the maximum milliamps of power draw you want - inline void setMaxPowerInVoltsAndMilliamps(uint8_t volts, uint32_t milliamps) { setMaxPowerInMilliWatts(volts * milliamps); } - - /// Set the maximum power to be used, given in milliwatts - /// @param milliwatts - the max power draw desired, in milliwatts - inline void setMaxPowerInMilliWatts(uint32_t milliwatts) { m_pPowerFunc = &calculate_max_brightness_for_power_mW; m_nPowerData = milliwatts; } - - /// Update all our controllers with the current led colors, using the passed in brightness - /// @param scale temporarily override the scale - void show(uint8_t scale); - - /// Update all our controllers with the current led colors - void show() { show(m_Scale); } - - /// clear the leds, wiping the local array of data, optionally black out the leds as well - /// @param writeData whether or not to write out to the leds as well - void clear(bool writeData = false); - - /// clear out the local data array - void clearData(); - - /// Set all leds on all controllers to the given color/scale - /// @param color what color to set the leds to - /// @param scale what brightness scale to show at - void showColor(const struct CRGB & color, uint8_t scale); - - /// Set all leds on all controllers to the given color - /// @param color what color to set the leds to - void showColor(const struct CRGB & color) { showColor(color, m_Scale); } - - /// Delay for the given number of milliseconds. Provided to allow the library to be used on platforms - /// that don't have a delay function (to allow code to be more portable). Note: this will call show - /// constantly to drive the dithering engine (and will call show at least once). - /// @param ms the number of milliseconds to pause for - void delay(unsigned long ms); - - /// Set a global color temperature. Sets the color temperature for all added led strips, overriding whatever - /// previous color temperature those controllers may have had - /// @param temp A CRGB structure describing the color temperature - void setTemperature(const struct CRGB & temp); - - /// Set a global color correction. Sets the color correction for all added led strips, - /// overriding whatever previous color correction those controllers may have had. - /// @param correction A CRGB structure describin the color correction. - void setCorrection(const struct CRGB & correction); - - /// Set the dithering mode. Sets the dithering mode for all added led strips, overriding - /// whatever previous dithering option those controllers may have had. - /// @param ditherMode - what type of dithering to use, either BINARY_DITHER or DISABLE_DITHER - void setDither(uint8_t ditherMode = BINARY_DITHER); - - /// Set the maximum refresh rate. This is global for all leds. Attempts to - /// call show faster than this rate will simply wait. Note that the refresh rate - /// defaults to the slowest refresh rate of all the leds added through addLeds. If - /// you wish to set/override this rate, be sure to call setMaxRefreshRate _after_ - /// adding all of your leds. - /// @param refresh - maximum refresh rate in hz - /// @param constrain - constrain refresh rate to the slowest speed yet set - void setMaxRefreshRate(uint16_t refresh, bool constrain=false); - - /// for debugging, will keep track of time between calls to countFPS, and every - /// nFrames calls, it will update an internal counter for the current FPS. - /// @todo make this a rolling counter - /// @param nFrames - how many frames to time for determining FPS - void countFPS(int nFrames=25); - - /// Get the number of frames/second being written out - /// @returns the most recently computed FPS value - uint16_t getFPS() { return m_nFPS; } - - /// Get how many controllers have been registered - /// @returns the number of controllers (strips) that have been added with addLeds - int count(); - - /// Get a reference to a registered controller - /// @returns a reference to the Nth controller - CLEDController & operator[](int x); - - /// Get the number of leds in the first controller - /// @returns the number of LEDs in the first controller - int size() { return (*this)[0].size(); } - - /// Get a pointer to led data for the first controller - /// @returns pointer to the CRGB buffer for the first controller - CRGB *leds() { return (*this)[0].leds(); } -}; - -#define FastSPI_LED FastLED -#define FastSPI_LED2 FastLED -#ifndef LEDS -#define LEDS FastLED -#endif - -extern CFastLED FastLED; - -// Warnings for undefined things -#ifndef HAS_HARDWARE_PIN_SUPPORT -#warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info." -#define NO_HARDWARE_PIN_SUPPORT -#endif - - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/bitswap.cpp b/FastLED/src/bitswap.cpp deleted file mode 100644 index 5be71f02770f4a198d48acb5dca36d7f55adb0c8..0000000000000000000000000000000000000000 --- a/FastLED/src/bitswap.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#define FASTLED_INTERNAL -#include "FastLED.h" - -/// Simplified form of bits rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt - rotating -/// data into LSB for a faster write (the code using this data can happily walk the array backwards) -void transpose8x1_noinline(unsigned char *A, unsigned char *B) { - uint32_t x, y, t; - - // Load the array and pack it into x and y. - y = *(unsigned int*)(A); - x = *(unsigned int*)(A+4); - - // pre-transform x - t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7); - t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14); - - // pre-transform y - t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7); - t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14); - - // final transform - t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F); - y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F); - x = t; - - *((uint32_t*)B) = y; - *((uint32_t*)(B+4)) = x; -} diff --git a/FastLED/src/bitswap.h b/FastLED/src/bitswap.h deleted file mode 100644 index 79eec540b25ca5c2fd432d6a58c70c4764215bdb..0000000000000000000000000000000000000000 --- a/FastLED/src/bitswap.h +++ /dev/null @@ -1,276 +0,0 @@ -#ifndef __INC_BITSWAP_H -#define __INC_BITSWAP_H - -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -///@file bitswap.h -///Functions for rotating bits/bytes - -///@defgroup Bitswap Bit swapping/rotate -///Functions for doing a rotation of bits/bytes used by parallel output -///@{ -#if defined(FASTLED_ARM) || defined(FASTLED_ESP8266) -/// structure representing 8 bits of access -typedef union { - uint8_t raw; - struct { - uint32_t a0:1; - uint32_t a1:1; - uint32_t a2:1; - uint32_t a3:1; - uint32_t a4:1; - uint32_t a5:1; - uint32_t a6:1; - uint32_t a7:1; - }; -} just8bits; - -/// structure representing 32 bits of access -typedef struct { - uint32_t a0:1; - uint32_t a1:1; - uint32_t a2:1; - uint32_t a3:1; - uint32_t a4:1; - uint32_t a5:1; - uint32_t a6:1; - uint32_t a7:1; - uint32_t b0:1; - uint32_t b1:1; - uint32_t b2:1; - uint32_t b3:1; - uint32_t b4:1; - uint32_t b5:1; - uint32_t b6:1; - uint32_t b7:1; - uint32_t c0:1; - uint32_t c1:1; - uint32_t c2:1; - uint32_t c3:1; - uint32_t c4:1; - uint32_t c5:1; - uint32_t c6:1; - uint32_t c7:1; - uint32_t d0:1; - uint32_t d1:1; - uint32_t d2:1; - uint32_t d3:1; - uint32_t d4:1; - uint32_t d5:1; - uint32_t d6:1; - uint32_t d7:1; -} sub4; - -/// union containing a full 8 bytes to swap the bit orientation on -typedef union { - uint32_t word[2]; - uint8_t bytes[8]; - struct { - sub4 a; - sub4 b; - }; -} bitswap_type; - - -#define SWAPSA(X,N) out. X ## 0 = in.a.a ## N; \ - out. X ## 1 = in.a.b ## N; \ - out. X ## 2 = in.a.c ## N; \ - out. X ## 3 = in.a.d ## N; - -#define SWAPSB(X,N) out. X ## 0 = in.b.a ## N; \ - out. X ## 1 = in.b.b ## N; \ - out. X ## 2 = in.b.c ## N; \ - out. X ## 3 = in.b.d ## N; - -#define SWAPS(X,N) out. X ## 0 = in.a.a ## N; \ - out. X ## 1 = in.a.b ## N; \ - out. X ## 2 = in.a.c ## N; \ - out. X ## 3 = in.a.d ## N; \ - out. X ## 4 = in.b.a ## N; \ - out. X ## 5 = in.b.b ## N; \ - out. X ## 6 = in.b.c ## N; \ - out. X ## 7 = in.b.d ## N; - - -/// Do an 8byte by 8bit rotation -__attribute__((always_inline)) inline void swapbits8(bitswap_type in, bitswap_type & out) { - - // SWAPS(a.a,7); - // SWAPS(a.b,6); - // SWAPS(a.c,5); - // SWAPS(a.d,4); - // SWAPS(b.a,3); - // SWAPS(b.b,2); - // SWAPS(b.c,1); - // SWAPS(b.d,0); - - // SWAPSA(a.a,7); - // SWAPSA(a.b,6); - // SWAPSA(a.c,5); - // SWAPSA(a.d,4); - // - // SWAPSB(a.a,7); - // SWAPSB(a.b,6); - // SWAPSB(a.c,5); - // SWAPSB(a.d,4); - // - // SWAPSA(b.a,3); - // SWAPSA(b.b,2); - // SWAPSA(b.c,1); - // SWAPSA(b.d,0); - // // - // SWAPSB(b.a,3); - // SWAPSB(b.b,2); - // SWAPSB(b.c,1); - // SWAPSB(b.d,0); - - for(int i = 0; i < 8; ++i) { - just8bits work; - work.a3 = in.word[0] >> 31; - work.a2 = in.word[0] >> 23; - work.a1 = in.word[0] >> 15; - work.a0 = in.word[0] >> 7; - in.word[0] <<= 1; - work.a7 = in.word[1] >> 31; - work.a6 = in.word[1] >> 23; - work.a5 = in.word[1] >> 15; - work.a4 = in.word[1] >> 7; - in.word[1] <<= 1; - out.bytes[i] = work.raw; - } -} - -/// Slow version of the 8 byte by 8 bit rotation -__attribute__((always_inline)) inline void slowswap(unsigned char *A, unsigned char *B) { - - for(int row = 0; row < 7; ++row) { - uint8_t x = A[row]; - - uint8_t bit = (1<<row); - unsigned char *p = B; - for(uint32_t mask = 1<<7 ; mask ; mask >>= 1) { - if(x & mask) { - *p++ |= bit; - } else { - *p++ &= ~bit; - } - } - // B[7] |= (x & 0x01) << row; x >>= 1; - // B[6] |= (x & 0x01) << row; x >>= 1; - // B[5] |= (x & 0x01) << row; x >>= 1; - // B[4] |= (x & 0x01) << row; x >>= 1; - // B[3] |= (x & 0x01) << row; x >>= 1; - // B[2] |= (x & 0x01) << row; x >>= 1; - // B[1] |= (x & 0x01) << row; x >>= 1; - // B[0] |= (x & 0x01) << row; x >>= 1; - } -} - -void transpose8x1_noinline(unsigned char *A, unsigned char *B); - -/// Simplified form of bits rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt - rotating -/// data into LSB for a faster write (the code using this data can happily walk the array backwards) -__attribute__((always_inline)) inline void transpose8x1(unsigned char *A, unsigned char *B) { - uint32_t x, y, t; - - // Load the array and pack it into x and y. - y = *(unsigned int*)(A); - x = *(unsigned int*)(A+4); - - // pre-transform x - t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7); - t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14); - - // pre-transform y - t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7); - t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14); - - // final transform - t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F); - y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F); - x = t; - - *((uint32_t*)B) = y; - *((uint32_t*)(B+4)) = x; -} - -/// Simplified form of bits rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt -__attribute__((always_inline)) inline void transpose8x1_MSB(unsigned char *A, unsigned char *B) { - uint32_t x, y, t; - - // Load the array and pack it into x and y. - y = *(unsigned int*)(A); - x = *(unsigned int*)(A+4); - - // pre-transform x - t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7); - t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14); - - // pre-transform y - t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7); - t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14); - - // final transform - t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F); - y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F); - x = t; - - B[7] = y; y >>= 8; - B[6] = y; y >>= 8; - B[5] = y; y >>= 8; - B[4] = y; - - B[3] = x; x >>= 8; - B[2] = x; x >>= 8; - B[1] = x; x >>= 8; - B[0] = x; /* */ -} - -/// templated bit-rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt -template<int m, int n> -__attribute__((always_inline)) inline void transpose8(unsigned char *A, unsigned char *B) { - uint32_t x, y, t; - - // Load the array and pack it into x and y. - if(m == 1) { - y = *(unsigned int*)(A); - x = *(unsigned int*)(A+4); - } else { - x = (A[0]<<24) | (A[m]<<16) | (A[2*m]<<8) | A[3*m]; - y = (A[4*m]<<24) | (A[5*m]<<16) | (A[6*m]<<8) | A[7*m]; - } - - // pre-transform x - t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7); - t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14); - - // pre-transform y - t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7); - t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14); - - // final transform - t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F); - y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F); - x = t; - - B[7*n] = y; y >>= 8; - B[6*n] = y; y >>= 8; - B[5*n] = y; y >>= 8; - B[4*n] = y; - - B[3*n] = x; x >>= 8; - B[2*n] = x; x >>= 8; - B[n] = x; x >>= 8; - B[0] = x; - // B[0]=x>>24; B[n]=x>>16; B[2*n]=x>>8; B[3*n]=x>>0; - // B[4*n]=y>>24; B[5*n]=y>>16; B[6*n]=y>>8; B[7*n]=y>>0; -} - -#endif - -FASTLED_NAMESPACE_END - -///@} -#endif diff --git a/FastLED/src/chipsets.h b/FastLED/src/chipsets.h deleted file mode 100644 index 60457254e2d1716af8f7e2263329921576c85344..0000000000000000000000000000000000000000 --- a/FastLED/src/chipsets.h +++ /dev/null @@ -1,619 +0,0 @@ -#ifndef __INC_CHIPSETS_H -#define __INC_CHIPSETS_H - -#include "FastLED.h" -#include "pixeltypes.h" - -///@file chipsets.h -/// contains the bulk of the definitions for the various LED chipsets supported. - -FASTLED_NAMESPACE_BEGIN -///@defgroup chipsets -/// Implementations of CLEDController classes for various led chipsets. -/// -///@{ - -#if defined(ARDUINO) //&& defined(SoftwareSerial_h) - - -#if defined(SoftwareSerial_h) || defined(__SoftwareSerial_h) -#include <SoftwareSerial.h> - -#define HAS_PIXIE - -/// Adafruit Pixie controller class -/// @tparam DATAPIN the pin to write data out on -/// @tparam RGB_ORDER the RGB ordering for the led data -template<uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class PixieController : public CPixelLEDController<RGB_ORDER> { - SoftwareSerial Serial; - CMinWait<2000> mWait; - -public: - PixieController() : Serial(-1, DATA_PIN) {} - -protected: - virtual void init() { - Serial.begin(115200); - mWait.mark(); - } - - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - while(pixels.has(1)) { - uint8_t r = pixels.loadAndScale0(); - Serial.write(r); - uint8_t g = pixels.loadAndScale1(); - Serial.write(g); - uint8_t b = pixels.loadAndScale2(); - Serial.write(b); - pixels.advanceData(); - pixels.stepDithering(); - } - mWait.mark(); - } - -}; - -// template<SoftwareSerial & STREAM, EOrder RGB_ORDER = RGB> -// class PixieController : public PixieBaseController<STREAM, RGB_ORDER> { -// public: -// virtual void init() { -// STREAM.begin(115200); -// } -// }; -#endif -#endif - -///@name Clocked chipsets - nominally SPI based these chipsets have a data and a clock line. -///@{ -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// LPD8806 controller class - takes data/clock/select pin values (N.B. should take an SPI definition?) -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/// LPD8806 controller class. -/// @tparam DATA_PIN the data pin for these leds -/// @tparam CLOCK_PIN the clock pin for these leds -/// @tparam RGB_ORDER the RGB ordering for these leds -/// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(12) -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12) > -class LPD8806Controller : public CPixelLEDController<RGB_ORDER> { - typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; - - class LPD8806_ADJUST { - public: - // LPD8806 spec wants the high bit of every rgb data byte sent out to be set. - __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data && (data<254)) & 0x01); } - __attribute__((always_inline)) inline static void postBlock(int len) { - SPI::writeBytesValueRaw(0, ((len*3+63)>>6)); - } - - }; - - SPI mSPI; - -public: - LPD8806Controller() {} - virtual void init() { - mSPI.init(); - } - -protected: - - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(pixels); - } -}; - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// WS2801 definition - takes data/clock/select pin values (N.B. should take an SPI definition?) -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/// WS2801 controller class. -/// @tparam DATA_PIN the data pin for these leds -/// @tparam CLOCK_PIN the clock pin for these leds -/// @tparam RGB_ORDER the RGB ordering for these leds -/// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(1) -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(1)> -class WS2801Controller : public CPixelLEDController<RGB_ORDER> { - typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; - SPI mSPI; - CMinWait<1000> mWaitDelay; - -public: - WS2801Controller() {} - - virtual void init() { - mSPI.init(); - mWaitDelay.mark(); - } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWaitDelay.wait(); - mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(pixels); - mWaitDelay.mark(); - } -}; - -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(25)> -class WS2803Controller : public WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_SPEED> {}; - -/// LPD6803 controller class (LPD1101). -/// 16 bit (1 bit - const "1", 5 bit - red, 5 bit - green, 5 bit blue). -/// In chip CMODE pin must be set to 1 (inside oscillator mode). -/// Datasheet: https://cdn-shop.adafruit.com/datasheets/LPD6803.pdf -/// @tparam DATA_PIN the data pin for these leds -/// @tparam CLOCK_PIN the clock pin for these leds -/// @tparam RGB_ORDER the RGB ordering for these leds -/// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(12) -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12)> -class LPD6803Controller : public CPixelLEDController<RGB_ORDER> { - typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; - SPI mSPI; - - void startBoundary() { mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); } - -public: - LPD6803Controller() {} - - virtual void init() { - mSPI.init(); - } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mSPI.select(); - - startBoundary(); - while(pixels.has(1)) { - register uint16_t command; - command = 0x8000; - command |= (pixels.loadAndScale0() & 0xF8) << 7; // red is the high 5 bits - command |= (pixels.loadAndScale1() & 0xF8) << 2; // green is the middle 5 bits - mSPI.writeByte((command >> 8) & 0xFF); - command |= pixels.loadAndScale2() >> 3 ; // blue is the low 5 bits - mSPI.writeByte(command & 0xFF); - - pixels.stepDithering(); - pixels.advanceData(); - } - //endBoundary(pixels.size()); - mSPI.waitFully(); - mSPI.release(); - } - -}; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// APA102 definition - takes data/clock/select pin values (N.B. should take an SPI definition?) -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/// APA102 controller class. -/// @tparam DATA_PIN the data pin for these leds -/// @tparam CLOCK_PIN the clock pin for these leds -/// @tparam RGB_ORDER the RGB ordering for these leds -/// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(12) -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12)> -class APA102Controller : public CPixelLEDController<RGB_ORDER> { - typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; - SPI mSPI; - - void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } - void endBoundary(int nLeds) { int nDWords = (nLeds/32); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nDWords--); } - - inline void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) { -#ifdef FASTLED_SPI_BYTE_ONLY - mSPI.writeByte(0xE0 | brightness); - mSPI.writeByte(b0); - mSPI.writeByte(b1); - mSPI.writeByte(b2); -#else - uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0; - mSPI.writeWord(b); - uint16_t w = b1 << 8; - w |= b2; - mSPI.writeWord(w); -#endif - } - -public: - APA102Controller() {} - - virtual void init() { - mSPI.init(); - } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mSPI.select(); - - uint8_t s0 = pixels.getScale0(), s1 = pixels.getScale1(), s2 = pixels.getScale2(); -#if FASTLED_USE_GLOBAL_BRIGHTNESS == 1 - const uint16_t maxBrightness = 0x1F; - uint16_t brightness = ((((uint16_t)max(max(s0, s1), s2) + 1) * maxBrightness - 1) >> 8) + 1; - s0 = (maxBrightness * s0 + (brightness >> 1)) / brightness; - s1 = (maxBrightness * s1 + (brightness >> 1)) / brightness; - s2 = (maxBrightness * s2 + (brightness >> 1)) / brightness; -#else - const uint8_t brightness = 0x1F; -#endif - - startBoundary(); - while (pixels.has(1)) { - writeLed(brightness, pixels.loadAndScale0(0, s0), pixels.loadAndScale1(0, s1), pixels.loadAndScale2(0, s2)); - pixels.stepDithering(); - pixels.advanceData(); - } - endBoundary(pixels.size()); - - mSPI.waitFully(); - mSPI.release(); - } - -}; - -/// SK9822 controller class. -/// @tparam DATA_PIN the data pin for these leds -/// @tparam CLOCK_PIN the clock pin for these leds -/// @tparam RGB_ORDER the RGB ordering for these leds -/// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(24) -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(24)> -class SK9822Controller : public CPixelLEDController<RGB_ORDER> { - typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; - SPI mSPI; - - void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } - void endBoundary(int nLeds) { int nLongWords = (nLeds/32); do { mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nLongWords--); } - - inline void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) { -#ifdef FASTLED_SPI_BYTE_ONLY - mSPI.writeByte(0xE0 | brightness); - mSPI.writeByte(b0); - mSPI.writeByte(b1); - mSPI.writeByte(b2); -#else - uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0; - mSPI.writeWord(b); - uint16_t w = b1 << 8; - w |= b2; - mSPI.writeWord(w); -#endif - } - -public: - SK9822Controller() {} - - virtual void init() { - mSPI.init(); - } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mSPI.select(); - - uint8_t s0 = pixels.getScale0(), s1 = pixels.getScale1(), s2 = pixels.getScale2(); -#if FASTLED_USE_GLOBAL_BRIGHTNESS == 1 - const uint16_t maxBrightness = 0x1F; - uint16_t brightness = ((((uint16_t)max(max(s0, s1), s2) + 1) * maxBrightness - 1) >> 8) + 1; - s0 = (maxBrightness * s0 + (brightness >> 1)) / brightness; - s1 = (maxBrightness * s1 + (brightness >> 1)) / brightness; - s2 = (maxBrightness * s2 + (brightness >> 1)) / brightness; -#else - const uint8_t brightness = 0x1F; -#endif - - startBoundary(); - while (pixels.has(1)) { - writeLed(brightness, pixels.loadAndScale0(0, s0), pixels.loadAndScale1(0, s1), pixels.loadAndScale2(0, s2)); - pixels.stepDithering(); - pixels.advanceData(); - } - - endBoundary(pixels.size()); - - mSPI.waitFully(); - mSPI.release(); - } - -}; - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// P9813 definition - takes data/clock/select pin values (N.B. should take an SPI definition?) -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/// P9813 controller class. -/// @tparam DATA_PIN the data pin for these leds -/// @tparam CLOCK_PIN the clock pin for these leds -/// @tparam RGB_ORDER the RGB ordering for these leds -/// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(10) -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(10)> -class P9813Controller : public CPixelLEDController<RGB_ORDER> { - typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; - SPI mSPI; - - void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } - - inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) { - register uint8_t top = 0xC0 | ((~b & 0xC0) >> 2) | ((~g & 0xC0) >> 4) | ((~r & 0xC0) >> 6); - mSPI.writeByte(top); mSPI.writeByte(b); mSPI.writeByte(g); mSPI.writeByte(r); - } - -public: - P9813Controller() {} - - virtual void init() { - mSPI.init(); - } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mSPI.select(); - - writeBoundary(); - while(pixels.has(1)) { - writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); - pixels.advanceData(); - pixels.stepDithering(); - } - writeBoundary(); - mSPI.waitFully(); - - mSPI.release(); - } - -}; - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// SM16716 definition - takes data/clock/select pin values (N.B. should take an SPI definition?) -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/// SM16716 controller class. -/// @tparam DATA_PIN the data pin for these leds -/// @tparam CLOCK_PIN the clock pin for these leds -/// @tparam RGB_ORDER the RGB ordering for these leds -/// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(16) -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(16)> -class SM16716Controller : public CPixelLEDController<RGB_ORDER> { - typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; - SPI mSPI; - - void writeHeader() { - // Write out 50 zeros to the spi line (6 blocks of 8 followed by two single bit writes) - mSPI.select(); - mSPI.template writeBit<0>(0); - mSPI.writeByte(0); - mSPI.writeByte(0); - mSPI.writeByte(0); - mSPI.template writeBit<0>(0); - mSPI.writeByte(0); - mSPI.writeByte(0); - mSPI.writeByte(0); - mSPI.waitFully(); - mSPI.release(); - } - -public: - SM16716Controller() {} - - virtual void init() { - mSPI.init(); - } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start - // of each triplet of bytes for rgb data - // writeHeader(); - mSPI.template writePixels<FLAG_START_BIT, DATA_NOP, RGB_ORDER>( pixels ); - writeHeader(); - } - -}; -/// @} -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Clockless template instantiations - see clockless.h for how the timing values are used -// -// Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. -// At T=0 : the line is raised hi to start a bit -// At T=T1 : the line is dropped low to transmit a zero bit -// At T=T1+T2 : the line is dropped low to transmit a one bit -// At T=T1+T2+T3 : the cycle is concluded (next bit can be sent) -// -// The units used for T1, T2, and T3 is nanoseconds. -// For 8MHz/16MHz/24MHz frequencies, these values are also guaranteed -// to be integral multiples of an 8MHz clock (125ns increments). -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#ifdef FASTLED_HAS_CLOCKLESS -/// @name clockless controllers -/// Provides timing definitions for the variety of clockless controllers supplied by the library. -/// @{ - -// Allow clock that clockless controller is based on to have different -// frequency than the CPU. -#if !defined(CLOCKLESS_FREQUENCY) - #define CLOCKLESS_FREQUENCY F_CPU -#endif - -// We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz -// need the more tightly defined timeframes. -#if defined(__LGT8F__) || (CLOCKLESS_FREQUENCY == 8000000 || CLOCKLESS_FREQUENCY == 16000000 || CLOCKLESS_FREQUENCY == 24000000) // || CLOCKLESS_FREQUENCY == 48000000 || CLOCKLESS_FREQUENCY == 96000000) // 125ns/clock -#define FMUL (CLOCKLESS_FREQUENCY/8000000) - -// GE8822 -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class GE8822Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER, 4> {}; - -// LPD1886 -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER, 4> {}; - -// LPD1886 -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER> {}; - -// WS2811@800khz 2 clocks, 5 clocks, 3 clocks -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class WS2812Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class WS2811Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> //not tested -class WS2813Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class WS2811Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 10 * FMUL, 6 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class SK6822Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class SM16703Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class SK6812Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 12 * FMUL, 4 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class UCS1903BController800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class UCS2903Controller : public ClocklessController<DATA_PIN, 2 * FMUL, 6 * FMUL, 2 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class TM1809Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class TM1803Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 9 * FMUL, 6 * FMUL, RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class TM1829Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER, 0, true, 500> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class GW6205Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 7 * FMUL, 6 * FMUL, RGB_ORDER, 4> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class GW6205Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER, 4> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class PL9823Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {}; - -#else - -// Similar to NS() macro, this calculates the number of cycles for -// the clockless chipset (which may differ from CPU cycles) - -#ifdef FASTLED_TEENSY4 -// just use raw nanosecond values for the teensy4 -#define C_NS(_NS) _NS -#else -#define C_NS(_NS) (((_NS * ((CLOCKLESS_FREQUENCY / 1000000L)) + 999)) / 1000) -#endif - -// GE8822 - 350ns 660ns 350ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class GE8822Controller800Khz : public ClocklessController<DATA_PIN, C_NS(350), C_NS(660), C_NS(350), RGB_ORDER, 4> {}; - -// GW6205@400khz - 800ns, 800ns, 800ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class GW6205Controller400Khz : public ClocklessController<DATA_PIN, C_NS(800), C_NS(800), C_NS(800), RGB_ORDER, 4> {}; - -// GW6205@400khz - 400ns, 400ns, 400ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class GW6205Controller800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(400), C_NS(400), RGB_ORDER, 4> {}; - -// UCS1903 - 500ns, 1500ns, 500ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, C_NS(500), C_NS(1500), C_NS(500), RGB_ORDER> {}; - -// UCS1903B - 400ns, 450ns, 450ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class UCS1903BController800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(450), C_NS(450), RGB_ORDER> {}; - -// UCS1904 - 400ns, 400ns, 450ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(400), C_NS(450), RGB_ORDER> {}; - -// UCS2903 - 250ns, 750ns, 250ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class UCS2903Controller : public ClocklessController<DATA_PIN, C_NS(250), C_NS(750), C_NS(250), RGB_ORDER> {}; - -// TM1809 - 350ns, 350ns, 550ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class TM1809Controller800Khz : public ClocklessController<DATA_PIN, C_NS(350), C_NS(350), C_NS(450), RGB_ORDER> {}; - -// WS2811 - 320ns, 320ns, 640ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class WS2811Controller800Khz : public ClocklessController<DATA_PIN, C_NS(320), C_NS(320), C_NS(640), RGB_ORDER> {}; - -// WS2813 - 320ns, 320ns, 640ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class WS2813Controller : public ClocklessController<DATA_PIN, C_NS(320), C_NS(320), C_NS(640), RGB_ORDER> {}; - -// WS2812 - 250ns, 625ns, 375ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class WS2812Controller800Khz : public ClocklessController<DATA_PIN, C_NS(250), C_NS(625), C_NS(375), RGB_ORDER> {}; - -// WS2811@400khz - 800ns, 800ns, 900ns -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class WS2811Controller400Khz : public ClocklessController<DATA_PIN, C_NS(800), C_NS(800), C_NS(900), RGB_ORDER> {}; - -// 750NS, 750NS, 750NS -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class TM1803Controller400Khz : public ClocklessController<DATA_PIN, C_NS(700), C_NS(1100), C_NS(700), RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class TM1829Controller800Khz : public ClocklessController<DATA_PIN, C_NS(340), C_NS(340), C_NS(550), RGB_ORDER, 0, true, 500> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class TM1829Controller1600Khz : public ClocklessController<DATA_PIN, C_NS(100), C_NS(300), C_NS(200), RGB_ORDER, 0, true, 500> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, C_NS(200), C_NS(400), C_NS(200), RGB_ORDER, 4> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, C_NS(200), C_NS(400), C_NS(200), RGB_ORDER> {}; - - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class SK6822Controller : public ClocklessController<DATA_PIN, C_NS(375), C_NS(1000), C_NS(375), RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class SK6812Controller : public ClocklessController<DATA_PIN, C_NS(300), C_NS(300), C_NS(600), RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class SM16703Controller : public ClocklessController<DATA_PIN, C_NS(300), C_NS(600), C_NS(300), RGB_ORDER> {}; - -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class PL9823Controller : public ClocklessController<DATA_PIN, C_NS(350), C_NS(1010), C_NS(350), RGB_ORDER> {}; -#endif -///@} - -#endif -///@} -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/color.h b/FastLED/src/color.h deleted file mode 100644 index 63687cb55f391b6b42709ccd6faf9b9bf6eb33a8..0000000000000000000000000000000000000000 --- a/FastLED/src/color.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __INC_COLOR_H -#define __INC_COLOR_H - -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -///@file color.h -/// contains definitions for color correction and temperature -///@defgroup ColorEnums Color correction/temperature -/// definitions for color correction and light temperatures -///@{ -typedef enum { - // Color correction starting points - - /// typical values for SMD5050 LEDs - ///@{ - TypicalSMD5050=0xFFB0F0 /* 255, 176, 240 */, - TypicalLEDStrip=0xFFB0F0 /* 255, 176, 240 */, - ///@} - - /// typical values for 8mm "pixels on a string" - /// also for many through-hole 'T' package LEDs - ///@{ - Typical8mmPixel=0xFFE08C /* 255, 224, 140 */, - TypicalPixelString=0xFFE08C /* 255, 224, 140 */, - ///@} - - /// uncorrected color - UncorrectedColor=0xFFFFFF - -} LEDColorCorrection; - - -typedef enum { - /// @name Black-body radiation light sources - /// Black-body radiation light sources emit a (relatively) continuous - /// spectrum, and can be described as having a Kelvin 'temperature' - ///@{ - /// 1900 Kelvin - Candle=0xFF9329 /* 1900 K, 255, 147, 41 */, - /// 2600 Kelvin - Tungsten40W=0xFFC58F /* 2600 K, 255, 197, 143 */, - /// 2850 Kelvin - Tungsten100W=0xFFD6AA /* 2850 K, 255, 214, 170 */, - /// 3200 Kelvin - Halogen=0xFFF1E0 /* 3200 K, 255, 241, 224 */, - /// 5200 Kelvin - CarbonArc=0xFFFAF4 /* 5200 K, 255, 250, 244 */, - /// 5400 Kelvin - HighNoonSun=0xFFFFFB /* 5400 K, 255, 255, 251 */, - /// 6000 Kelvin - DirectSunlight=0xFFFFFF /* 6000 K, 255, 255, 255 */, - /// 7000 Kelvin - OvercastSky=0xC9E2FF /* 7000 K, 201, 226, 255 */, - /// 20000 Kelvin - ClearBlueSky=0x409CFF /* 20000 K, 64, 156, 255 */, - ///@} - - /// @name Gaseous light sources - /// Gaseous light sources emit discrete spectral bands, and while we can - /// approximate their aggregate hue with RGB values, they don't actually - /// have a proper Kelvin temperature. - ///@{ - WarmFluorescent=0xFFF4E5 /* 0 K, 255, 244, 229 */, - StandardFluorescent=0xF4FFFA /* 0 K, 244, 255, 250 */, - CoolWhiteFluorescent=0xD4EBFF /* 0 K, 212, 235, 255 */, - FullSpectrumFluorescent=0xFFF4F2 /* 0 K, 255, 244, 242 */, - GrowLightFluorescent=0xFFEFF7 /* 0 K, 255, 239, 247 */, - BlackLightFluorescent=0xA700FF /* 0 K, 167, 0, 255 */, - MercuryVapor=0xD8F7FF /* 0 K, 216, 247, 255 */, - SodiumVapor=0xFFD1B2 /* 0 K, 255, 209, 178 */, - MetalHalide=0xF2FCFF /* 0 K, 242, 252, 255 */, - HighPressureSodium=0xFFB74C /* 0 K, 255, 183, 76 */, - ///@} - - /// Uncorrected temperature 0xFFFFFF - UncorrectedTemperature=0xFFFFFF -} ColorTemperature; - -FASTLED_NAMESPACE_END - -///@} -#endif diff --git a/FastLED/src/colorpalettes.cpp b/FastLED/src/colorpalettes.cpp deleted file mode 100644 index 68e42f0353fba1df5616eddd4a7a4a34f9a100a9..0000000000000000000000000000000000000000 --- a/FastLED/src/colorpalettes.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef __INC_COLORPALETTES_H -#define __INC_COLORPALETTES_H -#define FASTLED_INTERNAL -#include "FastLED.h" -#include "colorutils.h" -#include "colorpalettes.h" - -FASTLED_USING_NAMESPACE - - -// Preset color schemes, such as they are. - -// These schemes are all declared as "PROGMEM", meaning -// that they won't take up SRAM on AVR chips until used. -// Furthermore, the compiler won't even include these -// in your PROGMEM (flash) storage unless you specifically -// use each one, so you only 'pay for' those you actually use. - - -extern const TProgmemRGBPalette16 CloudColors_p FL_PROGMEM = -{ - CRGB::Blue, - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - - CRGB::Blue, - CRGB::DarkBlue, - CRGB::SkyBlue, - CRGB::SkyBlue, - - CRGB::LightBlue, - CRGB::White, - CRGB::LightBlue, - CRGB::SkyBlue -}; - -extern const TProgmemRGBPalette16 LavaColors_p FL_PROGMEM = -{ - CRGB::Black, - CRGB::Maroon, - CRGB::Black, - CRGB::Maroon, - - CRGB::DarkRed, - CRGB::Maroon, - CRGB::DarkRed, - - CRGB::DarkRed, - CRGB::DarkRed, - CRGB::Red, - CRGB::Orange, - - CRGB::White, - CRGB::Orange, - CRGB::Red, - CRGB::DarkRed -}; - - -extern const TProgmemRGBPalette16 OceanColors_p FL_PROGMEM = -{ - CRGB::MidnightBlue, - CRGB::DarkBlue, - CRGB::MidnightBlue, - CRGB::Navy, - - CRGB::DarkBlue, - CRGB::MediumBlue, - CRGB::SeaGreen, - CRGB::Teal, - - CRGB::CadetBlue, - CRGB::Blue, - CRGB::DarkCyan, - CRGB::CornflowerBlue, - - CRGB::Aquamarine, - CRGB::SeaGreen, - CRGB::Aqua, - CRGB::LightSkyBlue -}; - -extern const TProgmemRGBPalette16 ForestColors_p FL_PROGMEM = -{ - CRGB::DarkGreen, - CRGB::DarkGreen, - CRGB::DarkOliveGreen, - CRGB::DarkGreen, - - CRGB::Green, - CRGB::ForestGreen, - CRGB::OliveDrab, - CRGB::Green, - - CRGB::SeaGreen, - CRGB::MediumAquamarine, - CRGB::LimeGreen, - CRGB::YellowGreen, - - CRGB::LightGreen, - CRGB::LawnGreen, - CRGB::MediumAquamarine, - CRGB::ForestGreen -}; - -/// HSV Rainbow -extern const TProgmemRGBPalette16 RainbowColors_p FL_PROGMEM = -{ - 0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00, - 0xABAB00, 0x56D500, 0x00FF00, 0x00D52A, - 0x00AB55, 0x0056AA, 0x0000FF, 0x2A00D5, - 0x5500AB, 0x7F0081, 0xAB0055, 0xD5002B -}; - -/// HSV Rainbow colors with alternatating stripes of black -#define RainbowStripesColors_p RainbowStripeColors_p -extern const TProgmemRGBPalette16 RainbowStripeColors_p FL_PROGMEM = -{ - 0xFF0000, 0x000000, 0xAB5500, 0x000000, - 0xABAB00, 0x000000, 0x00FF00, 0x000000, - 0x00AB55, 0x000000, 0x0000FF, 0x000000, - 0x5500AB, 0x000000, 0xAB0055, 0x000000 -}; - -/// HSV color ramp: blue purple ping red orange yellow (and back) -/// Basically, everything but the greens, which tend to make -/// people's skin look unhealthy. This palette is good for -/// lighting at a club or party, where it'll be shining on people. -extern const TProgmemRGBPalette16 PartyColors_p FL_PROGMEM = -{ - 0x5500AB, 0x84007C, 0xB5004B, 0xE5001B, - 0xE81700, 0xB84700, 0xAB7700, 0xABAB00, - 0xAB5500, 0xDD2200, 0xF2000E, 0xC2003E, - 0x8F0071, 0x5F00A1, 0x2F00D0, 0x0007F9 -}; - -/// Approximate "black body radiation" palette, akin to -/// the FastLED 'HeatColor' function. -/// Recommend that you use values 0-240 rather than -/// the usual 0-255, as the last 15 colors will be -/// 'wrapping around' from the hot end to the cold end, -/// which looks wrong. -extern const TProgmemRGBPalette16 HeatColors_p FL_PROGMEM = -{ - 0x000000, - 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, - 0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00, - 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF -}; - - -// Gradient palette "Rainbow_gp", -// provided for situations where you're going -// to use a number of other gradient palettes, AND -// you want a 'standard' FastLED rainbow as well. - -DEFINE_GRADIENT_PALETTE( Rainbow_gp ) { - 0, 255, 0, 0, // Red - 32, 171, 85, 0, // Orange - 64, 171, 171, 0, // Yellow - 96, 0, 255, 0, // Green - 128, 0, 171, 85, // Aqua - 160, 0, 0, 255, // Blue - 192, 85, 0, 171, // Purple - 224, 171, 0, 85, // Pink - 255, 255, 0, 0};// and back to Red - -#endif diff --git a/FastLED/src/colorpalettes.h b/FastLED/src/colorpalettes.h deleted file mode 100644 index 4458575e41870227d4432ff96d3a135579d08f75..0000000000000000000000000000000000000000 --- a/FastLED/src/colorpalettes.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __INC_COLORPALETTES_H -#define __INC_COLORPALETTES_H - -#include "FastLED.h" -#include "colorutils.h" - -///@file colorpalettes.h -/// contains definitions for the predefined color palettes supplied by FastLED. - -FASTLED_NAMESPACE_BEGIN - -///@defgroup Colorpalletes Pre-defined color palletes -/// These schemes are all declared as "PROGMEM", meaning -/// that they won't take up SRAM on AVR chips until used. -/// Furthermore, the compiler won't even include these -/// in your PROGMEM (flash) storage unless you specifically -/// use each one, so you only 'pay for' those you actually use. - -///@{ - -/// Cloudy color pallete -extern const TProgmemRGBPalette16 CloudColors_p FL_PROGMEM; -/// Lava colors -extern const TProgmemRGBPalette16 LavaColors_p FL_PROGMEM; -/// Ocean colors, blues and whites -extern const TProgmemRGBPalette16 OceanColors_p FL_PROGMEM; -/// Forest colors, greens -extern const TProgmemRGBPalette16 ForestColors_p FL_PROGMEM; - -/// HSV Rainbow -extern const TProgmemRGBPalette16 RainbowColors_p FL_PROGMEM; - -#define RainbowStripesColors_p RainbowStripeColors_p -/// HSV Rainbow colors with alternatating stripes of black -extern const TProgmemRGBPalette16 RainbowStripeColors_p FL_PROGMEM; - -/// HSV color ramp: blue purple ping red orange yellow (and back) -/// Basically, everything but the greens, which tend to make -/// people's skin look unhealthy. This palette is good for -/// lighting at a club or party, where it'll be shining on people. -extern const TProgmemRGBPalette16 PartyColors_p FL_PROGMEM; - -/// Approximate "black body radiation" palette, akin to -/// the FastLED 'HeatColor' function. -/// Recommend that you use values 0-240 rather than -/// the usual 0-255, as the last 15 colors will be -/// 'wrapping around' from the hot end to the cold end, -/// which looks wrong. -extern const TProgmemRGBPalette16 HeatColors_p FL_PROGMEM; - - -DECLARE_GRADIENT_PALETTE( Rainbow_gp); - -FASTLED_NAMESPACE_END - -///@} -#endif diff --git a/FastLED/src/colorutils.cpp b/FastLED/src/colorutils.cpp deleted file mode 100644 index c40f4860586f6ad5c2dbee5751b717e57566538a..0000000000000000000000000000000000000000 --- a/FastLED/src/colorutils.cpp +++ /dev/null @@ -1,1198 +0,0 @@ -#define FASTLED_INTERNAL -#define __PROG_TYPES_COMPAT__ - -#include <stdint.h> -#include <math.h> - -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - - - -void fill_solid( struct CRGB * leds, int numToFill, - const struct CRGB& color) -{ - for( int i = 0; i < numToFill; ++i) { - leds[i] = color; - } -} - -void fill_solid( struct CHSV * targetArray, int numToFill, - const struct CHSV& hsvColor) -{ - for( int i = 0; i < numToFill; ++i) { - targetArray[i] = hsvColor; - } -} - - -// void fill_solid( struct CRGB* targetArray, int numToFill, -// const struct CHSV& hsvColor) -// { -// fill_solid<CRGB>( targetArray, numToFill, (CRGB) hsvColor); -// } - -void fill_rainbow( struct CRGB * pFirstLED, int numToFill, - uint8_t initialhue, - uint8_t deltahue ) -{ - CHSV hsv; - hsv.hue = initialhue; - hsv.val = 255; - hsv.sat = 240; - for( int i = 0; i < numToFill; ++i) { - pFirstLED[i] = hsv; - hsv.hue += deltahue; - } -} - -void fill_rainbow( struct CHSV * targetArray, int numToFill, - uint8_t initialhue, - uint8_t deltahue ) -{ - CHSV hsv; - hsv.hue = initialhue; - hsv.val = 255; - hsv.sat = 240; - for( int i = 0; i < numToFill; ++i) { - targetArray[i] = hsv; - hsv.hue += deltahue; - } -} - - -void fill_gradient_RGB( CRGB* leds, - uint16_t startpos, CRGB startcolor, - uint16_t endpos, CRGB endcolor ) -{ - // if the points are in the wrong order, straighten them - if( endpos < startpos ) { - uint16_t t = endpos; - CRGB tc = endcolor; - endcolor = startcolor; - endpos = startpos; - startpos = t; - startcolor = tc; - } - - saccum87 rdistance87; - saccum87 gdistance87; - saccum87 bdistance87; - - rdistance87 = (endcolor.r - startcolor.r) << 7; - gdistance87 = (endcolor.g - startcolor.g) << 7; - bdistance87 = (endcolor.b - startcolor.b) << 7; - - uint16_t pixeldistance = endpos - startpos; - int16_t divisor = pixeldistance ? pixeldistance : 1; - - saccum87 rdelta87 = rdistance87 / divisor; - saccum87 gdelta87 = gdistance87 / divisor; - saccum87 bdelta87 = bdistance87 / divisor; - - rdelta87 *= 2; - gdelta87 *= 2; - bdelta87 *= 2; - - accum88 r88 = startcolor.r << 8; - accum88 g88 = startcolor.g << 8; - accum88 b88 = startcolor.b << 8; - for( uint16_t i = startpos; i <= endpos; ++i) { - leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8); - r88 += rdelta87; - g88 += gdelta87; - b88 += bdelta87; - } -} - -#if 0 -void fill_gradient( const CHSV& c1, const CHSV& c2) -{ - fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2); -} - -void fill_gradient( const CHSV& c1, const CHSV& c2, const CHSV& c3) -{ - fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3); -} - -void fill_gradient( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) -{ - fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3, c4); -} - -void fill_gradient_RGB( const CRGB& c1, const CRGB& c2) -{ - fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2); -} - -void fill_gradient_RGB( const CRGB& c1, const CRGB& c2, const CRGB& c3) -{ - fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3); -} - -void fill_gradient_RGB( const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) -{ - fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3, c4); -} -#endif - - - - -void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2) -{ - uint16_t last = numLeds - 1; - fill_gradient_RGB( leds, 0, c1, last, c2); -} - - -void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2, const CRGB& c3) -{ - uint16_t half = (numLeds / 2); - uint16_t last = numLeds - 1; - fill_gradient_RGB( leds, 0, c1, half, c2); - fill_gradient_RGB( leds, half, c2, last, c3); -} - -void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) -{ - uint16_t onethird = (numLeds / 3); - uint16_t twothirds = ((numLeds * 2) / 3); - uint16_t last = numLeds - 1; - fill_gradient_RGB( leds, 0, c1, onethird, c2); - fill_gradient_RGB( leds, onethird, c2, twothirds, c3); - fill_gradient_RGB( leds, twothirds, c3, last, c4); -} - - - - -void nscale8_video( CRGB* leds, uint16_t num_leds, uint8_t scale) -{ - for( uint16_t i = 0; i < num_leds; ++i) { - leds[i].nscale8_video( scale); - } -} - -void fade_video(CRGB* leds, uint16_t num_leds, uint8_t fadeBy) -{ - nscale8_video( leds, num_leds, 255 - fadeBy); -} - -void fadeLightBy(CRGB* leds, uint16_t num_leds, uint8_t fadeBy) -{ - nscale8_video( leds, num_leds, 255 - fadeBy); -} - - -void fadeToBlackBy( CRGB* leds, uint16_t num_leds, uint8_t fadeBy) -{ - nscale8( leds, num_leds, 255 - fadeBy); -} - -void fade_raw( CRGB* leds, uint16_t num_leds, uint8_t fadeBy) -{ - nscale8( leds, num_leds, 255 - fadeBy); -} - -void nscale8_raw( CRGB* leds, uint16_t num_leds, uint8_t scale) -{ - nscale8( leds, num_leds, scale); -} - -void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale) -{ - for( uint16_t i = 0; i < num_leds; ++i) { - leds[i].nscale8( scale); - } -} - -void fadeUsingColor( CRGB* leds, uint16_t numLeds, const CRGB& colormask) -{ - uint8_t fr, fg, fb; - fr = colormask.r; - fg = colormask.g; - fb = colormask.b; - - for( uint16_t i = 0; i < numLeds; ++i) { - leds[i].r = scale8_LEAVING_R1_DIRTY( leds[i].r, fr); - leds[i].g = scale8_LEAVING_R1_DIRTY( leds[i].g, fg); - leds[i].b = scale8 ( leds[i].b, fb); - } -} - - -CRGB& nblend( CRGB& existing, const CRGB& overlay, fract8 amountOfOverlay ) -{ - if( amountOfOverlay == 0) { - return existing; - } - - if( amountOfOverlay == 255) { - existing = overlay; - return existing; - } - -#if 0 - // Old blend method which unfortunately had some rounding errors - fract8 amountOfKeep = 255 - amountOfOverlay; - - existing.red = scale8_LEAVING_R1_DIRTY( existing.red, amountOfKeep) - + scale8_LEAVING_R1_DIRTY( overlay.red, amountOfOverlay); - existing.green = scale8_LEAVING_R1_DIRTY( existing.green, amountOfKeep) - + scale8_LEAVING_R1_DIRTY( overlay.green, amountOfOverlay); - existing.blue = scale8_LEAVING_R1_DIRTY( existing.blue, amountOfKeep) - + scale8_LEAVING_R1_DIRTY( overlay.blue, amountOfOverlay); - - cleanup_R1(); -#else - // Corrected blend method, with no loss-of-precision rounding errors - existing.red = blend8( existing.red, overlay.red, amountOfOverlay); - existing.green = blend8( existing.green, overlay.green, amountOfOverlay); - existing.blue = blend8( existing.blue, overlay.blue, amountOfOverlay); -#endif - - return existing; -} - - - -void nblend( CRGB* existing, CRGB* overlay, uint16_t count, fract8 amountOfOverlay) -{ - for( uint16_t i = count; i; --i) { - nblend( *existing, *overlay, amountOfOverlay); - ++existing; - ++overlay; - } -} - -CRGB blend( const CRGB& p1, const CRGB& p2, fract8 amountOfP2 ) -{ - CRGB nu(p1); - nblend( nu, p2, amountOfP2); - return nu; -} - -CRGB* blend( const CRGB* src1, const CRGB* src2, CRGB* dest, uint16_t count, fract8 amountOfsrc2 ) -{ - for( uint16_t i = 0; i < count; ++i) { - dest[i] = blend(src1[i], src2[i], amountOfsrc2); - } - return dest; -} - - - -CHSV& nblend( CHSV& existing, const CHSV& overlay, fract8 amountOfOverlay, TGradientDirectionCode directionCode) -{ - if( amountOfOverlay == 0) { - return existing; - } - - if( amountOfOverlay == 255) { - existing = overlay; - return existing; - } - - fract8 amountOfKeep = 255 - amountOfOverlay; - - uint8_t huedelta8 = overlay.hue - existing.hue; - - if( directionCode == SHORTEST_HUES ) { - directionCode = FORWARD_HUES; - if( huedelta8 > 127) { - directionCode = BACKWARD_HUES; - } - } - - if( directionCode == LONGEST_HUES ) { - directionCode = FORWARD_HUES; - if( huedelta8 < 128) { - directionCode = BACKWARD_HUES; - } - } - - if( directionCode == FORWARD_HUES) { - existing.hue = existing.hue + scale8( huedelta8, amountOfOverlay); - } - else /* directionCode == BACKWARD_HUES */ - { - huedelta8 = -huedelta8; - existing.hue = existing.hue - scale8( huedelta8, amountOfOverlay); - } - - existing.sat = scale8_LEAVING_R1_DIRTY( existing.sat, amountOfKeep) - + scale8_LEAVING_R1_DIRTY( overlay.sat, amountOfOverlay); - existing.val = scale8_LEAVING_R1_DIRTY( existing.val, amountOfKeep) - + scale8_LEAVING_R1_DIRTY( overlay.val, amountOfOverlay); - - cleanup_R1(); - - return existing; -} - - - -void nblend( CHSV* existing, CHSV* overlay, uint16_t count, fract8 amountOfOverlay, TGradientDirectionCode directionCode ) -{ - if(existing == overlay) return; - for( uint16_t i = count; i; --i) { - nblend( *existing, *overlay, amountOfOverlay, directionCode); - ++existing; - ++overlay; - } -} - -CHSV blend( const CHSV& p1, const CHSV& p2, fract8 amountOfP2, TGradientDirectionCode directionCode ) -{ - CHSV nu(p1); - nblend( nu, p2, amountOfP2, directionCode); - return nu; -} - -CHSV* blend( const CHSV* src1, const CHSV* src2, CHSV* dest, uint16_t count, fract8 amountOfsrc2, TGradientDirectionCode directionCode ) -{ - for( uint16_t i = 0; i < count; ++i) { - dest[i] = blend(src1[i], src2[i], amountOfsrc2, directionCode); - } - return dest; -} - - - -// Forward declaration of the function "XY" which must be provided by -// the application for use in two-dimensional filter functions. -uint16_t XY( uint8_t, uint8_t);// __attribute__ ((weak)); - - -// blur1d: one-dimensional blur filter. Spreads light to 2 line neighbors. -// blur2d: two-dimensional blur filter. Spreads light to 8 XY neighbors. -// -// 0 = no spread at all -// 64 = moderate spreading -// 172 = maximum smooth, even spreading -// -// 173..255 = wider spreading, but increasing flicker -// -// Total light is NOT entirely conserved, so many repeated -// calls to 'blur' will also result in the light fading, -// eventually all the way to black; this is by design so that -// it can be used to (slowly) clear the LEDs to black. -void blur1d( CRGB* leds, uint16_t numLeds, fract8 blur_amount) -{ - uint8_t keep = 255 - blur_amount; - uint8_t seep = blur_amount >> 1; - CRGB carryover = CRGB::Black; - for( uint16_t i = 0; i < numLeds; ++i) { - CRGB cur = leds[i]; - CRGB part = cur; - part.nscale8( seep); - cur.nscale8( keep); - cur += carryover; - if( i) leds[i-1] += part; - leds[i] = cur; - carryover = part; - } -} - -void blur2d( CRGB* leds, uint8_t width, uint8_t height, fract8 blur_amount) -{ - blurRows(leds, width, height, blur_amount); - blurColumns(leds, width, height, blur_amount); -} - -// blurRows: perform a blur1d on every row of a rectangular matrix -void blurRows( CRGB* leds, uint8_t width, uint8_t height, fract8 blur_amount) -{ - for( uint8_t row = 0; row < height; ++row) { - CRGB* rowbase = leds + (row * width); - blur1d( rowbase, width, blur_amount); - } -} - -// blurColumns: perform a blur1d on each column of a rectangular matrix -void blurColumns(CRGB* leds, uint8_t width, uint8_t height, fract8 blur_amount) -{ - // blur columns - uint8_t keep = 255 - blur_amount; - uint8_t seep = blur_amount >> 1; - for( uint8_t col = 0; col < width; ++col) { - CRGB carryover = CRGB::Black; - for( uint8_t i = 0; i < height; ++i) { - CRGB cur = leds[XY(col,i)]; - CRGB part = cur; - part.nscale8( seep); - cur.nscale8( keep); - cur += carryover; - if( i) leds[XY(col,i-1)] += part; - leds[XY(col,i)] = cur; - carryover = part; - } - } -} - - - -// CRGB HeatColor( uint8_t temperature) -// -// Approximates a 'black body radiation' spectrum for -// a given 'heat' level. This is useful for animations of 'fire'. -// Heat is specified as an arbitrary scale from 0 (cool) to 255 (hot). -// This is NOT a chromatically correct 'black body radiation' -// spectrum, but it's surprisingly close, and it's fast and small. -// -// On AVR/Arduino, this typically takes around 70 bytes of program memory, -// versus 768 bytes for a full 256-entry RGB lookup table. - -CRGB HeatColor( uint8_t temperature) -{ - CRGB heatcolor; - - // Scale 'heat' down from 0-255 to 0-191, - // which can then be easily divided into three - // equal 'thirds' of 64 units each. - uint8_t t192 = scale8_video( temperature, 191); - - // calculate a value that ramps up from - // zero to 255 in each 'third' of the scale. - uint8_t heatramp = t192 & 0x3F; // 0..63 - heatramp <<= 2; // scale up to 0..252 - - // now figure out which third of the spectrum we're in: - if( t192 & 0x80) { - // we're in the hottest third - heatcolor.r = 255; // full red - heatcolor.g = 255; // full green - heatcolor.b = heatramp; // ramp up blue - - } else if( t192 & 0x40 ) { - // we're in the middle third - heatcolor.r = 255; // full red - heatcolor.g = heatramp; // ramp up green - heatcolor.b = 0; // no blue - - } else { - // we're in the coolest third - heatcolor.r = heatramp; // ramp up red - heatcolor.g = 0; // no green - heatcolor.b = 0; // no blue - } - - return heatcolor; -} - - -// lsrX4: helper function to divide a number by 16, aka four LSR's. -// On avr-gcc, "u8 >> 4" generates a loop, which is big, and slow. -// merely forcing it to be four /=2's causes avr-gcc to emit -// a SWAP instruction followed by an AND 0x0F, which is faster, and smaller. -inline uint8_t lsrX4( uint8_t dividend) __attribute__((always_inline)); -inline uint8_t lsrX4( uint8_t dividend) -{ -#if defined(__AVR__) - dividend /= 2; - dividend /= 2; - dividend /= 2; - dividend /= 2; -#else - dividend >>= 4; -#endif - return dividend; -} - - -CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType) -{ - // hi4 = index >> 4; - uint8_t hi4 = lsrX4(index); - uint8_t lo4 = index & 0x0F; - - // const CRGB* entry = &(pal[0]) + hi4; - // since hi4 is always 0..15, hi4 * sizeof(CRGB) can be a single-byte value, - // instead of the two byte 'int' that avr-gcc defaults to. - // So, we multiply hi4 X sizeof(CRGB), giving hi4XsizeofCRGB; - uint8_t hi4XsizeofCRGB = hi4 * sizeof(CRGB); - // We then add that to a base array pointer. - const CRGB* entry = (CRGB*)( (uint8_t*)(&(pal[0])) + hi4XsizeofCRGB); - - uint8_t blend = lo4 && (blendType != NOBLEND); - - uint8_t red1 = entry->red; - uint8_t green1 = entry->green; - uint8_t blue1 = entry->blue; - - - if( blend ) { - - if( hi4 == 15 ) { - entry = &(pal[0]); - } else { - ++entry; - } - - uint8_t f2 = lo4 << 4; - uint8_t f1 = 255 - f2; - - // rgb1.nscale8(f1); - uint8_t red2 = entry->red; - red1 = scale8_LEAVING_R1_DIRTY( red1, f1); - red2 = scale8_LEAVING_R1_DIRTY( red2, f2); - red1 += red2; - - uint8_t green2 = entry->green; - green1 = scale8_LEAVING_R1_DIRTY( green1, f1); - green2 = scale8_LEAVING_R1_DIRTY( green2, f2); - green1 += green2; - - uint8_t blue2 = entry->blue; - blue1 = scale8_LEAVING_R1_DIRTY( blue1, f1); - blue2 = scale8_LEAVING_R1_DIRTY( blue2, f2); - blue1 += blue2; - - cleanup_R1(); - } - - if( brightness != 255) { - if( brightness ) { - ++brightness; // adjust for rounding - // Now, since brightness is nonzero, we don't need the full scale8_video logic; - // we can just to scale8 and then add one (unless scale8 fixed) to all nonzero inputs. - if( red1 ) { - red1 = scale8_LEAVING_R1_DIRTY( red1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++red1; -#endif - } - if( green1 ) { - green1 = scale8_LEAVING_R1_DIRTY( green1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++green1; -#endif - } - if( blue1 ) { - blue1 = scale8_LEAVING_R1_DIRTY( blue1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++blue1; -#endif - } - cleanup_R1(); - } else { - red1 = 0; - green1 = 0; - blue1 = 0; - } - } - - return CRGB( red1, green1, blue1); -} - -CRGB ColorFromPalette( const TProgmemRGBPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType) -{ - // hi4 = index >> 4; - uint8_t hi4 = lsrX4(index); - uint8_t lo4 = index & 0x0F; - - CRGB entry = FL_PGM_READ_DWORD_NEAR( &(pal[0]) + hi4 ); - - - uint8_t red1 = entry.red; - uint8_t green1 = entry.green; - uint8_t blue1 = entry.blue; - - uint8_t blend = lo4 && (blendType != NOBLEND); - - if( blend ) { - - if( hi4 == 15 ) { - entry = FL_PGM_READ_DWORD_NEAR( &(pal[0]) ); - } else { - entry = FL_PGM_READ_DWORD_NEAR( &(pal[1]) + hi4 ); - } - - uint8_t f2 = lo4 << 4; - uint8_t f1 = 255 - f2; - - uint8_t red2 = entry.red; - red1 = scale8_LEAVING_R1_DIRTY( red1, f1); - red2 = scale8_LEAVING_R1_DIRTY( red2, f2); - red1 += red2; - - uint8_t green2 = entry.green; - green1 = scale8_LEAVING_R1_DIRTY( green1, f1); - green2 = scale8_LEAVING_R1_DIRTY( green2, f2); - green1 += green2; - - uint8_t blue2 = entry.blue; - blue1 = scale8_LEAVING_R1_DIRTY( blue1, f1); - blue2 = scale8_LEAVING_R1_DIRTY( blue2, f2); - blue1 += blue2; - - cleanup_R1(); - } - - if( brightness != 255) { - if( brightness ) { - ++brightness; // adjust for rounding - // Now, since brightness is nonzero, we don't need the full scale8_video logic; - // we can just to scale8 and then add one (unless scale8 fixed) to all nonzero inputs. - if( red1 ) { - red1 = scale8_LEAVING_R1_DIRTY( red1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++red1; -#endif - } - if( green1 ) { - green1 = scale8_LEAVING_R1_DIRTY( green1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++green1; -#endif - } - if( blue1 ) { - blue1 = scale8_LEAVING_R1_DIRTY( blue1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++blue1; -#endif - } - cleanup_R1(); - } else { - red1 = 0; - green1 = 0; - blue1 = 0; - } - } - - return CRGB( red1, green1, blue1); -} - - -CRGB ColorFromPalette( const CRGBPalette32& pal, uint8_t index, uint8_t brightness, TBlendType blendType) -{ - uint8_t hi5 = index; -#if defined(__AVR__) - hi5 /= 2; - hi5 /= 2; - hi5 /= 2; -#else - hi5 >>= 3; -#endif - uint8_t lo3 = index & 0x07; - - // const CRGB* entry = &(pal[0]) + hi5; - // since hi5 is always 0..31, hi4 * sizeof(CRGB) can be a single-byte value, - // instead of the two byte 'int' that avr-gcc defaults to. - // So, we multiply hi5 X sizeof(CRGB), giving hi5XsizeofCRGB; - uint8_t hi5XsizeofCRGB = hi5 * sizeof(CRGB); - // We then add that to a base array pointer. - const CRGB* entry = (CRGB*)( (uint8_t*)(&(pal[0])) + hi5XsizeofCRGB); - - uint8_t red1 = entry->red; - uint8_t green1 = entry->green; - uint8_t blue1 = entry->blue; - - uint8_t blend = lo3 && (blendType != NOBLEND); - - if( blend ) { - - if( hi5 == 31 ) { - entry = &(pal[0]); - } else { - ++entry; - } - - uint8_t f2 = lo3 << 5; - uint8_t f1 = 255 - f2; - - uint8_t red2 = entry->red; - red1 = scale8_LEAVING_R1_DIRTY( red1, f1); - red2 = scale8_LEAVING_R1_DIRTY( red2, f2); - red1 += red2; - - uint8_t green2 = entry->green; - green1 = scale8_LEAVING_R1_DIRTY( green1, f1); - green2 = scale8_LEAVING_R1_DIRTY( green2, f2); - green1 += green2; - - uint8_t blue2 = entry->blue; - blue1 = scale8_LEAVING_R1_DIRTY( blue1, f1); - blue2 = scale8_LEAVING_R1_DIRTY( blue2, f2); - blue1 += blue2; - - cleanup_R1(); - - } - - if( brightness != 255) { - if( brightness ) { - ++brightness; // adjust for rounding - // Now, since brightness is nonzero, we don't need the full scale8_video logic; - // we can just to scale8 and then add one (unless scale8 fixed) to all nonzero inputs. - if( red1 ) { - red1 = scale8_LEAVING_R1_DIRTY( red1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++red1; -#endif - } - if( green1 ) { - green1 = scale8_LEAVING_R1_DIRTY( green1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++green1; -#endif - } - if( blue1 ) { - blue1 = scale8_LEAVING_R1_DIRTY( blue1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++blue1; -#endif - } - cleanup_R1(); - } else { - red1 = 0; - green1 = 0; - blue1 = 0; - } - } - - return CRGB( red1, green1, blue1); -} - - -CRGB ColorFromPalette( const TProgmemRGBPalette32& pal, uint8_t index, uint8_t brightness, TBlendType blendType) -{ - uint8_t hi5 = index; -#if defined(__AVR__) - hi5 /= 2; - hi5 /= 2; - hi5 /= 2; -#else - hi5 >>= 3; -#endif - uint8_t lo3 = index & 0x07; - - CRGB entry = FL_PGM_READ_DWORD_NEAR( &(pal[0]) + hi5); - - uint8_t red1 = entry.red; - uint8_t green1 = entry.green; - uint8_t blue1 = entry.blue; - - uint8_t blend = lo3 && (blendType != NOBLEND); - - if( blend ) { - - if( hi5 == 31 ) { - entry = FL_PGM_READ_DWORD_NEAR( &(pal[0]) ); - } else { - entry = FL_PGM_READ_DWORD_NEAR( &(pal[1]) + hi5 ); - } - - uint8_t f2 = lo3 << 5; - uint8_t f1 = 255 - f2; - - uint8_t red2 = entry.red; - red1 = scale8_LEAVING_R1_DIRTY( red1, f1); - red2 = scale8_LEAVING_R1_DIRTY( red2, f2); - red1 += red2; - - uint8_t green2 = entry.green; - green1 = scale8_LEAVING_R1_DIRTY( green1, f1); - green2 = scale8_LEAVING_R1_DIRTY( green2, f2); - green1 += green2; - - uint8_t blue2 = entry.blue; - blue1 = scale8_LEAVING_R1_DIRTY( blue1, f1); - blue2 = scale8_LEAVING_R1_DIRTY( blue2, f2); - blue1 += blue2; - - cleanup_R1(); - } - - if( brightness != 255) { - if( brightness ) { - ++brightness; // adjust for rounding - // Now, since brightness is nonzero, we don't need the full scale8_video logic; - // we can just to scale8 and then add one (unless scale8 fixed) to all nonzero inputs. - if( red1 ) { - red1 = scale8_LEAVING_R1_DIRTY( red1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++red1; -#endif - } - if( green1 ) { - green1 = scale8_LEAVING_R1_DIRTY( green1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++green1; -#endif - } - if( blue1 ) { - blue1 = scale8_LEAVING_R1_DIRTY( blue1, brightness); -#if !(FASTLED_SCALE8_FIXED==1) - ++blue1; -#endif - } - cleanup_R1(); - } else { - red1 = 0; - green1 = 0; - blue1 = 0; - } - } - - return CRGB( red1, green1, blue1); -} - - - -CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightness, TBlendType) -{ - const CRGB* entry = &(pal[0]) + index; - - uint8_t red = entry->red; - uint8_t green = entry->green; - uint8_t blue = entry->blue; - - if( brightness != 255) { - ++brightness; // adjust for rounding - red = scale8_video_LEAVING_R1_DIRTY( red, brightness); - green = scale8_video_LEAVING_R1_DIRTY( green, brightness); - blue = scale8_video_LEAVING_R1_DIRTY( blue, brightness); - cleanup_R1(); - } - - return CRGB( red, green, blue); -} - - -CHSV ColorFromPalette( const struct CHSVPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType) -{ - // hi4 = index >> 4; - uint8_t hi4 = lsrX4(index); - uint8_t lo4 = index & 0x0F; - - // CRGB rgb1 = pal[ hi4]; - const CHSV* entry = &(pal[0]) + hi4; - - uint8_t hue1 = entry->hue; - uint8_t sat1 = entry->sat; - uint8_t val1 = entry->val; - - uint8_t blend = lo4 && (blendType != NOBLEND); - - if( blend ) { - - if( hi4 == 15 ) { - entry = &(pal[0]); - } else { - ++entry; - } - - uint8_t f2 = lo4 << 4; - uint8_t f1 = 255 - f2; - - uint8_t hue2 = entry->hue; - uint8_t sat2 = entry->sat; - uint8_t val2 = entry->val; - - // Now some special casing for blending to or from - // either black or white. Black and white don't have - // proper 'hue' of their own, so when ramping from - // something else to/from black/white, we set the 'hue' - // of the black/white color to be the same as the hue - // of the other color, so that you get the expected - // brightness or saturation ramp, with hue staying - // constant: - - // If we are starting from white (sat=0) - // or black (val=0), adopt the target hue. - if( sat1 == 0 || val1 == 0) { - hue1 = hue2; - } - - // If we are ending at white (sat=0) - // or black (val=0), adopt the starting hue. - if( sat2 == 0 || val2 == 0) { - hue2 = hue1; - } - - - sat1 = scale8_LEAVING_R1_DIRTY( sat1, f1); - val1 = scale8_LEAVING_R1_DIRTY( val1, f1); - - sat2 = scale8_LEAVING_R1_DIRTY( sat2, f2); - val2 = scale8_LEAVING_R1_DIRTY( val2, f2); - - // cleanup_R1(); - - // These sums can't overflow, so no qadd8 needed. - sat1 += sat2; - val1 += val2; - - uint8_t deltaHue = (uint8_t)(hue2 - hue1); - if( deltaHue & 0x80 ) { - // go backwards - hue1 -= scale8( 256 - deltaHue, f2); - } else { - // go forwards - hue1 += scale8( deltaHue, f2); - } - - cleanup_R1(); - } - - if( brightness != 255) { - val1 = scale8_video( val1, brightness); - } - - return CHSV( hue1, sat1, val1); -} - - -CHSV ColorFromPalette( const struct CHSVPalette32& pal, uint8_t index, uint8_t brightness, TBlendType blendType) -{ - uint8_t hi5 = index; -#if defined(__AVR__) - hi5 /= 2; - hi5 /= 2; - hi5 /= 2; -#else - hi5 >>= 3; -#endif - uint8_t lo3 = index & 0x07; - - uint8_t hi5XsizeofCHSV = hi5 * sizeof(CHSV); - const CHSV* entry = (CHSV*)( (uint8_t*)(&(pal[0])) + hi5XsizeofCHSV); - - uint8_t hue1 = entry->hue; - uint8_t sat1 = entry->sat; - uint8_t val1 = entry->val; - - uint8_t blend = lo3 && (blendType != NOBLEND); - - if( blend ) { - - if( hi5 == 31 ) { - entry = &(pal[0]); - } else { - ++entry; - } - - uint8_t f2 = lo3 << 5; - uint8_t f1 = 255 - f2; - - uint8_t hue2 = entry->hue; - uint8_t sat2 = entry->sat; - uint8_t val2 = entry->val; - - // Now some special casing for blending to or from - // either black or white. Black and white don't have - // proper 'hue' of their own, so when ramping from - // something else to/from black/white, we set the 'hue' - // of the black/white color to be the same as the hue - // of the other color, so that you get the expected - // brightness or saturation ramp, with hue staying - // constant: - - // If we are starting from white (sat=0) - // or black (val=0), adopt the target hue. - if( sat1 == 0 || val1 == 0) { - hue1 = hue2; - } - - // If we are ending at white (sat=0) - // or black (val=0), adopt the starting hue. - if( sat2 == 0 || val2 == 0) { - hue2 = hue1; - } - - - sat1 = scale8_LEAVING_R1_DIRTY( sat1, f1); - val1 = scale8_LEAVING_R1_DIRTY( val1, f1); - - sat2 = scale8_LEAVING_R1_DIRTY( sat2, f2); - val2 = scale8_LEAVING_R1_DIRTY( val2, f2); - - // cleanup_R1(); - - // These sums can't overflow, so no qadd8 needed. - sat1 += sat2; - val1 += val2; - - uint8_t deltaHue = (uint8_t)(hue2 - hue1); - if( deltaHue & 0x80 ) { - // go backwards - hue1 -= scale8( 256 - deltaHue, f2); - } else { - // go forwards - hue1 += scale8( deltaHue, f2); - } - - cleanup_R1(); - } - - if( brightness != 255) { - val1 = scale8_video( val1, brightness); - } - - return CHSV( hue1, sat1, val1); -} - -CHSV ColorFromPalette( const struct CHSVPalette256& pal, uint8_t index, uint8_t brightness, TBlendType) -{ - CHSV hsv = *( &(pal[0]) + index ); - - if( brightness != 255) { - hsv.value = scale8_video( hsv.value, brightness); - } - - return hsv; -} - - -void UpscalePalette(const struct CRGBPalette16& srcpal16, struct CRGBPalette256& destpal256) -{ - for( int i = 0; i < 256; ++i) { - destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i); - } -} - -void UpscalePalette(const struct CHSVPalette16& srcpal16, struct CHSVPalette256& destpal256) -{ - for( int i = 0; i < 256; ++i) { - destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i); - } -} - - -void UpscalePalette(const struct CRGBPalette16& srcpal16, struct CRGBPalette32& destpal32) -{ - for( uint8_t i = 0; i < 16; ++i) { - uint8_t j = i * 2; - destpal32[j+0] = srcpal16[i]; - destpal32[j+1] = srcpal16[i]; - } -} - -void UpscalePalette(const struct CHSVPalette16& srcpal16, struct CHSVPalette32& destpal32) -{ - for( uint8_t i = 0; i < 16; ++i) { - uint8_t j = i * 2; - destpal32[j+0] = srcpal16[i]; - destpal32[j+1] = srcpal16[i]; - } -} - -void UpscalePalette(const struct CRGBPalette32& srcpal32, struct CRGBPalette256& destpal256) -{ - for( int i = 0; i < 256; ++i) { - destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal32, i); - } -} - -void UpscalePalette(const struct CHSVPalette32& srcpal32, struct CHSVPalette256& destpal256) -{ - for( int i = 0; i < 256; ++i) { - destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal32, i); - } -} - - - -#if 0 -// replaced by PartyColors_p -void SetupPartyColors(CRGBPalette16& pal) -{ - fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 18,255,255), FORWARD_HUES); - fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 18,255,255), BACKWARD_HUES); -} -#endif - - -void nblendPaletteTowardPalette( CRGBPalette16& current, CRGBPalette16& target, uint8_t maxChanges) -{ - uint8_t* p1; - uint8_t* p2; - uint8_t changes = 0; - - p1 = (uint8_t*)current.entries; - p2 = (uint8_t*)target.entries; - - const uint8_t totalChannels = sizeof(CRGBPalette16); - for( uint8_t i = 0; i < totalChannels; ++i) { - // if the values are equal, no changes are needed - if( p1[i] == p2[i] ) { continue; } - - // if the current value is less than the target, increase it by one - if( p1[i] < p2[i] ) { ++p1[i]; ++changes; } - - // if the current value is greater than the target, - // increase it by one (or two if it's still greater). - if( p1[i] > p2[i] ) { - --p1[i]; ++changes; - if( p1[i] > p2[i] ) { --p1[i]; } - } - - // if we've hit the maximum number of changes, exit - if( changes >= maxChanges) { break; } - } -} - - -uint8_t applyGamma_video( uint8_t brightness, float gamma) -{ - float orig; - float adj; - orig = (float)(brightness) / (255.0); - adj = pow( orig, gamma) * (255.0); - uint8_t result = (uint8_t)(adj); - if( (brightness > 0) && (result == 0)) { - result = 1; // never gamma-adjust a positive number down to zero - } - return result; -} - -CRGB applyGamma_video( const CRGB& orig, float gamma) -{ - CRGB adj; - adj.r = applyGamma_video( orig.r, gamma); - adj.g = applyGamma_video( orig.g, gamma); - adj.b = applyGamma_video( orig.b, gamma); - return adj; -} - -CRGB applyGamma_video( const CRGB& orig, float gammaR, float gammaG, float gammaB) -{ - CRGB adj; - adj.r = applyGamma_video( orig.r, gammaR); - adj.g = applyGamma_video( orig.g, gammaG); - adj.b = applyGamma_video( orig.b, gammaB); - return adj; -} - -CRGB& napplyGamma_video( CRGB& rgb, float gamma) -{ - rgb = applyGamma_video( rgb, gamma); - return rgb; -} - -CRGB& napplyGamma_video( CRGB& rgb, float gammaR, float gammaG, float gammaB) -{ - rgb = applyGamma_video( rgb, gammaR, gammaG, gammaB); - return rgb; -} - -void napplyGamma_video( CRGB* rgbarray, uint16_t count, float gamma) -{ - for( uint16_t i = 0; i < count; ++i) { - rgbarray[i] = applyGamma_video( rgbarray[i], gamma); - } -} - -void napplyGamma_video( CRGB* rgbarray, uint16_t count, float gammaR, float gammaG, float gammaB) -{ - for( uint16_t i = 0; i < count; ++i) { - rgbarray[i] = applyGamma_video( rgbarray[i], gammaR, gammaG, gammaB); - } -} - - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/colorutils.h b/FastLED/src/colorutils.h deleted file mode 100644 index f09d525fe743816164b9ca374971ad1ec2cb7cf7..0000000000000000000000000000000000000000 --- a/FastLED/src/colorutils.h +++ /dev/null @@ -1,1706 +0,0 @@ -#ifndef __INC_COLORUTILS_H -#define __INC_COLORUTILS_H - -///@file colorutils.h -/// functions for color fill, paletters, blending, and more - -#include "FastLED.h" -#include "pixeltypes.h" -#include "fastled_progmem.h" - -FASTLED_NAMESPACE_BEGIN -///@defgroup Colorutils Color utility functions -///A variety of functions for working with color, palletes, and leds -///@{ - -/// fill_solid - fill a range of LEDs with a solid color -/// Example: fill_solid( leds, NUM_LEDS, CRGB(50,0,200)); -void fill_solid( struct CRGB * leds, int numToFill, - const struct CRGB& color); - -/// fill_solid - fill a range of LEDs with a solid color -/// Example: fill_solid( leds, NUM_LEDS, CRGB(50,0,200)); -void fill_solid( struct CHSV* targetArray, int numToFill, - const struct CHSV& hsvColor); - - -/// fill_rainbow - fill a range of LEDs with a rainbow of colors, at -/// full saturation and full value (brightness) -void fill_rainbow( struct CRGB * pFirstLED, int numToFill, - uint8_t initialhue, - uint8_t deltahue = 5); - -/// fill_rainbow - fill a range of LEDs with a rainbow of colors, at -/// full saturation and full value (brightness) -void fill_rainbow( struct CHSV * targetArray, int numToFill, - uint8_t initialhue, - uint8_t deltahue = 5); - - -// fill_gradient - fill an array of colors with a smooth HSV gradient -// between two specified HSV colors. -// Since 'hue' is a value around a color wheel, -// there are always two ways to sweep from one hue -// to another. -// This function lets you specify which way you want -// the hue gradient to sweep around the color wheel: -// FORWARD_HUES: hue always goes clockwise -// BACKWARD_HUES: hue always goes counter-clockwise -// SHORTEST_HUES: hue goes whichever way is shortest -// LONGEST_HUES: hue goes whichever way is longest -// The default is SHORTEST_HUES, as this is nearly -// always what is wanted. -// -// fill_gradient can write the gradient colors EITHER -// (1) into an array of CRGBs (e.g., into leds[] array, or an RGB Palette) -// OR -// (2) into an array of CHSVs (e.g. an HSV Palette). -// -// In the case of writing into a CRGB array, the gradient is -// computed in HSV space, and then HSV values are converted to RGB -// as they're written into the RGB array. - -typedef enum { FORWARD_HUES, BACKWARD_HUES, SHORTEST_HUES, LONGEST_HUES } TGradientDirectionCode; - - - -#define saccum87 int16_t - -/// fill_gradient - fill an array of colors with a smooth HSV gradient -/// between two specified HSV colors. -/// Since 'hue' is a value around a color wheel, -/// there are always two ways to sweep from one hue -/// to another. -/// This function lets you specify which way you want -/// the hue gradient to sweep around the color wheel: -/// -/// FORWARD_HUES: hue always goes clockwise -/// BACKWARD_HUES: hue always goes counter-clockwise -/// SHORTEST_HUES: hue goes whichever way is shortest -/// LONGEST_HUES: hue goes whichever way is longest -/// -/// The default is SHORTEST_HUES, as this is nearly -/// always what is wanted. -/// -/// fill_gradient can write the gradient colors EITHER -/// (1) into an array of CRGBs (e.g., into leds[] array, or an RGB Palette) -/// OR -/// (2) into an array of CHSVs (e.g. an HSV Palette). -/// -/// In the case of writing into a CRGB array, the gradient is -/// computed in HSV space, and then HSV values are converted to RGB -/// as they're written into the RGB array. -template <typename T> -void fill_gradient( T* targetArray, - uint16_t startpos, CHSV startcolor, - uint16_t endpos, CHSV endcolor, - TGradientDirectionCode directionCode = SHORTEST_HUES ) -{ - // if the points are in the wrong order, straighten them - if( endpos < startpos ) { - uint16_t t = endpos; - CHSV tc = endcolor; - endcolor = startcolor; - endpos = startpos; - startpos = t; - startcolor = tc; - } - - // If we're fading toward black (val=0) or white (sat=0), - // then set the endhue to the starthue. - // This lets us ramp smoothly to black or white, regardless - // of what 'hue' was set in the endcolor (since it doesn't matter) - if( endcolor.value == 0 || endcolor.saturation == 0) { - endcolor.hue = startcolor.hue; - } - - // Similarly, if we're fading in from black (val=0) or white (sat=0) - // then set the starthue to the endhue. - // This lets us ramp smoothly up from black or white, regardless - // of what 'hue' was set in the startcolor (since it doesn't matter) - if( startcolor.value == 0 || startcolor.saturation == 0) { - startcolor.hue = endcolor.hue; - } - - saccum87 huedistance87; - saccum87 satdistance87; - saccum87 valdistance87; - - satdistance87 = (endcolor.sat - startcolor.sat) << 7; - valdistance87 = (endcolor.val - startcolor.val) << 7; - - uint8_t huedelta8 = endcolor.hue - startcolor.hue; - - if( directionCode == SHORTEST_HUES ) { - directionCode = FORWARD_HUES; - if( huedelta8 > 127) { - directionCode = BACKWARD_HUES; - } - } - - if( directionCode == LONGEST_HUES ) { - directionCode = FORWARD_HUES; - if( huedelta8 < 128) { - directionCode = BACKWARD_HUES; - } - } - - if( directionCode == FORWARD_HUES) { - huedistance87 = huedelta8 << 7; - } - else /* directionCode == BACKWARD_HUES */ - { - huedistance87 = (uint8_t)(256 - huedelta8) << 7; - huedistance87 = -huedistance87; - } - - uint16_t pixeldistance = endpos - startpos; - int16_t divisor = pixeldistance ? pixeldistance : 1; - - saccum87 huedelta87 = huedistance87 / divisor; - saccum87 satdelta87 = satdistance87 / divisor; - saccum87 valdelta87 = valdistance87 / divisor; - - huedelta87 *= 2; - satdelta87 *= 2; - valdelta87 *= 2; - - accum88 hue88 = startcolor.hue << 8; - accum88 sat88 = startcolor.sat << 8; - accum88 val88 = startcolor.val << 8; - for( uint16_t i = startpos; i <= endpos; ++i) { - targetArray[i] = CHSV( hue88 >> 8, sat88 >> 8, val88 >> 8); - hue88 += huedelta87; - sat88 += satdelta87; - val88 += valdelta87; - } -} - - -// Convenience functions to fill an array of colors with a -// two-color, three-color, or four-color gradient -template <typename T> -void fill_gradient( T* targetArray, uint16_t numLeds, const CHSV& c1, const CHSV& c2, - TGradientDirectionCode directionCode = SHORTEST_HUES ) -{ - uint16_t last = numLeds - 1; - fill_gradient( targetArray, 0, c1, last, c2, directionCode); -} - -template <typename T> -void fill_gradient( T* targetArray, uint16_t numLeds, - const CHSV& c1, const CHSV& c2, const CHSV& c3, - TGradientDirectionCode directionCode = SHORTEST_HUES ) -{ - uint16_t half = (numLeds / 2); - uint16_t last = numLeds - 1; - fill_gradient( targetArray, 0, c1, half, c2, directionCode); - fill_gradient( targetArray, half, c2, last, c3, directionCode); -} - -template <typename T> -void fill_gradient( T* targetArray, uint16_t numLeds, - const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4, - TGradientDirectionCode directionCode = SHORTEST_HUES ) -{ - uint16_t onethird = (numLeds / 3); - uint16_t twothirds = ((numLeds * 2) / 3); - uint16_t last = numLeds - 1; - fill_gradient( targetArray, 0, c1, onethird, c2, directionCode); - fill_gradient( targetArray, onethird, c2, twothirds, c3, directionCode); - fill_gradient( targetArray, twothirds, c3, last, c4, directionCode); -} - -// convenience synonym -#define fill_gradient_HSV fill_gradient - - -// fill_gradient_RGB - fill a range of LEDs with a smooth RGB gradient -// between two specified RGB colors. -// Unlike HSV, there is no 'color wheel' in RGB space, -// and therefore there's only one 'direction' for the -// gradient to go, and no 'direction code' is needed. -void fill_gradient_RGB( CRGB* leds, - uint16_t startpos, CRGB startcolor, - uint16_t endpos, CRGB endcolor ); -void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2); -void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2, const CRGB& c3); -void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4); - - -// fadeLightBy and fade_video - reduce the brightness of an array -// of pixels all at once. Guaranteed -// to never fade all the way to black. -// (The two names are synonyms.) -void fadeLightBy( CRGB* leds, uint16_t num_leds, uint8_t fadeBy); -void fade_video( CRGB* leds, uint16_t num_leds, uint8_t fadeBy); - -// nscale8_video - scale down the brightness of an array of pixels -// all at once. Guaranteed to never scale a pixel -// all the way down to black, unless 'scale' is zero. -void nscale8_video( CRGB* leds, uint16_t num_leds, uint8_t scale); - -// fadeToBlackBy and fade_raw - reduce the brightness of an array -// of pixels all at once. These -// functions will eventually fade all -// the way to black. -// (The two names are synonyms.) -void fadeToBlackBy( CRGB* leds, uint16_t num_leds, uint8_t fadeBy); -void fade_raw( CRGB* leds, uint16_t num_leds, uint8_t fadeBy); - -// nscale8 - scale down the brightness of an array of pixels -// all at once. This function can scale pixels all the -// way down to black even if 'scale' is not zero. -void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale); - -// fadeUsingColor - scale down the brightness of an array of pixels, -// as though it were seen through a transparent -// filter with the specified color. -// For example, if the colormask is -// CRGB( 200, 100, 50) -// then the pixels' red will be faded to 200/256ths, -// their green to 100/256ths, and their blue to 50/256ths. -// This particular example give a 'hot fade' look, -// with white fading to yellow, then red, then black. -// You can also use colormasks like CRGB::Blue to -// zero out the red and green elements, leaving blue -// (largely) the same. -void fadeUsingColor( CRGB* leds, uint16_t numLeds, const CRGB& colormask); - - -// Pixel blending -// -// blend - computes a new color blended some fraction of the way -// between two other colors. -CRGB blend( const CRGB& p1, const CRGB& p2, fract8 amountOfP2 ); - -CHSV blend( const CHSV& p1, const CHSV& p2, fract8 amountOfP2, - TGradientDirectionCode directionCode = SHORTEST_HUES ); - -// blend - computes a new color blended array of colors, each -// a given fraction of the way between corresponding -// elements of two source arrays of colors. -// Useful for blending palettes. -CRGB* blend( const CRGB* src1, const CRGB* src2, CRGB* dest, - uint16_t count, fract8 amountOfsrc2 ); - -CHSV* blend( const CHSV* src1, const CHSV* src2, CHSV* dest, - uint16_t count, fract8 amountOfsrc2, - TGradientDirectionCode directionCode = SHORTEST_HUES ); - -// nblend - destructively modifies one color, blending -// in a given fraction of an overlay color -CRGB& nblend( CRGB& existing, const CRGB& overlay, fract8 amountOfOverlay ); - -CHSV& nblend( CHSV& existing, const CHSV& overlay, fract8 amountOfOverlay, - TGradientDirectionCode directionCode = SHORTEST_HUES ); - -// nblend - destructively blends a given fraction of -// a new color array into an existing color array -void nblend( CRGB* existing, CRGB* overlay, uint16_t count, fract8 amountOfOverlay); - -void nblend( CHSV* existing, CHSV* overlay, uint16_t count, fract8 amountOfOverlay, - TGradientDirectionCode directionCode = SHORTEST_HUES); - - -// blur1d: one-dimensional blur filter. Spreads light to 2 line neighbors. -// blur2d: two-dimensional blur filter. Spreads light to 8 XY neighbors. -// -// 0 = no spread at all -// 64 = moderate spreading -// 172 = maximum smooth, even spreading -// -// 173..255 = wider spreading, but increasing flicker -// -// Total light is NOT entirely conserved, so many repeated -// calls to 'blur' will also result in the light fading, -// eventually all the way to black; this is by design so that -// it can be used to (slowly) clear the LEDs to black. -void blur1d( CRGB* leds, uint16_t numLeds, fract8 blur_amount); -void blur2d( CRGB* leds, uint8_t width, uint8_t height, fract8 blur_amount); - -// blurRows: perform a blur1d on every row of a rectangular matrix -void blurRows( CRGB* leds, uint8_t width, uint8_t height, fract8 blur_amount); -// blurColumns: perform a blur1d on each column of a rectangular matrix -void blurColumns(CRGB* leds, uint8_t width, uint8_t height, fract8 blur_amount); - - -// CRGB HeatColor( uint8_t temperature) -// -// Approximates a 'black body radiation' spectrum for -// a given 'heat' level. This is useful for animations of 'fire'. -// Heat is specified as an arbitrary scale from 0 (cool) to 255 (hot). -// This is NOT a chromatically correct 'black body radiation' -// spectrum, but it's surprisingly close, and it's fast and small. -CRGB HeatColor( uint8_t temperature); - - -// Palettes -// -// RGB Palettes map an 8-bit value (0..255) to an RGB color. -// -// You can create any color palette you wish; a couple of starters -// are provided: Forest, Clouds, Lava, Ocean, Rainbow, and Rainbow Stripes. -// -// Palettes come in the traditional 256-entry variety, which take -// up 768 bytes of RAM, and lightweight 16-entry varieties. The 16-entry -// variety automatically interpolates between its entries to produce -// a full 256-element color map, but at a cost of only 48 bytes or RAM. -// -// Basic operation is like this: (example shows the 16-entry variety) -// 1. Declare your palette storage: -// CRGBPalette16 myPalette; -// -// 2. Fill myPalette with your own 16 colors, or with a preset color scheme. -// You can specify your 16 colors a variety of ways: -// CRGBPalette16 myPalette( -// CRGB::Black, -// CRGB::Black, -// CRGB::Red, -// CRGB::Yellow, -// CRGB::Green, -// CRGB::Blue, -// CRGB::Purple, -// CRGB::Black, -// -// 0x100000, -// 0x200000, -// 0x400000, -// 0x800000, -// -// CHSV( 30,255,255), -// CHSV( 50,255,255), -// CHSV( 70,255,255), -// CHSV( 90,255,255) -// ); -// -// Or you can initiaize your palette with a preset color scheme: -// myPalette = RainbowStripesColors_p; -// -// 3. Any time you want to set a pixel to a color from your palette, use -// "ColorFromPalette(...)" as shown: -// -// uint8_t index = /* any value 0..255 */; -// leds[i] = ColorFromPalette( myPalette, index); -// -// Even though your palette has only 16 explicily defined entries, you -// can use an 'index' from 0..255. The 16 explicit palette entries will -// be spread evenly across the 0..255 range, and the intermedate values -// will be RGB-interpolated between adjacent explicit entries. -// -// It's easier to use than it sounds. -// - -class CRGBPalette16; -class CRGBPalette32; -class CRGBPalette256; -class CHSVPalette16; -class CHSVPalette32; -class CHSVPalette256; -typedef uint32_t TProgmemRGBPalette16[16]; -typedef uint32_t TProgmemHSVPalette16[16]; -#define TProgmemPalette16 TProgmemRGBPalette16 -typedef uint32_t TProgmemRGBPalette32[32]; -typedef uint32_t TProgmemHSVPalette32[32]; -#define TProgmemPalette32 TProgmemRGBPalette32 - -typedef const uint8_t TProgmemRGBGradientPalette_byte ; -typedef const TProgmemRGBGradientPalette_byte *TProgmemRGBGradientPalette_bytes; -typedef TProgmemRGBGradientPalette_bytes TProgmemRGBGradientPalettePtr; -typedef union { - struct { - uint8_t index; - uint8_t r; - uint8_t g; - uint8_t b; - }; - uint32_t dword; - uint8_t bytes[4]; -} TRGBGradientPaletteEntryUnion; - -typedef uint8_t TDynamicRGBGradientPalette_byte ; -typedef const TDynamicRGBGradientPalette_byte *TDynamicRGBGradientPalette_bytes; -typedef TDynamicRGBGradientPalette_bytes TDynamicRGBGradientPalettePtr; - -// Convert a 16-entry palette to a 256-entry palette -void UpscalePalette(const struct CRGBPalette16& srcpal16, struct CRGBPalette256& destpal256); -void UpscalePalette(const struct CHSVPalette16& srcpal16, struct CHSVPalette256& destpal256); - -// Convert a 16-entry palette to a 32-entry palette -void UpscalePalette(const struct CRGBPalette16& srcpal16, struct CRGBPalette32& destpal32); -void UpscalePalette(const struct CHSVPalette16& srcpal16, struct CHSVPalette32& destpal32); - -// Convert a 32-entry palette to a 256-entry palette -void UpscalePalette(const struct CRGBPalette32& srcpal32, struct CRGBPalette256& destpal256); -void UpscalePalette(const struct CHSVPalette32& srcpal32, struct CHSVPalette256& destpal256); - - -class CHSVPalette16 { -public: - CHSV entries[16]; - CHSVPalette16() {}; - CHSVPalette16( const CHSV& c00,const CHSV& c01,const CHSV& c02,const CHSV& c03, - const CHSV& c04,const CHSV& c05,const CHSV& c06,const CHSV& c07, - const CHSV& c08,const CHSV& c09,const CHSV& c10,const CHSV& c11, - const CHSV& c12,const CHSV& c13,const CHSV& c14,const CHSV& c15 ) - { - entries[0]=c00; entries[1]=c01; entries[2]=c02; entries[3]=c03; - entries[4]=c04; entries[5]=c05; entries[6]=c06; entries[7]=c07; - entries[8]=c08; entries[9]=c09; entries[10]=c10; entries[11]=c11; - entries[12]=c12; entries[13]=c13; entries[14]=c14; entries[15]=c15; - }; - - CHSVPalette16( const CHSVPalette16& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - } - CHSVPalette16& operator=( const CHSVPalette16& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - return *this; - } - - CHSVPalette16( const TProgmemHSVPalette16& rhs) - { - for( uint8_t i = 0; i < 16; ++i) { - CRGB xyz = FL_PGM_READ_DWORD_NEAR( rhs + i); - entries[i].hue = xyz.red; - entries[i].sat = xyz.green; - entries[i].val = xyz.blue; - } - } - CHSVPalette16& operator=( const TProgmemHSVPalette16& rhs) - { - for( uint8_t i = 0; i < 16; ++i) { - CRGB xyz = FL_PGM_READ_DWORD_NEAR( rhs + i); - entries[i].hue = xyz.red; - entries[i].sat = xyz.green; - entries[i].val = xyz.blue; - } - return *this; - } - - inline CHSV& operator[] (uint8_t x) __attribute__((always_inline)) - { - return entries[x]; - } - inline const CHSV& operator[] (uint8_t x) const __attribute__((always_inline)) - { - return entries[x]; - } - - inline CHSV& operator[] (int x) __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - inline const CHSV& operator[] (int x) const __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - - operator CHSV*() - { - return &(entries[0]); - } - - bool operator==( const CHSVPalette16 rhs) - { - const uint8_t* p = (const uint8_t*)(&(this->entries[0])); - const uint8_t* q = (const uint8_t*)(&(rhs.entries[0])); - if( p == q) return true; - for( uint8_t i = 0; i < (sizeof( entries)); ++i) { - if( *p != *q) return false; - ++p; - ++q; - } - return true; - } - bool operator!=( const CHSVPalette16 rhs) - { - return !( *this == rhs); - } - - CHSVPalette16( const CHSV& c1) - { - fill_solid( &(entries[0]), 16, c1); - } - CHSVPalette16( const CHSV& c1, const CHSV& c2) - { - fill_gradient( &(entries[0]), 16, c1, c2); - } - CHSVPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3) - { - fill_gradient( &(entries[0]), 16, c1, c2, c3); - } - CHSVPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) - { - fill_gradient( &(entries[0]), 16, c1, c2, c3, c4); - } - -}; - -class CHSVPalette256 { -public: - CHSV entries[256]; - CHSVPalette256() {}; - CHSVPalette256( const CHSV& c00,const CHSV& c01,const CHSV& c02,const CHSV& c03, - const CHSV& c04,const CHSV& c05,const CHSV& c06,const CHSV& c07, - const CHSV& c08,const CHSV& c09,const CHSV& c10,const CHSV& c11, - const CHSV& c12,const CHSV& c13,const CHSV& c14,const CHSV& c15 ) - { - CHSVPalette16 p16(c00,c01,c02,c03,c04,c05,c06,c07, - c08,c09,c10,c11,c12,c13,c14,c15); - *this = p16; - }; - - CHSVPalette256( const CHSVPalette256& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - } - CHSVPalette256& operator=( const CHSVPalette256& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - return *this; - } - - CHSVPalette256( const CHSVPalette16& rhs16) - { - UpscalePalette( rhs16, *this); - } - CHSVPalette256& operator=( const CHSVPalette16& rhs16) - { - UpscalePalette( rhs16, *this); - return *this; - } - - CHSVPalette256( const TProgmemRGBPalette16& rhs) - { - CHSVPalette16 p16(rhs); - *this = p16; - } - CHSVPalette256& operator=( const TProgmemRGBPalette16& rhs) - { - CHSVPalette16 p16(rhs); - *this = p16; - return *this; - } - - inline CHSV& operator[] (uint8_t x) __attribute__((always_inline)) - { - return entries[x]; - } - inline const CHSV& operator[] (uint8_t x) const __attribute__((always_inline)) - { - return entries[x]; - } - - inline CHSV& operator[] (int x) __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - inline const CHSV& operator[] (int x) const __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - - operator CHSV*() - { - return &(entries[0]); - } - - bool operator==( const CHSVPalette256 rhs) - { - const uint8_t* p = (const uint8_t*)(&(this->entries[0])); - const uint8_t* q = (const uint8_t*)(&(rhs.entries[0])); - if( p == q) return true; - for( uint16_t i = 0; i < (sizeof( entries)); ++i) { - if( *p != *q) return false; - ++p; - ++q; - } - return true; - } - bool operator!=( const CHSVPalette256 rhs) - { - return !( *this == rhs); - } - - CHSVPalette256( const CHSV& c1) - { - fill_solid( &(entries[0]), 256, c1); - } - CHSVPalette256( const CHSV& c1, const CHSV& c2) - { - fill_gradient( &(entries[0]), 256, c1, c2); - } - CHSVPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3) - { - fill_gradient( &(entries[0]), 256, c1, c2, c3); - } - CHSVPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) - { - fill_gradient( &(entries[0]), 256, c1, c2, c3, c4); - } -}; - -class CRGBPalette16 { -public: - CRGB entries[16]; - CRGBPalette16() {}; - CRGBPalette16( const CRGB& c00,const CRGB& c01,const CRGB& c02,const CRGB& c03, - const CRGB& c04,const CRGB& c05,const CRGB& c06,const CRGB& c07, - const CRGB& c08,const CRGB& c09,const CRGB& c10,const CRGB& c11, - const CRGB& c12,const CRGB& c13,const CRGB& c14,const CRGB& c15 ) - { - entries[0]=c00; entries[1]=c01; entries[2]=c02; entries[3]=c03; - entries[4]=c04; entries[5]=c05; entries[6]=c06; entries[7]=c07; - entries[8]=c08; entries[9]=c09; entries[10]=c10; entries[11]=c11; - entries[12]=c12; entries[13]=c13; entries[14]=c14; entries[15]=c15; - }; - - CRGBPalette16( const CRGBPalette16& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - } - CRGBPalette16( const CRGB rhs[16]) - { - memmove8( (void *) &(entries[0]), &(rhs[0]), sizeof( entries)); - } - CRGBPalette16& operator=( const CRGBPalette16& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - return *this; - } - CRGBPalette16& operator=( const CRGB rhs[16]) - { - memmove8( (void *) &(entries[0]), &(rhs[0]), sizeof( entries)); - return *this; - } - - CRGBPalette16( const CHSVPalette16& rhs) - { - for( uint8_t i = 0; i < 16; ++i) { - entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion - } - } - CRGBPalette16( const CHSV rhs[16]) - { - for( uint8_t i = 0; i < 16; ++i) { - entries[i] = rhs[i]; // implicit HSV-to-RGB conversion - } - } - CRGBPalette16& operator=( const CHSVPalette16& rhs) - { - for( uint8_t i = 0; i < 16; ++i) { - entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion - } - return *this; - } - CRGBPalette16& operator=( const CHSV rhs[16]) - { - for( uint8_t i = 0; i < 16; ++i) { - entries[i] = rhs[i]; // implicit HSV-to-RGB conversion - } - return *this; - } - - CRGBPalette16( const TProgmemRGBPalette16& rhs) - { - for( uint8_t i = 0; i < 16; ++i) { - entries[i] = FL_PGM_READ_DWORD_NEAR( rhs + i); - } - } - CRGBPalette16& operator=( const TProgmemRGBPalette16& rhs) - { - for( uint8_t i = 0; i < 16; ++i) { - entries[i] = FL_PGM_READ_DWORD_NEAR( rhs + i); - } - return *this; - } - - bool operator==( const CRGBPalette16 rhs) - { - const uint8_t* p = (const uint8_t*)(&(this->entries[0])); - const uint8_t* q = (const uint8_t*)(&(rhs.entries[0])); - if( p == q) return true; - for( uint8_t i = 0; i < (sizeof( entries)); ++i) { - if( *p != *q) return false; - ++p; - ++q; - } - return true; - } - bool operator!=( const CRGBPalette16 rhs) - { - return !( *this == rhs); - } - - inline CRGB& operator[] (uint8_t x) __attribute__((always_inline)) - { - return entries[x]; - } - inline const CRGB& operator[] (uint8_t x) const __attribute__((always_inline)) - { - return entries[x]; - } - - inline CRGB& operator[] (int x) __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - inline const CRGB& operator[] (int x) const __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - - operator CRGB*() - { - return &(entries[0]); - } - - CRGBPalette16( const CHSV& c1) - { - fill_solid( &(entries[0]), 16, c1); - } - CRGBPalette16( const CHSV& c1, const CHSV& c2) - { - fill_gradient( &(entries[0]), 16, c1, c2); - } - CRGBPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3) - { - fill_gradient( &(entries[0]), 16, c1, c2, c3); - } - CRGBPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) - { - fill_gradient( &(entries[0]), 16, c1, c2, c3, c4); - } - - CRGBPalette16( const CRGB& c1) - { - fill_solid( &(entries[0]), 16, c1); - } - CRGBPalette16( const CRGB& c1, const CRGB& c2) - { - fill_gradient_RGB( &(entries[0]), 16, c1, c2); - } - CRGBPalette16( const CRGB& c1, const CRGB& c2, const CRGB& c3) - { - fill_gradient_RGB( &(entries[0]), 16, c1, c2, c3); - } - CRGBPalette16( const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) - { - fill_gradient_RGB( &(entries[0]), 16, c1, c2, c3, c4); - } - - - // Gradient palettes are loaded into CRGB16Palettes in such a way - // that, if possible, every color represented in the gradient palette - // is also represented in the CRGBPalette16. - // For example, consider a gradient palette that is all black except - // for a single, one-element-wide (1/256th!) spike of red in the middle: - // 0, 0,0,0 - // 124, 0,0,0 - // 125, 255,0,0 // one 1/256th-palette-wide red stripe - // 126, 0,0,0 - // 255, 0,0,0 - // A naive conversion of this 256-element palette to a 16-element palette - // might accidentally completely eliminate the red spike, rendering the - // palette completely black. - // However, the conversions provided here would attempt to include a - // the red stripe in the output, more-or-less as faithfully as possible. - // So in this case, the resulting CRGBPalette16 palette would have a red - // stripe in the middle which was 1/16th of a palette wide -- the - // narrowest possible in a CRGBPalette16. - // This means that the relative width of stripes in a CRGBPalette16 - // will be, by definition, different from the widths in the gradient - // palette. This code attempts to preserve "all the colors", rather than - // the exact stripe widths at the expense of dropping some colors. - CRGBPalette16( TProgmemRGBGradientPalette_bytes progpal ) - { - *this = progpal; - } - CRGBPalette16& operator=( TProgmemRGBGradientPalette_bytes progpal ) - { - TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal); - TRGBGradientPaletteEntryUnion u; - - // Count entries - uint16_t count = 0; - do { - u.dword = FL_PGM_READ_DWORD_NEAR(progent + count); - ++count; - } while ( u.index != 255); - - int8_t lastSlotUsed = -1; - - u.dword = FL_PGM_READ_DWORD_NEAR( progent); - CRGB rgbstart( u.r, u.g, u.b); - - int indexstart = 0; - uint8_t istart8 = 0; - uint8_t iend8 = 0; - while( indexstart < 255) { - ++progent; - u.dword = FL_PGM_READ_DWORD_NEAR( progent); - int indexend = u.index; - CRGB rgbend( u.r, u.g, u.b); - istart8 = indexstart / 16; - iend8 = indexend / 16; - if( count < 16) { - if( (istart8 <= lastSlotUsed) && (lastSlotUsed < 15)) { - istart8 = lastSlotUsed + 1; - if( iend8 < istart8) { - iend8 = istart8; - } - } - lastSlotUsed = iend8; - } - fill_gradient_RGB( &(entries[0]), istart8, rgbstart, iend8, rgbend); - indexstart = indexend; - rgbstart = rgbend; - } - return *this; - } - CRGBPalette16& loadDynamicGradientPalette( TDynamicRGBGradientPalette_bytes gpal ) - { - TRGBGradientPaletteEntryUnion* ent = (TRGBGradientPaletteEntryUnion*)(gpal); - TRGBGradientPaletteEntryUnion u; - - // Count entries - uint16_t count = 0; - do { - u = *(ent + count); - ++count; - } while ( u.index != 255); - - int8_t lastSlotUsed = -1; - - - u = *ent; - CRGB rgbstart( u.r, u.g, u.b); - - int indexstart = 0; - uint8_t istart8 = 0; - uint8_t iend8 = 0; - while( indexstart < 255) { - ++ent; - u = *ent; - int indexend = u.index; - CRGB rgbend( u.r, u.g, u.b); - istart8 = indexstart / 16; - iend8 = indexend / 16; - if( count < 16) { - if( (istart8 <= lastSlotUsed) && (lastSlotUsed < 15)) { - istart8 = lastSlotUsed + 1; - if( iend8 < istart8) { - iend8 = istart8; - } - } - lastSlotUsed = iend8; - } - fill_gradient_RGB( &(entries[0]), istart8, rgbstart, iend8, rgbend); - indexstart = indexend; - rgbstart = rgbend; - } - return *this; - } - -}; - - - -class CHSVPalette32 { -public: - CHSV entries[32]; - CHSVPalette32() {}; - CHSVPalette32( const CHSV& c00,const CHSV& c01,const CHSV& c02,const CHSV& c03, - const CHSV& c04,const CHSV& c05,const CHSV& c06,const CHSV& c07, - const CHSV& c08,const CHSV& c09,const CHSV& c10,const CHSV& c11, - const CHSV& c12,const CHSV& c13,const CHSV& c14,const CHSV& c15 ) - { - for( uint8_t i = 0; i < 2; ++i) { - entries[0+i]=c00; entries[2+i]=c01; entries[4+i]=c02; entries[6+i]=c03; - entries[8+i]=c04; entries[10+i]=c05; entries[12+i]=c06; entries[14+i]=c07; - entries[16+i]=c08; entries[18+i]=c09; entries[20+i]=c10; entries[22+i]=c11; - entries[24+i]=c12; entries[26+i]=c13; entries[28+i]=c14; entries[30+i]=c15; - } - }; - - CHSVPalette32( const CHSVPalette32& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - } - CHSVPalette32& operator=( const CHSVPalette32& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - return *this; - } - - CHSVPalette32( const TProgmemHSVPalette32& rhs) - { - for( uint8_t i = 0; i < 32; ++i) { - CRGB xyz = FL_PGM_READ_DWORD_NEAR( rhs + i); - entries[i].hue = xyz.red; - entries[i].sat = xyz.green; - entries[i].val = xyz.blue; - } - } - CHSVPalette32& operator=( const TProgmemHSVPalette32& rhs) - { - for( uint8_t i = 0; i < 32; ++i) { - CRGB xyz = FL_PGM_READ_DWORD_NEAR( rhs + i); - entries[i].hue = xyz.red; - entries[i].sat = xyz.green; - entries[i].val = xyz.blue; - } - return *this; - } - - inline CHSV& operator[] (uint8_t x) __attribute__((always_inline)) - { - return entries[x]; - } - inline const CHSV& operator[] (uint8_t x) const __attribute__((always_inline)) - { - return entries[x]; - } - - inline CHSV& operator[] (int x) __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - inline const CHSV& operator[] (int x) const __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - - operator CHSV*() - { - return &(entries[0]); - } - - bool operator==( const CHSVPalette32 rhs) - { - const uint8_t* p = (const uint8_t*)(&(this->entries[0])); - const uint8_t* q = (const uint8_t*)(&(rhs.entries[0])); - if( p == q) return true; - for( uint8_t i = 0; i < (sizeof( entries)); ++i) { - if( *p != *q) return false; - ++p; - ++q; - } - return true; - } - bool operator!=( const CHSVPalette32 rhs) - { - return !( *this == rhs); - } - - CHSVPalette32( const CHSV& c1) - { - fill_solid( &(entries[0]), 32, c1); - } - CHSVPalette32( const CHSV& c1, const CHSV& c2) - { - fill_gradient( &(entries[0]), 32, c1, c2); - } - CHSVPalette32( const CHSV& c1, const CHSV& c2, const CHSV& c3) - { - fill_gradient( &(entries[0]), 32, c1, c2, c3); - } - CHSVPalette32( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) - { - fill_gradient( &(entries[0]), 32, c1, c2, c3, c4); - } - -}; - -class CRGBPalette32 { -public: - CRGB entries[32]; - CRGBPalette32() {}; - CRGBPalette32( const CRGB& c00,const CRGB& c01,const CRGB& c02,const CRGB& c03, - const CRGB& c04,const CRGB& c05,const CRGB& c06,const CRGB& c07, - const CRGB& c08,const CRGB& c09,const CRGB& c10,const CRGB& c11, - const CRGB& c12,const CRGB& c13,const CRGB& c14,const CRGB& c15 ) - { - for( uint8_t i = 0; i < 2; ++i) { - entries[0+i]=c00; entries[2+i]=c01; entries[4+i]=c02; entries[6+i]=c03; - entries[8+i]=c04; entries[10+i]=c05; entries[12+i]=c06; entries[14+i]=c07; - entries[16+i]=c08; entries[18+i]=c09; entries[20+i]=c10; entries[22+i]=c11; - entries[24+i]=c12; entries[26+i]=c13; entries[28+i]=c14; entries[30+i]=c15; - } - }; - - CRGBPalette32( const CRGBPalette32& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - } - CRGBPalette32( const CRGB rhs[32]) - { - memmove8( (void *) &(entries[0]), &(rhs[0]), sizeof( entries)); - } - CRGBPalette32& operator=( const CRGBPalette32& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - return *this; - } - CRGBPalette32& operator=( const CRGB rhs[32]) - { - memmove8( (void *) &(entries[0]), &(rhs[0]), sizeof( entries)); - return *this; - } - - CRGBPalette32( const CHSVPalette32& rhs) - { - for( uint8_t i = 0; i < 32; ++i) { - entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion - } - } - CRGBPalette32( const CHSV rhs[32]) - { - for( uint8_t i = 0; i < 32; ++i) { - entries[i] = rhs[i]; // implicit HSV-to-RGB conversion - } - } - CRGBPalette32& operator=( const CHSVPalette32& rhs) - { - for( uint8_t i = 0; i < 32; ++i) { - entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion - } - return *this; - } - CRGBPalette32& operator=( const CHSV rhs[32]) - { - for( uint8_t i = 0; i < 32; ++i) { - entries[i] = rhs[i]; // implicit HSV-to-RGB conversion - } - return *this; - } - - CRGBPalette32( const TProgmemRGBPalette32& rhs) - { - for( uint8_t i = 0; i < 32; ++i) { - entries[i] = FL_PGM_READ_DWORD_NEAR( rhs + i); - } - } - CRGBPalette32& operator=( const TProgmemRGBPalette32& rhs) - { - for( uint8_t i = 0; i < 32; ++i) { - entries[i] = FL_PGM_READ_DWORD_NEAR( rhs + i); - } - return *this; - } - - bool operator==( const CRGBPalette32 rhs) - { - const uint8_t* p = (const uint8_t*)(&(this->entries[0])); - const uint8_t* q = (const uint8_t*)(&(rhs.entries[0])); - if( p == q) return true; - for( uint8_t i = 0; i < (sizeof( entries)); ++i) { - if( *p != *q) return false; - ++p; - ++q; - } - return true; - } - bool operator!=( const CRGBPalette32 rhs) - { - return !( *this == rhs); - } - - inline CRGB& operator[] (uint8_t x) __attribute__((always_inline)) - { - return entries[x]; - } - inline const CRGB& operator[] (uint8_t x) const __attribute__((always_inline)) - { - return entries[x]; - } - - inline CRGB& operator[] (int x) __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - inline const CRGB& operator[] (int x) const __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - - operator CRGB*() - { - return &(entries[0]); - } - - CRGBPalette32( const CHSV& c1) - { - fill_solid( &(entries[0]), 32, c1); - } - CRGBPalette32( const CHSV& c1, const CHSV& c2) - { - fill_gradient( &(entries[0]), 32, c1, c2); - } - CRGBPalette32( const CHSV& c1, const CHSV& c2, const CHSV& c3) - { - fill_gradient( &(entries[0]), 32, c1, c2, c3); - } - CRGBPalette32( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) - { - fill_gradient( &(entries[0]), 32, c1, c2, c3, c4); - } - - CRGBPalette32( const CRGB& c1) - { - fill_solid( &(entries[0]), 32, c1); - } - CRGBPalette32( const CRGB& c1, const CRGB& c2) - { - fill_gradient_RGB( &(entries[0]), 32, c1, c2); - } - CRGBPalette32( const CRGB& c1, const CRGB& c2, const CRGB& c3) - { - fill_gradient_RGB( &(entries[0]), 32, c1, c2, c3); - } - CRGBPalette32( const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) - { - fill_gradient_RGB( &(entries[0]), 32, c1, c2, c3, c4); - } - - - CRGBPalette32( const CRGBPalette16& rhs16) - { - UpscalePalette( rhs16, *this); - } - CRGBPalette32& operator=( const CRGBPalette16& rhs16) - { - UpscalePalette( rhs16, *this); - return *this; - } - - CRGBPalette32( const TProgmemRGBPalette16& rhs) - { - CRGBPalette16 p16(rhs); - *this = p16; - } - CRGBPalette32& operator=( const TProgmemRGBPalette16& rhs) - { - CRGBPalette16 p16(rhs); - *this = p16; - return *this; - } - - - // Gradient palettes are loaded into CRGB16Palettes in such a way - // that, if possible, every color represented in the gradient palette - // is also represented in the CRGBPalette32. - // For example, consider a gradient palette that is all black except - // for a single, one-element-wide (1/256th!) spike of red in the middle: - // 0, 0,0,0 - // 124, 0,0,0 - // 125, 255,0,0 // one 1/256th-palette-wide red stripe - // 126, 0,0,0 - // 255, 0,0,0 - // A naive conversion of this 256-element palette to a 16-element palette - // might accidentally completely eliminate the red spike, rendering the - // palette completely black. - // However, the conversions provided here would attempt to include a - // the red stripe in the output, more-or-less as faithfully as possible. - // So in this case, the resulting CRGBPalette32 palette would have a red - // stripe in the middle which was 1/16th of a palette wide -- the - // narrowest possible in a CRGBPalette32. - // This means that the relative width of stripes in a CRGBPalette32 - // will be, by definition, different from the widths in the gradient - // palette. This code attempts to preserve "all the colors", rather than - // the exact stripe widths at the expense of dropping some colors. - CRGBPalette32( TProgmemRGBGradientPalette_bytes progpal ) - { - *this = progpal; - } - CRGBPalette32& operator=( TProgmemRGBGradientPalette_bytes progpal ) - { - TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal); - TRGBGradientPaletteEntryUnion u; - - // Count entries - uint16_t count = 0; - do { - u.dword = FL_PGM_READ_DWORD_NEAR(progent + count); - ++count; - } while ( u.index != 255); - - int8_t lastSlotUsed = -1; - - u.dword = FL_PGM_READ_DWORD_NEAR( progent); - CRGB rgbstart( u.r, u.g, u.b); - - int indexstart = 0; - uint8_t istart8 = 0; - uint8_t iend8 = 0; - while( indexstart < 255) { - ++progent; - u.dword = FL_PGM_READ_DWORD_NEAR( progent); - int indexend = u.index; - CRGB rgbend( u.r, u.g, u.b); - istart8 = indexstart / 8; - iend8 = indexend / 8; - if( count < 16) { - if( (istart8 <= lastSlotUsed) && (lastSlotUsed < 31)) { - istart8 = lastSlotUsed + 1; - if( iend8 < istart8) { - iend8 = istart8; - } - } - lastSlotUsed = iend8; - } - fill_gradient_RGB( &(entries[0]), istart8, rgbstart, iend8, rgbend); - indexstart = indexend; - rgbstart = rgbend; - } - return *this; - } - CRGBPalette32& loadDynamicGradientPalette( TDynamicRGBGradientPalette_bytes gpal ) - { - TRGBGradientPaletteEntryUnion* ent = (TRGBGradientPaletteEntryUnion*)(gpal); - TRGBGradientPaletteEntryUnion u; - - // Count entries - uint16_t count = 0; - do { - u = *(ent + count); - ++count; - } while ( u.index != 255); - - int8_t lastSlotUsed = -1; - - - u = *ent; - CRGB rgbstart( u.r, u.g, u.b); - - int indexstart = 0; - uint8_t istart8 = 0; - uint8_t iend8 = 0; - while( indexstart < 255) { - ++ent; - u = *ent; - int indexend = u.index; - CRGB rgbend( u.r, u.g, u.b); - istart8 = indexstart / 8; - iend8 = indexend / 8; - if( count < 16) { - if( (istart8 <= lastSlotUsed) && (lastSlotUsed < 31)) { - istart8 = lastSlotUsed + 1; - if( iend8 < istart8) { - iend8 = istart8; - } - } - lastSlotUsed = iend8; - } - fill_gradient_RGB( &(entries[0]), istart8, rgbstart, iend8, rgbend); - indexstart = indexend; - rgbstart = rgbend; - } - return *this; - } - -}; - - - -class CRGBPalette256 { -public: - CRGB entries[256]; - CRGBPalette256() {}; - CRGBPalette256( const CRGB& c00,const CRGB& c01,const CRGB& c02,const CRGB& c03, - const CRGB& c04,const CRGB& c05,const CRGB& c06,const CRGB& c07, - const CRGB& c08,const CRGB& c09,const CRGB& c10,const CRGB& c11, - const CRGB& c12,const CRGB& c13,const CRGB& c14,const CRGB& c15 ) - { - CRGBPalette16 p16(c00,c01,c02,c03,c04,c05,c06,c07, - c08,c09,c10,c11,c12,c13,c14,c15); - *this = p16; - }; - - CRGBPalette256( const CRGBPalette256& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - } - CRGBPalette256( const CRGB rhs[256]) - { - memmove8( (void *) &(entries[0]), &(rhs[0]), sizeof( entries)); - } - CRGBPalette256& operator=( const CRGBPalette256& rhs) - { - memmove8( (void *) &(entries[0]), &(rhs.entries[0]), sizeof( entries)); - return *this; - } - CRGBPalette256& operator=( const CRGB rhs[256]) - { - memmove8( (void *) &(entries[0]), &(rhs[0]), sizeof( entries)); - return *this; - } - - CRGBPalette256( const CHSVPalette256& rhs) - { - for( int i = 0; i < 256; ++i) { - entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion - } - } - CRGBPalette256( const CHSV rhs[256]) - { - for( int i = 0; i < 256; ++i) { - entries[i] = rhs[i]; // implicit HSV-to-RGB conversion - } - } - CRGBPalette256& operator=( const CHSVPalette256& rhs) - { - for( int i = 0; i < 256; ++i) { - entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion - } - return *this; - } - CRGBPalette256& operator=( const CHSV rhs[256]) - { - for( int i = 0; i < 256; ++i) { - entries[i] = rhs[i]; // implicit HSV-to-RGB conversion - } - return *this; - } - - CRGBPalette256( const CRGBPalette16& rhs16) - { - UpscalePalette( rhs16, *this); - } - CRGBPalette256& operator=( const CRGBPalette16& rhs16) - { - UpscalePalette( rhs16, *this); - return *this; - } - - CRGBPalette256( const TProgmemRGBPalette16& rhs) - { - CRGBPalette16 p16(rhs); - *this = p16; - } - CRGBPalette256& operator=( const TProgmemRGBPalette16& rhs) - { - CRGBPalette16 p16(rhs); - *this = p16; - return *this; - } - - bool operator==( const CRGBPalette256 rhs) - { - const uint8_t* p = (const uint8_t*)(&(this->entries[0])); - const uint8_t* q = (const uint8_t*)(&(rhs.entries[0])); - if( p == q) return true; - for( uint16_t i = 0; i < (sizeof( entries)); ++i) { - if( *p != *q) return false; - ++p; - ++q; - } - return true; - } - bool operator!=( const CRGBPalette256 rhs) - { - return !( *this == rhs); - } - - inline CRGB& operator[] (uint8_t x) __attribute__((always_inline)) - { - return entries[x]; - } - inline const CRGB& operator[] (uint8_t x) const __attribute__((always_inline)) - { - return entries[x]; - } - - inline CRGB& operator[] (int x) __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - inline const CRGB& operator[] (int x) const __attribute__((always_inline)) - { - return entries[(uint8_t)x]; - } - - operator CRGB*() - { - return &(entries[0]); - } - - CRGBPalette256( const CHSV& c1) - { - fill_solid( &(entries[0]), 256, c1); - } - CRGBPalette256( const CHSV& c1, const CHSV& c2) - { - fill_gradient( &(entries[0]), 256, c1, c2); - } - CRGBPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3) - { - fill_gradient( &(entries[0]), 256, c1, c2, c3); - } - CRGBPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) - { - fill_gradient( &(entries[0]), 256, c1, c2, c3, c4); - } - - CRGBPalette256( const CRGB& c1) - { - fill_solid( &(entries[0]), 256, c1); - } - CRGBPalette256( const CRGB& c1, const CRGB& c2) - { - fill_gradient_RGB( &(entries[0]), 256, c1, c2); - } - CRGBPalette256( const CRGB& c1, const CRGB& c2, const CRGB& c3) - { - fill_gradient_RGB( &(entries[0]), 256, c1, c2, c3); - } - CRGBPalette256( const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) - { - fill_gradient_RGB( &(entries[0]), 256, c1, c2, c3, c4); - } - - CRGBPalette256( TProgmemRGBGradientPalette_bytes progpal ) - { - *this = progpal; - } - CRGBPalette256& operator=( TProgmemRGBGradientPalette_bytes progpal ) - { - TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal); - TRGBGradientPaletteEntryUnion u; - u.dword = FL_PGM_READ_DWORD_NEAR( progent); - CRGB rgbstart( u.r, u.g, u.b); - - int indexstart = 0; - while( indexstart < 255) { - ++progent; - u.dword = FL_PGM_READ_DWORD_NEAR( progent); - int indexend = u.index; - CRGB rgbend( u.r, u.g, u.b); - fill_gradient_RGB( &(entries[0]), indexstart, rgbstart, indexend, rgbend); - indexstart = indexend; - rgbstart = rgbend; - } - return *this; - } - CRGBPalette256& loadDynamicGradientPalette( TDynamicRGBGradientPalette_bytes gpal ) - { - TRGBGradientPaletteEntryUnion* ent = (TRGBGradientPaletteEntryUnion*)(gpal); - TRGBGradientPaletteEntryUnion u; - u = *ent; - CRGB rgbstart( u.r, u.g, u.b); - - int indexstart = 0; - while( indexstart < 255) { - ++ent; - u = *ent; - int indexend = u.index; - CRGB rgbend( u.r, u.g, u.b); - fill_gradient_RGB( &(entries[0]), indexstart, rgbstart, indexend, rgbend); - indexstart = indexend; - rgbstart = rgbend; - } - return *this; - } -}; - - - -typedef enum { NOBLEND=0, LINEARBLEND=1 } TBlendType; - -CRGB ColorFromPalette( const CRGBPalette16& pal, - uint8_t index, - uint8_t brightness=255, - TBlendType blendType=LINEARBLEND); - -CRGB ColorFromPalette( const TProgmemRGBPalette16& pal, - uint8_t index, - uint8_t brightness=255, - TBlendType blendType=LINEARBLEND); - -CRGB ColorFromPalette( const CRGBPalette256& pal, - uint8_t index, - uint8_t brightness=255, - TBlendType blendType=NOBLEND ); - -CHSV ColorFromPalette( const CHSVPalette16& pal, - uint8_t index, - uint8_t brightness=255, - TBlendType blendType=LINEARBLEND); - -CHSV ColorFromPalette( const CHSVPalette256& pal, - uint8_t index, - uint8_t brightness=255, - TBlendType blendType=NOBLEND ); - -CRGB ColorFromPalette( const CRGBPalette32& pal, - uint8_t index, - uint8_t brightness=255, - TBlendType blendType=LINEARBLEND); - -CRGB ColorFromPalette( const TProgmemRGBPalette32& pal, - uint8_t index, - uint8_t brightness=255, - TBlendType blendType=LINEARBLEND); - -CHSV ColorFromPalette( const CHSVPalette32& pal, - uint8_t index, - uint8_t brightness=255, - TBlendType blendType=LINEARBLEND); - - -// Fill a range of LEDs with a sequece of entryies from a palette -template <typename PALETTE> -void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, - const PALETTE& pal, uint8_t brightness, TBlendType blendType) -{ - uint8_t colorIndex = startIndex; - for( uint16_t i = 0; i < N; ++i) { - L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType); - colorIndex += incIndex; - } -} - -template <typename PALETTE> -void map_data_into_colors_through_palette( - uint8_t *dataArray, uint16_t dataCount, - CRGB* targetColorArray, - const PALETTE& pal, - uint8_t brightness=255, - uint8_t opacity=255, - TBlendType blendType=LINEARBLEND) -{ - for( uint16_t i = 0; i < dataCount; ++i) { - uint8_t d = dataArray[i]; - CRGB rgb = ColorFromPalette( pal, d, brightness, blendType); - if( opacity == 255 ) { - targetColorArray[i] = rgb; - } else { - targetColorArray[i].nscale8( 256 - opacity); - rgb.nscale8_video( opacity); - targetColorArray[i] += rgb; - } - } -} - -// nblendPaletteTowardPalette: -// Alter one palette by making it slightly more like -// a 'target palette', used for palette cross-fades. -// -// It does this by comparing each of the R, G, and B channels -// of each entry in the current palette to the corresponding -// entry in the target palette and making small adjustments: -// If the Red channel is too low, it will be increased. -// If the Red channel is too high, it will be slightly reduced. -// ... and likewise for Green and Blue channels. -// -// Additionally, there are two significant visual improvements -// to this algorithm implemented here. First is this: -// When increasing a channel, it is stepped up by ONE. -// When decreasing a channel, it is stepped down by TWO. -// Due to the way the eye perceives light, and the way colors -// are represented in RGB, this produces a more uniform apparent -// brightness when cross-fading between most palette colors. -// -// The second visual tweak is limiting the number of changes -// that will be made to the palette at once. If all the palette -// entries are changed at once, it can give a muddled appearance. -// However, if only a few palette entries are changed at once, -// you get a visually smoother transition: in the middle of the -// cross-fade your current palette will actually contain some -// colors from the old palette, a few blended colors, and some -// colors from the new palette. -// The maximum number of possible palette changes per call -// is 48 (sixteen color entries time three channels each). -// The default 'maximim number of changes' here is 12, meaning -// that only approximately a quarter of the palette entries -// will be changed per call. -void nblendPaletteTowardPalette( CRGBPalette16& currentPalette, - CRGBPalette16& targetPalette, - uint8_t maxChanges=24); - - - - -// You can also define a static RGB palette very compactly in terms of a series -// of connected color gradients. -// For example, if you want the first 3/4ths of the palette to be a slow -// gradient ramping from black to red, and then the remaining 1/4 of the -// palette to be a quicker ramp to white, you specify just three points: the -// starting black point (at index 0), the red midpoint (at index 192), -// and the final white point (at index 255). It looks like this: -// -// index: 0 192 255 -// |----------r-r-r-rrrrrrrrRrRrRrRrRRRR-|-RRWRWWRWWW-| -// color: (0,0,0) (255,0,0) (255,255,255) -// -// Here's how you'd define that gradient palette: -// -// DEFINE_GRADIENT_PALETTE( black_to_red_to_white_p ) { -// 0, 0, 0, 0, /* at index 0, black(0,0,0) */ -// 192, 255, 0, 0, /* at index 192, red(255,0,0) */ -// 255, 255,255,255 /* at index 255, white(255,255,255) */ -// }; -// -// This format is designed for compact storage. The example palette here -// takes up just 12 bytes of PROGMEM (flash) storage, and zero bytes -// of SRAM when not currently in use. -// -// To use one of these gradient palettes, simply assign it into a -// CRGBPalette16 or a CRGBPalette256, like this: -// -// CRGBPalette16 pal = black_to_red_to_white_p; -// -// When the assignment is made, the gradients are expanded out into -// either 16 or 256 palette entries, depending on the kind of palette -// object they're assigned to. -// -// IMPORTANT NOTES & CAVEATS: -// -// - The last 'index' position MUST BE 255! Failure to end with -// index 255 will result in program hangs or crashes. -// -// - At this point, these gradient palette definitions MUST BE -// stored in PROGMEM on AVR-based Arduinos. If you use the -// DEFINE_GRADIENT_PALETTE macro, this is taken care of automatically. -// - -#define DEFINE_GRADIENT_PALETTE(X) \ - FL_ALIGN_PROGMEM \ - extern const TProgmemRGBGradientPalette_byte X[] FL_PROGMEM = - -#define DECLARE_GRADIENT_PALETTE(X) \ - FL_ALIGN_PROGMEM \ - extern const TProgmemRGBGradientPalette_byte X[] FL_PROGMEM - - -// Functions to apply gamma adjustments, either: -// - a single gamma adjustment to a single scalar value, -// - a single gamma adjustment to each channel of a CRGB color, or -// - different gamma adjustments for each channel of a CRFB color. -// -// Note that the gamma is specified as a traditional floating point value -// e.g., "2.5", and as such these functions should not be called in -// your innermost pixel loops, or in animations that are extremely -// low on program storage space. Nevertheless, if you need these -// functions, here they are. -// -// Furthermore, bear in mind that CRGB leds have only eight bits -// per channel of color resolution, and that very small, subtle shadings -// may not be visible. -uint8_t applyGamma_video( uint8_t brightness, float gamma); -CRGB applyGamma_video( const CRGB& orig, float gamma); -CRGB applyGamma_video( const CRGB& orig, float gammaR, float gammaG, float gammaB); -// The "n" versions below modify their arguments in-place. -CRGB& napplyGamma_video( CRGB& rgb, float gamma); -CRGB& napplyGamma_video( CRGB& rgb, float gammaR, float gammaG, float gammaB); -void napplyGamma_video( CRGB* rgbarray, uint16_t count, float gamma); -void napplyGamma_video( CRGB* rgbarray, uint16_t count, float gammaR, float gammaG, float gammaB); - - -FASTLED_NAMESPACE_END - -///@} -#endif diff --git a/FastLED/src/controller.h b/FastLED/src/controller.h deleted file mode 100644 index fe32d70d3294a1125750e4ca9d851e58d2afbb9c..0000000000000000000000000000000000000000 --- a/FastLED/src/controller.h +++ /dev/null @@ -1,418 +0,0 @@ -#ifndef __INC_CONTROLLER_H -#define __INC_CONTROLLER_H - -///@file controller.h -/// base definitions used by led controllers for writing out led data - -#include "FastLED.h" -#include "led_sysdefs.h" -#include "pixeltypes.h" -#include "color.h" -#include <stddef.h> - -FASTLED_NAMESPACE_BEGIN - -#define RO(X) RGB_BYTE(RGB_ORDER, X) -#define RGB_BYTE(RO,X) (((RO)>>(3*(2-(X)))) & 0x3) - -#define RGB_BYTE0(RO) ((RO>>6) & 0x3) -#define RGB_BYTE1(RO) ((RO>>3) & 0x3) -#define RGB_BYTE2(RO) ((RO) & 0x3) - -// operator byte *(struct CRGB[] arr) { return (byte*)arr; } - -#define DISABLE_DITHER 0x00 -#define BINARY_DITHER 0x01 -typedef uint8_t EDitherMode; - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// LED Controller interface definition -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/// Base definition for an LED controller. Pretty much the methods that every LED controller object will make available. -/// Note that the showARGB method is not impelemented for all controllers yet. Note also the methods for eventual checking -/// of background writing of data (I'm looking at you, teensy 3.0 DMA controller!). If you want to pass LED controllers around -/// to methods, make them references to this type, keeps your code saner. However, most people won't be seeing/using these objects -/// directly at all -class CLEDController { -protected: - friend class CFastLED; - CRGB *m_Data; - CLEDController *m_pNext; - CRGB m_ColorCorrection; - CRGB m_ColorTemperature; - EDitherMode m_DitherMode; - int m_nLeds; - static CLEDController *m_pHead; - static CLEDController *m_pTail; - - /// set all the leds on the controller to a given color - ///@param data the crgb color to set the leds to - ///@param nLeds the number of leds to set to this color - ///@param scale the rgb scaling value for outputting color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) = 0; - - /// write the passed in rgb data out to the leds managed by this controller - ///@param data the rgb data to write out to the strip - ///@param nLeds the number of leds being written out - ///@param scale the rgb scaling to apply to each led before writing it out - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) = 0; - -public: - /// create an led controller object, add it to the chain of controllers - CLEDController() : m_Data(NULL), m_ColorCorrection(UncorrectedColor), m_ColorTemperature(UncorrectedTemperature), m_DitherMode(BINARY_DITHER), m_nLeds(0) { - m_pNext = NULL; - if(m_pHead==NULL) { m_pHead = this; } - if(m_pTail != NULL) { m_pTail->m_pNext = this; } - m_pTail = this; - } - - ///initialize the LED controller - virtual void init() = 0; - - ///clear out/zero out the given number of leds. - virtual void clearLeds(int nLeds) { showColor(CRGB::Black, nLeds, CRGB::Black); } - - /// show function w/integer brightness, will scale for color correction and temperature - void show(const struct CRGB *data, int nLeds, uint8_t brightness) { - show(data, nLeds, getAdjustment(brightness)); - } - - /// show function w/integer brightness, will scale for color correction and temperature - void showColor(const struct CRGB &data, int nLeds, uint8_t brightness) { - showColor(data, nLeds, getAdjustment(brightness)); - } - - /// show function using the "attached to this controller" led data - void showLeds(uint8_t brightness=255) { - show(m_Data, m_nLeds, getAdjustment(brightness)); - } - - /// show the given color on the led strip - void showColor(const struct CRGB & data, uint8_t brightness=255) { - showColor(data, m_nLeds, getAdjustment(brightness)); - } - - /// get the first led controller in the chain of controllers - static CLEDController *head() { return m_pHead; } - /// get the next controller in the chain after this one. will return NULL at the end of the chain - CLEDController *next() { return m_pNext; } - - /// set the default array of leds to be used by this controller - CLEDController & setLeds(CRGB *data, int nLeds) { - m_Data = data; - m_nLeds = nLeds; - return *this; - } - - /// zero out the led data managed by this controller - void clearLedData() { - if(m_Data) { - memset8((void*)m_Data, 0, sizeof(struct CRGB) * m_nLeds); - } - } - - /// How many leds does this controller manage? - virtual int size() { return m_nLeds; } - - /// Pointer to the CRGB array for this controller - CRGB* leds() { return m_Data; } - - /// Reference to the n'th item in the controller - CRGB &operator[](int x) { return m_Data[x]; } - - /// set the dithering mode for this controller to use - inline CLEDController & setDither(uint8_t ditherMode = BINARY_DITHER) { m_DitherMode = ditherMode; return *this; } - /// get the dithering option currently set for this controller - inline uint8_t getDither() { return m_DitherMode; } - - /// the the color corrction to use for this controller, expressed as an rgb object - CLEDController & setCorrection(CRGB correction) { m_ColorCorrection = correction; return *this; } - /// set the color correction to use for this controller - CLEDController & setCorrection(LEDColorCorrection correction) { m_ColorCorrection = correction; return *this; } - /// get the correction value used by this controller - CRGB getCorrection() { return m_ColorCorrection; } - - /// set the color temperature, aka white point, for this controller - CLEDController & setTemperature(CRGB temperature) { m_ColorTemperature = temperature; return *this; } - /// set the color temperature, aka white point, for this controller - CLEDController & setTemperature(ColorTemperature temperature) { m_ColorTemperature = temperature; return *this; } - /// get the color temperature, aka whipe point, for this controller - CRGB getTemperature() { return m_ColorTemperature; } - - /// Get the combined brightness/color adjustment for this controller - CRGB getAdjustment(uint8_t scale) { - return computeAdjustment(scale, m_ColorCorrection, m_ColorTemperature); - } - - static CRGB computeAdjustment(uint8_t scale, const CRGB & colorCorrection, const CRGB & colorTemperature) { - #if defined(NO_CORRECTION) && (NO_CORRECTION==1) - return CRGB(scale,scale,scale); - #else - CRGB adj(0,0,0); - - if(scale > 0) { - for(uint8_t i = 0; i < 3; ++i) { - uint8_t cc = colorCorrection.raw[i]; - uint8_t ct = colorTemperature.raw[i]; - if(cc > 0 && ct > 0) { - uint32_t work = (((uint32_t)cc)+1) * (((uint32_t)ct)+1) * scale; - work /= 0x10000L; - adj.raw[i] = work & 0xFF; - } - } - } - - return adj; - #endif - } - virtual uint16_t getMaxRefreshRate() const { return 0; } -}; - -// Pixel controller class. This is the class that we use to centralize pixel access in a block of data, including -// support for things like RGB reordering, scaling, dithering, skipping (for ARGB data), and eventually, we will -// centralize 8/12/16 conversions here as well. -template<EOrder RGB_ORDER, int LANES=1, uint32_t MASK=0xFFFFFFFF> -struct PixelController { - const uint8_t *mData; - int mLen,mLenRemaining; - uint8_t d[3]; - uint8_t e[3]; - CRGB mScale; - int8_t mAdvance; - int mOffsets[LANES]; - - PixelController(const PixelController & other) { - d[0] = other.d[0]; - d[1] = other.d[1]; - d[2] = other.d[2]; - e[0] = other.e[0]; - e[1] = other.e[1]; - e[2] = other.e[2]; - mData = other.mData; - mScale = other.mScale; - mAdvance = other.mAdvance; - mLenRemaining = mLen = other.mLen; - for(int i = 0; i < LANES; ++i) { mOffsets[i] = other.mOffsets[i]; } - - } - - void initOffsets(int len) { - int nOffset = 0; - for(int i = 0; i < LANES; ++i) { - mOffsets[i] = nOffset; - if((1<<i) & MASK) { nOffset += (len * mAdvance); } - } - } - - PixelController(const uint8_t *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER, bool advance=true, uint8_t skip=0) : mData(d), mLen(len), mLenRemaining(len), mScale(s) { - enable_dithering(dither); - mData += skip; - mAdvance = (advance) ? 3+skip : 0; - initOffsets(len); - } - - PixelController(const CRGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mLen(len), mLenRemaining(len), mScale(s) { - enable_dithering(dither); - mAdvance = 3; - initOffsets(len); - } - - PixelController(const CRGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mLen(len), mLenRemaining(len), mScale(s) { - enable_dithering(dither); - mAdvance = 0; - initOffsets(len); - } - - void init_binary_dithering() { -#if !defined(NO_DITHERING) || (NO_DITHERING != 1) - - // Set 'virtual bits' of dithering to the highest level - // that is not likely to cause excessive flickering at - // low brightness levels + low update rates. - // These pre-set values are a little ambitious, since - // a 400Hz update rate for WS2811-family LEDs is only - // possible with 85 pixels or fewer. - // Once we have a 'number of milliseconds since last update' - // value available here, we can quickly calculate the correct - // number of 'virtual bits' on the fly with a couple of 'if' - // statements -- no division required. At this point, - // the division is done at compile time, so there's no runtime - // cost, but the values are still hard-coded. -#define MAX_LIKELY_UPDATE_RATE_HZ 400 -#define MIN_ACCEPTABLE_DITHER_RATE_HZ 50 -#define UPDATES_PER_FULL_DITHER_CYCLE (MAX_LIKELY_UPDATE_RATE_HZ / MIN_ACCEPTABLE_DITHER_RATE_HZ) -#define RECOMMENDED_VIRTUAL_BITS ((UPDATES_PER_FULL_DITHER_CYCLE>1) + \ - (UPDATES_PER_FULL_DITHER_CYCLE>2) + \ - (UPDATES_PER_FULL_DITHER_CYCLE>4) + \ - (UPDATES_PER_FULL_DITHER_CYCLE>8) + \ - (UPDATES_PER_FULL_DITHER_CYCLE>16) + \ - (UPDATES_PER_FULL_DITHER_CYCLE>32) + \ - (UPDATES_PER_FULL_DITHER_CYCLE>64) + \ - (UPDATES_PER_FULL_DITHER_CYCLE>128) ) -#define VIRTUAL_BITS RECOMMENDED_VIRTUAL_BITS - - // R is the digther signal 'counter'. - static uint8_t R = 0; - ++R; - - // R is wrapped around at 2^ditherBits, - // so if ditherBits is 2, R will cycle through (0,1,2,3) - uint8_t ditherBits = VIRTUAL_BITS; - R &= (0x01 << ditherBits) - 1; - - // Q is the "unscaled dither signal" itself. - // It's initialized to the reversed bits of R. - // If 'ditherBits' is 2, Q here will cycle through (0,128,64,192) - uint8_t Q = 0; - - // Reverse bits in a byte - { - if(R & 0x01) { Q |= 0x80; } - if(R & 0x02) { Q |= 0x40; } - if(R & 0x04) { Q |= 0x20; } - if(R & 0x08) { Q |= 0x10; } - if(R & 0x10) { Q |= 0x08; } - if(R & 0x20) { Q |= 0x04; } - if(R & 0x40) { Q |= 0x02; } - if(R & 0x80) { Q |= 0x01; } - } - - // Now we adjust Q to fall in the center of each range, - // instead of at the start of the range. - // If ditherBits is 2, Q will be (0, 128, 64, 192) at first, - // and this adjustment makes it (31, 159, 95, 223). - if( ditherBits < 8) { - Q += 0x01 << (7 - ditherBits); - } - - // D and E form the "scaled dither signal" - // which is added to pixel values to affect the - // actual dithering. - - // Setup the initial D and E values - for(int i = 0; i < 3; ++i) { - uint8_t s = mScale.raw[i]; - e[i] = s ? (256/s) + 1 : 0; - d[i] = scale8(Q, e[i]); -#if (FASTLED_SCALE8_FIXED == 1) - if(d[i]) (--d[i]); -#endif - if(e[i]) --e[i]; - } -#endif - } - - // Do we have n pixels left to process? - __attribute__((always_inline)) inline bool has(int n) { - return mLenRemaining >= n; - } - - // toggle dithering enable - void enable_dithering(EDitherMode dither) { - switch(dither) { - case BINARY_DITHER: init_binary_dithering(); break; - default: d[0]=d[1]=d[2]=e[0]=e[1]=e[2]=0; break; - } - } - - __attribute__((always_inline)) inline int size() { return mLen; } - - // get the amount to advance the pointer by - __attribute__((always_inline)) inline int advanceBy() { return mAdvance; } - - // advance the data pointer forward, adjust position counter - __attribute__((always_inline)) inline void advanceData() { mData += mAdvance; --mLenRemaining;} - - // step the dithering forward - __attribute__((always_inline)) inline void stepDithering() { - // IF UPDATING HERE, BE SURE TO UPDATE THE ASM VERSION IN - // clockless_trinket.h! - d[0] = e[0] - d[0]; - d[1] = e[1] - d[1]; - d[2] = e[2] - d[2]; - } - - // Some chipsets pre-cycle the first byte, which means we want to cycle byte 0's dithering separately - __attribute__((always_inline)) inline void preStepFirstByteDithering() { - d[RO(0)] = e[RO(0)] - d[RO(0)]; - } - - template<int SLOT> __attribute__((always_inline)) inline static uint8_t loadByte(PixelController & pc) { return pc.mData[RO(SLOT)]; } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t loadByte(PixelController & pc, int lane) { return pc.mData[pc.mOffsets[lane] + RO(SLOT)]; } - - template<int SLOT> __attribute__((always_inline)) inline static uint8_t dither(PixelController & pc, uint8_t b) { return b ? qadd8(b, pc.d[RO(SLOT)]) : 0; } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t dither(PixelController & , uint8_t b, uint8_t d) { return b ? qadd8(b,d) : 0; } - - template<int SLOT> __attribute__((always_inline)) inline static uint8_t scale(PixelController & pc, uint8_t b) { return scale8(b, pc.mScale.raw[RO(SLOT)]); } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t scale(PixelController & , uint8_t b, uint8_t scale) { return scale8(b, scale); } - - // composite shortcut functions for loading, dithering, and scaling - template<int SLOT> __attribute__((always_inline)) inline static uint8_t loadAndScale(PixelController & pc) { return scale<SLOT>(pc, pc.dither<SLOT>(pc, pc.loadByte<SLOT>(pc))); } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t loadAndScale(PixelController & pc, int lane) { return scale<SLOT>(pc, pc.dither<SLOT>(pc, pc.loadByte<SLOT>(pc, lane))); } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t loadAndScale(PixelController & pc, int lane, uint8_t d, uint8_t scale) { return scale8(pc.dither<SLOT>(pc, pc.loadByte<SLOT>(pc, lane), d), scale); } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t loadAndScale(PixelController & pc, int lane, uint8_t scale) { return scale8(pc.loadByte<SLOT>(pc, lane), scale); } - - template<int SLOT> __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc); } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc, int lane) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc, lane); } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc, int lane, uint8_t scale) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc, lane, scale); } - - template<int SLOT> __attribute__((always_inline)) inline static uint8_t getd(PixelController & pc) { return pc.d[RO(SLOT)]; } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t getscale(PixelController & pc) { return pc.mScale.raw[RO(SLOT)]; } - - // Helper functions to get around gcc stupidities - __attribute__((always_inline)) inline uint8_t loadAndScale0(int lane, uint8_t scale) { return loadAndScale<0>(*this, lane, scale); } - __attribute__((always_inline)) inline uint8_t loadAndScale1(int lane, uint8_t scale) { return loadAndScale<1>(*this, lane, scale); } - __attribute__((always_inline)) inline uint8_t loadAndScale2(int lane, uint8_t scale) { return loadAndScale<2>(*this, lane, scale); } - __attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0(int lane, uint8_t scale) { return advanceAndLoadAndScale<0>(*this, lane, scale); } - __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0(int lane, uint8_t scale) { stepDithering(); return advanceAndLoadAndScale<0>(*this, lane, scale); } - - __attribute__((always_inline)) inline uint8_t loadAndScale0(int lane) { return loadAndScale<0>(*this, lane); } - __attribute__((always_inline)) inline uint8_t loadAndScale1(int lane) { return loadAndScale<1>(*this, lane); } - __attribute__((always_inline)) inline uint8_t loadAndScale2(int lane) { return loadAndScale<2>(*this, lane); } - __attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0(int lane) { return advanceAndLoadAndScale<0>(*this, lane); } - __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0(int lane) { stepDithering(); return advanceAndLoadAndScale<0>(*this, lane); } - - __attribute__((always_inline)) inline uint8_t loadAndScale0() { return loadAndScale<0>(*this); } - __attribute__((always_inline)) inline uint8_t loadAndScale1() { return loadAndScale<1>(*this); } - __attribute__((always_inline)) inline uint8_t loadAndScale2() { return loadAndScale<2>(*this); } - __attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0() { return advanceAndLoadAndScale<0>(*this); } - __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0() { stepDithering(); return advanceAndLoadAndScale<0>(*this); } - - __attribute__((always_inline)) inline uint8_t getScale0() { return getscale<0>(*this); } - __attribute__((always_inline)) inline uint8_t getScale1() { return getscale<1>(*this); } - __attribute__((always_inline)) inline uint8_t getScale2() { return getscale<2>(*this); } -}; - -template<EOrder RGB_ORDER, int LANES=1, uint32_t MASK=0xFFFFFFFF> class CPixelLEDController : public CLEDController { -protected: - virtual void showPixels(PixelController<RGB_ORDER,LANES,MASK> & pixels) = 0; - - /// set all the leds on the controller to a given color - ///@param data the crgb color to set the leds to - ///@param nLeds the numner of leds to set to this color - ///@param scale the rgb scaling value for outputting color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER, LANES, MASK> pixels(data, nLeds, scale, getDither()); - showPixels(pixels); - } - - /// write the passed in rgb data out to the leds managed by this controller - ///@param data the rgb data to write out to the strip - ///@param nLeds the number of leds being written out - ///@param scale the rgb scaling to apply to each led before writing it out - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER, LANES, MASK> pixels(data, nLeds, scale, getDither()); - showPixels(pixels); - } - -public: - CPixelLEDController() : CLEDController() {} -}; - - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/cpp_compat.h b/FastLED/src/cpp_compat.h deleted file mode 100644 index ab5b773aa427379fcc02406c507187fd9211d1a4..0000000000000000000000000000000000000000 --- a/FastLED/src/cpp_compat.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __INC_CPP_COMPAT_H -#define __INC_CPP_COMPAT_H - -#include "FastLED.h" - -#if __cplusplus <= 199711L - -#define static_assert(expression, message) -#define constexpr const - -#else - -// things that we can turn on if we're in a C++11 environment -#endif - -#endif diff --git a/FastLED/src/dmx.h b/FastLED/src/dmx.h deleted file mode 100644 index 04cb5de0beefaf2a536f7cd1898191c14bf327ba..0000000000000000000000000000000000000000 --- a/FastLED/src/dmx.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __INC_DMX_H -#define __INC_DMX_H - -#include "FastLED.h" - -#ifdef DmxSimple_h -#include <DmxSimple.h> -#define HAS_DMX_SIMPLE - -///@ingroup chipsets -///@{ -FASTLED_NAMESPACE_BEGIN - -// note - dmx simple must be included before FastSPI for this code to be enabled -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> class DMXSimpleController : public CPixelLEDController<RGB_ORDER> { -public: - // initialize the LED controller - virtual void init() { DmxSimple.usePin(DATA_PIN); } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - int iChannel = 1; - while(pixels.has(1)) { - DmxSimple.write(iChannel++, pixels.loadAndScale0()); - DmxSimple.write(iChannel++, pixels.loadAndScale1()); - DmxSimple.write(iChannel++, pixels.loadAndScale2()); - pixels.advanceData(); - pixels.stepDithering(); - } - } -}; - -FASTLED_NAMESPACE_END - -#endif - -#ifdef DmxSerial_h -#include <DMXSerial.h> - -FASTLED_NAMESPACE_BEGIN - -template <EOrder RGB_ORDER = RGB> class DMXSerialController : public CPixelLEDController<RGB_ORDER> { -public: - // initialize the LED controller - virtual void init() { DMXSerial.init(DMXController); } - - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - int iChannel = 1; - while(pixels.has(1)) { - DMXSerial.write(iChannel++, pixels.loadAndScale0()); - DMXSerial.write(iChannel++, pixels.loadAndScale1()); - DMXSerial.write(iChannel++, pixels.loadAndScale2()); - pixels.advanceData(); - pixels.stepDithering(); - } - } -}; - -FASTLED_NAMESPACE_END -///@} - -#define HAS_DMX_SERIAL -#endif - -#endif diff --git a/FastLED/src/fastled_config.h b/FastLED/src/fastled_config.h deleted file mode 100644 index 6e415274d1f6822eb81da94d8f7c7593603d6c49..0000000000000000000000000000000000000000 --- a/FastLED/src/fastled_config.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __INC_FASTLED_CONFIG_H -#define __INC_FASTLED_CONFIG_H - -#include "FastLED.h" - -///@file fastled_config.h -/// contains definitions that can be used to configure FastLED at compile time - -// Use this option only for debugging pin access and forcing software pin access. Note that -// software pin access only works in Arduino based environments. Forces use of digitalWrite -// methods for pin access vs. direct hardware port access -// #define FASTLED_FORCE_SOFTWARE_PINS - -// Use this option only for debugging bitbang'd spi access or to work around bugs in hardware -// spi access. Forces use of bit-banged spi, even on pins that has hardware SPI available. -// #define FASTLED_FORCE_SOFTWARE_SPI - -// Use this to force FastLED to allow interrupts in the clockless chipsets (or to force it to -// disallow), overriding the default on platforms that support this. Set the value to 1 to -// allow interrupts or 0 to disallow them. -// #define FASTLED_ALLOW_INTERRUPTS 1 -// #define FASTLED_ALLOW_INTERRUPTS 0 - -// Use this to allow some integer overflows/underflows in the inoise functions. -// The original implementions allowed this, and had some discontinuties in the noise -// output. It's technically an implementation bug, and was fixed, but you may wish -// to preserve the old look and feel of the inoise functions in your existing animations. -// The default is 0: NO overflow, and 'continuous' noise output, aka the fixed way. -// #define FASTLED_NOISE_ALLOW_AVERAGE_TO_OVERFLOW 0 -// #define FASTLED_NOISE_ALLOW_AVERAGE_TO_OVERFLOW 1 - -// Use this toggle whether or not to use the 'fixed' FastLED scale8. The initial scale8 -// had a problem where scale8(255,255) would give you 254. This is now fixed, and that -// fix is enabled by default. However, if for some reason you have code that is not -// working right as a result of this (e.g. code that was expecting the old scale8 behavior) -// you can disable it here. -#define FASTLED_SCALE8_FIXED 1 -// #define FASTLED_SCALE8_FIXED 0 - -// Use this toggle whether to use 'fixed' FastLED pixel blending, including ColorFromPalette. -// The prior pixel blend functions had integer-rounding math errors that led to -// small errors being inadvertently added to the low bits of blended colors, including colors -// retrieved from color palettes using LINEAR_BLEND. This is now fixed, and the -// fix is enabled by default. However, if for some reason you wish to run with the old -// blending, including the integer rounding and color errors, you can disable the bugfix here. -#define FASTLED_BLEND_FIXED 1 -// #define FASTLED_BLEND_FIXED 0 - -// Use this toggle whether to use 'fixed' FastLED 8- and 16-bit noise functions. -// The prior noise functions had some math errors that led to 'discontinuities' in the -// output, which by definition should be smooth and continuous. The bug led to -// noise function output that had 'edges' and glitches in it. This is now fixed, and the -// fix is enabled by default. However, if for some reason you wish to run with the old -// noise code, including the glitches, you can disable the bugfix here. -#define FASTLED_NOISE_FIXED 1 -//#define FASTLED_NOISE_FIXED 0 - -// Use this to determine how many times FastLED will attempt to re-transmit a frame if interrupted -// for too long by interrupts. -#ifndef FASTLED_INTERRUPT_RETRY_COUNT -#define FASTLED_INTERRUPT_RETRY_COUNT 2 -#endif - -// Use this toggle to enable global brightness in contollers that support is (ADA102 and SK9822). -// It changes how color scaling works and uses global brightness before scaling down color values. -// This enable much more accurate color control on low brightness settings. -//#define FASTLED_USE_GLOBAL_BRIGHTNESS 1 - -#endif diff --git a/FastLED/src/fastled_delay.h b/FastLED/src/fastled_delay.h deleted file mode 100644 index a14e8a29416bd1b8f6165bf3077511b212ded2f5..0000000000000000000000000000000000000000 --- a/FastLED/src/fastled_delay.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef __INC_FL_DELAY_H -#define __INC_FL_DELAY_H - -#include "FastLED.h" - -///@file fastled_delay.h -///Utility functions and classes for managing delaycycles - -FASTLED_NAMESPACE_BEGIN - -/// Class to ensure that a minimum amount of time has kicked since the last time run - and delay if not enough time has passed yet -/// this should make sure that chipsets that have -template<int WAIT> class CMinWait { - uint16_t mLastMicros; - -public: - CMinWait() { mLastMicros = 0; } - - void wait() { - uint16_t diff; - do { - diff = (micros() & 0xFFFF) - mLastMicros; - } while(diff < WAIT); - } - - void mark() { mLastMicros = micros() & 0xFFFF; } -}; - - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Clock cycle counted delay loop -// -//////////////////////////////////////////////////////////////////////////////////////////// - -// Default is now just 'nop', with special case for AVR - -// ESP32 core has it's own definition of NOP, so undef it first -#ifdef ESP32 -#undef NOP -#undef NOP2 -#endif - -#if defined(__AVR__) -# define FL_NOP __asm__ __volatile__ ("cp r0,r0\n"); -# define FL_NOP2 __asm__ __volatile__ ("rjmp .+0"); -#else -# define FL_NOP __asm__ __volatile__ ("nop\n"); -# define FL_NOP2 __asm__ __volatile__ ("nop\n\t nop\n"); -#endif - -// predeclaration to not upset the compiler -template<int CYCLES> inline void delaycycles(); -template<int CYCLES> inline void delaycycles_min1() { - delaycycles<1>(); - delaycycles<CYCLES-1>(); -} - - -// TODO: ARM version of _delaycycles_ - -// usable definition -#if defined(FASTLED_AVR) -// worker template - this will nop for LOOP * 3 + PAD cycles total -template<int LOOP, int PAD> inline void _delaycycles_AVR() { - delaycycles<PAD>(); - // the loop below is 3 cycles * LOOP. the LDI is one cycle, - // the DEC is 1 cycle, the BRNE is 2 cycles if looping back and - // 1 if not (the LDI balances out the BRNE being 1 cycle on exit) - __asm__ __volatile__ ( - " LDI R16, %0\n" - "L_%=: DEC R16\n" - " BRNE L_%=\n" - : /* no outputs */ - : "M" (LOOP) - : "r16" - ); -} - -template<int CYCLES> __attribute__((always_inline)) inline void delaycycles() { - _delaycycles_AVR<CYCLES / 3, CYCLES % 3>(); -} -#else -// template<int LOOP, int PAD> inline void _delaycycles_ARM() { -// delaycycles<PAD>(); -// // the loop below is 3 cycles * LOOP. the LDI is one cycle, -// // the DEC is 1 cycle, the BRNE is 2 cycles if looping back and -// // 1 if not (the LDI balances out the BRNE being 1 cycle on exit) -// __asm__ __volatile__ ( -// " mov.w r9, %0\n" -// "L_%=: subs.w r9, r9, #1\n" -// " bne.n L_%=\n" -// : /* no outputs */ -// : "M" (LOOP) -// : "r9" -// ); -// } - - -template<int CYCLES> __attribute__((always_inline)) inline void delaycycles() { - // _delaycycles_ARM<CYCLES / 3, CYCLES % 3>(); - FL_NOP; delaycycles<CYCLES-1>(); -} -#endif - -// pre-instantiations for values small enough to not need the loop, as well as sanity holders -// for some negative values. -template<> __attribute__((always_inline)) inline void delaycycles<-10>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-9>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-8>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-7>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-6>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-5>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-4>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-3>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-2>() {} -template<> __attribute__((always_inline)) inline void delaycycles<-1>() {} -template<> __attribute__((always_inline)) inline void delaycycles<0>() {} -template<> __attribute__((always_inline)) inline void delaycycles<1>() {FL_NOP;} -template<> __attribute__((always_inline)) inline void delaycycles<2>() {FL_NOP2;} -template<> __attribute__((always_inline)) inline void delaycycles<3>() {FL_NOP;FL_NOP2;} -template<> __attribute__((always_inline)) inline void delaycycles<4>() {FL_NOP2;FL_NOP2;} -template<> __attribute__((always_inline)) inline void delaycycles<5>() {FL_NOP2;FL_NOP2;FL_NOP;} - -// Some timing related macros/definitions - -// Macro to convert from nano-seconds to clocks and clocks to nano-seconds -// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) -#define F_CPU_MHZ (F_CPU / 1000000L) - -// #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 -#define NS(_NS) (((_NS * F_CPU_MHZ) + 999) / 1000) -#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L) - -// Macro for making sure there's enough time available -#define NO_TIME(A, B, C) (NS(A) < 3 || NS(B) < 3 || NS(C) < 6) - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/fastled_progmem.h b/FastLED/src/fastled_progmem.h deleted file mode 100644 index dfcb9effb00007b9eb4d07b38bf1419791013a88..0000000000000000000000000000000000000000 --- a/FastLED/src/fastled_progmem.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef __INC_FL_PROGMEM_H -#define __INC_FL_PROGMEM_H - -#include "FastLED.h" - -///@file fastled_progmem.h -/// wrapper definitions to allow seamless use of PROGMEM in environmens that have it - -FASTLED_NAMESPACE_BEGIN - -// Compatibility layer for devices that do or don't -// have "PROGMEM" and the associated pgm_ accessors. -// -// If a platform supports PROGMEM, it should define -// "FASTLED_USE_PROGMEM" as 1, otherwise FastLED will -// fall back to NOT using PROGMEM. -// -// Whether or not pgmspace.h is #included is separately -// controllable by FASTLED_INCLUDE_PGMSPACE, if needed. - - -// If FASTLED_USE_PROGMEM is 1, we'll map FL_PROGMEM -// and the FL_PGM_* accessors to the Arduino equivalents. -#if FASTLED_USE_PROGMEM == 1 -#ifndef FASTLED_INCLUDE_PGMSPACE -#define FASTLED_INCLUDE_PGMSPACE 1 -#endif - -#if FASTLED_INCLUDE_PGMSPACE == 1 -#include <avr/pgmspace.h> -#endif - -#define FL_PROGMEM PROGMEM - -// Note: only the 'near' memory wrappers are provided. -// If you're using 'far' memory, you already have -// portability issues to work through, but you could -// add more support here if needed. -#define FL_PGM_READ_BYTE_NEAR(x) (pgm_read_byte_near(x)) -#define FL_PGM_READ_WORD_NEAR(x) (pgm_read_word_near(x)) -#define FL_PGM_READ_DWORD_NEAR(x) (pgm_read_dword_near(x)) - -// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734 -#if __GNUC__ < 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ < 6)) -#ifdef FASTLED_AVR -#ifdef PROGMEM -#undef PROGMEM -#define PROGMEM __attribute__((section(".progmem.data"))) -#endif -#endif -#endif - -#else -// If FASTLED_USE_PROGMEM is 0 or undefined, -// we'll use regular memory (RAM) access. - -//empty PROGMEM simulation -#define FL_PROGMEM -#define FL_PGM_READ_BYTE_NEAR(x) (*((const uint8_t*)(x))) -#define FL_PGM_READ_WORD_NEAR(x) (*((const uint16_t*)(x))) -#define FL_PGM_READ_DWORD_NEAR(x) (*((const uint32_t*)(x))) - -#endif - - -// On some platforms, most notably ARM M0, unaligned access -// to 'PROGMEM' for multibyte values (eg read dword) is -// not allowed and causes a crash. This macro can help -// force 4-byte alignment as needed. The FastLED gradient -// palette code uses 'read dword', and now uses this macro -// to make sure that gradient palettes are 4-byte aligned. -#if defined(FASTLED_ARM) || defined(ESP32) || defined(ESP8266) -#define FL_ALIGN_PROGMEM __attribute__ ((aligned (4))) -#else -#define FL_ALIGN_PROGMEM -#endif - - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/fastpin.h b/FastLED/src/fastpin.h deleted file mode 100644 index 085a7d1b53e03f4661c97c3e781a964dd62e1887..0000000000000000000000000000000000000000 --- a/FastLED/src/fastpin.h +++ /dev/null @@ -1,275 +0,0 @@ -#ifndef __INC_FASTPIN_H -#define __INC_FASTPIN_H - -#include "FastLED.h" - -#include "led_sysdefs.h" -#include <stddef.h> - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wignored-qualifiers" - -///@file fastpin.h -/// Class base definitions for defining fast pin access - -FASTLED_NAMESPACE_BEGIN - -#define NO_PIN 255 - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Pin access class - needs to tune for various platforms (naive fallback solution?) -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class Selectable { -public: - virtual void select() = 0; - virtual void release() = 0; - virtual bool isSelected() = 0; -}; - -#if !defined(FASTLED_NO_PINMAP) - -class Pin : public Selectable { - volatile RwReg *mPort; - volatile RoReg *mInPort; - RwReg mPinMask; - uint8_t mPin; - - void _init() { - mPinMask = digitalPinToBitMask(mPin); - mPort = (volatile RwReg*)portOutputRegister(digitalPinToPort(mPin)); - mInPort = (volatile RoReg*)portInputRegister(digitalPinToPort(mPin)); - } - -public: - Pin(int pin) : mPin(pin) { _init(); } - - typedef volatile RwReg * port_ptr_t; - typedef RwReg port_t; - - inline void setOutput() { pinMode(mPin, OUTPUT); } - inline void setInput() { pinMode(mPin, INPUT); } - - inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; } - inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; } - - inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; } - - inline void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; } - inline void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; } - inline void set(register port_t val) __attribute__ ((always_inline)) { *mPort = val; } - - inline void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; } - port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; } - port_ptr_t port() __attribute__ ((always_inline)) { return mPort; } - port_t mask() __attribute__ ((always_inline)) { return mPinMask; } - - virtual void select() { hi(); } - virtual void release() { lo(); } - virtual bool isSelected() { return (*mPort & mPinMask) == mPinMask; } -}; - -class OutputPin : public Pin { -public: - OutputPin(int pin) : Pin(pin) { setOutput(); } -}; - -class InputPin : public Pin { -public: - InputPin(int pin) : Pin(pin) { setInput(); } -}; - -#else -// This is the empty code version of the raw pin class, method bodies should be filled in to Do The Right Thing[tm] when making this -// available on a new platform -class Pin : public Selectable { - volatile RwReg *mPort; - volatile RoReg *mInPort; - RwReg mPinMask; - uint8_t mPin; - - void _init() { - // TODO: fill in init on a new platform - mPinMask = 0; - mPort = NULL; - mInPort = NULL; - } - -public: - Pin(int pin) : mPin(pin) { _init(); } - - void setPin(int pin) { mPin = pin; _init(); } - - typedef volatile RwReg * port_ptr_t; - typedef RwReg port_t; - - inline void setOutput() { /* TODO: Set pin output */ } - inline void setInput() { /* TODO: Set pin input */ } - - inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; } - inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; } - - inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; } - - inline void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; } - inline void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; } - inline void set(register port_t val) __attribute__ ((always_inline)) { *mPort = val; } - - inline void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - port_t hival() __attribute__ ((always_inline)) { return *mPort | mPinMask; } - port_t loval() __attribute__ ((always_inline)) { return *mPort & ~mPinMask; } - port_ptr_t port() __attribute__ ((always_inline)) { return mPort; } - port_t mask() __attribute__ ((always_inline)) { return mPinMask; } - - virtual void select() { hi(); } - virtual void release() { lo(); } - virtual bool isSelected() { return (*mPort & mPinMask) == mPinMask; } -}; - -class OutputPin : public Pin { -public: - OutputPin(int pin) : Pin(pin) { setOutput(); } -}; - -class InputPin : public Pin { -public: - InputPin(int pin) : Pin(pin) { setInput(); } -}; - -#endif - -/// The simplest level of Pin class. This relies on runtime functions durinig initialization to get the port/pin mask for the pin. Most -/// of the accesses involve references to these static globals that get set up. This won't be the fastest set of pin operations, but it -/// will provide pin level access on pretty much all arduino environments. In addition, it includes some methods to help optimize access in -/// various ways. Namely, the versions of hi, lo, and fastset that take the port register as a passed in register variable (saving a global -/// dereference), since these functions are aggressively inlined, that can help collapse out a lot of extraneous memory loads/dereferences. -/// -/// In addition, if, while writing a bunch of data to a pin, you know no other pins will be getting written to, you can get/cache a value of -/// the pin's port register and use that to do a full set to the register. This results in one being able to simply do a store to the register, -/// vs. the load, and/or, and store that would be done normally. -/// -/// There are platform specific instantiations of this class that provide direct i/o register access to pins for much higher speed pin twiddling. -/// -/// Note that these classes are all static functions. So the proper usage is Pin<13>::hi(); or such. Instantiating objects is not recommended, -/// as passing Pin objects around will likely -not- have the effect you're expecting. -#ifdef FASTLED_FORCE_SOFTWARE_PINS -template<uint8_t PIN> class FastPin { - static RwReg sPinMask; - static volatile RwReg *sPort; - static volatile RoReg *sInPort; - static void _init() { -#if !defined(FASTLED_NO_PINMAP) - sPinMask = digitalPinToBitMask(PIN); - sPort = portOutputRegister(digitalPinToPort(PIN)); - sInPort = portInputRegister(digitalPinToPort(PIN)); -#endif - } - -public: - typedef volatile RwReg * port_ptr_t; - typedef RwReg port_t; - - inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); } - inline static void setInput() { _init(); pinMode(PIN, INPUT); } - - inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; } - inline static void lo() __attribute__ ((always_inline)) { *sPort &= ~sPinMask; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { *sInPort = sPinMask; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { *sPort = val; } - - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - static port_t hival() __attribute__ ((always_inline)) { return *sPort | sPinMask; } - static port_t loval() __attribute__ ((always_inline)) { return *sPort & ~sPinMask; } - static port_ptr_t port() __attribute__ ((always_inline)) { return sPort; } - static port_t mask() __attribute__ ((always_inline)) { return sPinMask; } -}; - -template<uint8_t PIN> RwReg FastPin<PIN>::sPinMask; -template<uint8_t PIN> volatile RwReg *FastPin<PIN>::sPort; -template<uint8_t PIN> volatile RoReg *FastPin<PIN>::sInPort; - -#else - -template<uint8_t PIN> class FastPin { - constexpr static bool validpin() { return false; } - - static_assert(validpin(), "Invalid pin specified"); - - static void _init() { } - -public: - typedef volatile RwReg * port_ptr_t; - typedef RwReg port_t; - - inline static void setOutput() { } - inline static void setInput() { } - - inline static void hi() __attribute__ ((always_inline)) { } - inline static void lo() __attribute__ ((always_inline)) { } - - inline static void strobe() __attribute__ ((always_inline)) { } - - inline static void toggle() __attribute__ ((always_inline)) { } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { } - inline static void set(register port_t val) __attribute__ ((always_inline)) { } - - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { } - - static port_t hival() __attribute__ ((always_inline)) { return 0; } - static port_t loval() __attribute__ ((always_inline)) { return 0;} - static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; } - static port_t mask() __attribute__ ((always_inline)) { return 0; } -}; - -#endif - -template<uint8_t PIN> class FastPinBB : public FastPin<PIN> {}; - -typedef volatile uint32_t & reg32_t; -typedef volatile uint32_t * ptr_reg32_t; - -// Utility templates for tracking down information about pins and ports -template<uint8_t port> struct __FL_PORT_INFO { - static bool hasPort() { return 0; } - static const char *portName() { return "--"; } - static const void *portAddr() { return NULL; } -}; - -// Give us our instantiations for defined ports - we're going to abuse this later for -// auto discovery of pin/port mappings for new variants. Use _FL_DEFINE_PORT for ports that -// are numeric in nature, e.g. GPIO0, GPIO1. Use _FL_DEFINE_PORT3 for ports that are letters. -// The first parameter will be the letter, the second parameter will be an integer/counter of smoe kind -// (this is because attempts to turn macro parameters into character constants break in some compilers) -#define _FL_DEFINE_PORT(L, BASE) template<> struct __FL_PORT_INFO<L> { \ - static bool hasPort() { return 1; } \ - static const char *portName() { return #L; } \ - typedef BASE __t_baseType; \ - static const void *portAddr() { return (void*)&__t_baseType::r(); } }; - -#define _FL_DEFINE_PORT3(L, LC, BASE) template<> struct __FL_PORT_INFO<LC> { \ - static bool hasPort() { return 1; } \ - static const char *portName() { return #L; } \ - typedef BASE __t_baseType; \ - static const void *portAddr() { return (void*)&__t_baseType::r(); } }; - -FASTLED_NAMESPACE_END - -#pragma GCC diagnostic pop - -#endif // __INC_FASTPIN_H diff --git a/FastLED/src/fastspi.h b/FastLED/src/fastspi.h deleted file mode 100644 index 2245ffe924b447e789017af2f10dad1b48f77804..0000000000000000000000000000000000000000 --- a/FastLED/src/fastspi.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef __INC_FASTSPI_H -#define __INC_FASTSPI_H - -#include "FastLED.h" - -#include "controller.h" -#include "lib8tion.h" - -#include "fastspi_bitbang.h" - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_TEENSY3) && (F_CPU > 48000000) -#define DATA_RATE_MHZ(X) (((48000000L / 1000000L) / X)) -#define DATA_RATE_KHZ(X) (((48000000L / 1000L) / X)) -#elif defined(FASTLED_TEENSY4) // && (ARM_HARDWARE_SPI) -// just use clocks -#define DATA_RATE_MHZ(X) (1000000 * (X)) -#define DATA_RATE_KHZ(X) (1000 * (X)) -#else -#define DATA_RATE_MHZ(X) ((F_CPU / 1000000L) / X) -#define DATA_RATE_KHZ(X) ((F_CPU / 1000L) / X) -#endif - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// External SPI template definition with partial instantiation(s) to map to hardware SPI ports on platforms/builds where the pin -// mappings are known at compile time. -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#if !defined(FASTLED_ALL_PINS_HARDWARE_SPI) -template<uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class SPIOutput : public AVRSoftwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; -#endif - -template<uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class SoftwareSPIOutput : public AVRSoftwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; - -#ifndef FASTLED_FORCE_SOFTWARE_SPI - -#if defined(NRF51) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) -template<uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class SPIOutput : public NRF51SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; -#endif - -#if defined(NRF52_SERIES) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) -template<uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class SPIOutput : public NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; -#endif - -#if defined(FASTLED_APOLLO3) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) -template<uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class SPIOutput : public APOLLO3HardwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; -#endif - -#if defined(SPI_DATA) && defined(SPI_CLOCK) - -#if defined(FASTLED_TEENSY3) && defined(ARM_HARDWARE_SPI) - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED, 0x4002C000> {}; - -#if defined(SPI2_DATA) - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI2_DATA, SPI2_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI2_DATA, SPI2_CLOCK, SPI_SPEED, 0x4002C000> {}; - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI_DATA, SPI2_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI_DATA, SPI2_CLOCK, SPI_SPEED, 0x4002C000> {}; - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI2_DATA, SPI_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI2_DATA, SPI_CLOCK, SPI_SPEED, 0x4002C000> {}; -#endif - -#elif defined(FASTLED_TEENSY4) && defined(ARM_HARDWARE_SPI) - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> : public Teesy4HardwareSPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED, SPI, 0> {}; - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI1_DATA, SPI_CLOCK, SPI_SPEED> : public Teesy4HardwareSPIOutput<SPI1_DATA, SPI1_CLOCK, SPI_SPEED, SPI1, 1> {}; - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI2_DATA, SPI2_CLOCK, SPI_SPEED> : public Teesy4HardwareSPIOutput<SPI2_DATA, SPI2_CLOCK, SPI_SPEED, SPI2, 2> {}; - -#elif defined(FASTLED_TEENSYLC) && defined(ARM_HARDWARE_SPI) - -#define DECLARE_SPI0(__DATA,__CLOCK) template<uint32_t SPI_SPEED>\ - class SPIOutput<__DATA, __CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<__DATA, __CLOCK, SPI_SPEED, 0x40076000> {}; - #define DECLARE_SPI1(__DATA,__CLOCK) template<uint32_t SPI_SPEED>\ - class SPIOutput<__DATA, __CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<__DATA, __CLOCK, SPI_SPEED, 0x40077000> {}; - -DECLARE_SPI0(7,13); -DECLARE_SPI0(8,13); -DECLARE_SPI0(11,13); -DECLARE_SPI0(12,13); -DECLARE_SPI0(7,14); -DECLARE_SPI0(8,14); -DECLARE_SPI0(11,14); -DECLARE_SPI0(12,14); -DECLARE_SPI1(0,20); -DECLARE_SPI1(1,20); -DECLARE_SPI1(21,20); - -#elif defined(__SAM3X8E__) - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> : public SAMHardwareSPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> {}; - -#elif defined(AVR_HARDWARE_SPI) - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> : public AVRHardwareSPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> {}; - -#if defined(SPI_UART0_DATA) - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI_UART0_DATA, SPI_UART0_CLOCK, SPI_SPEED> : public AVRUSART0SPIOutput<SPI_UART0_DATA, SPI_UART0_CLOCK, SPI_SPEED> {}; - -#endif - -#if defined(SPI_UART1_DATA) - -template<uint32_t SPI_SPEED> -class SPIOutput<SPI_UART1_DATA, SPI_UART1_CLOCK, SPI_SPEED> : public AVRUSART1SPIOutput<SPI_UART1_DATA, SPI_UART1_CLOCK, SPI_SPEED> {}; - -#endif - -#endif - -#else -# if !defined(FASTLED_INTERNAL) && !defined(FASTLED_ALL_PINS_HARDWARE_SPI) -# ifdef FASTLED_HAS_PRAGMA_MESSAGE -# pragma message "No hardware SPI pins defined. All SPI access will default to bitbanged output" -# else -# warning "No hardware SPI pins defined. All SPI access will default to bitbanged output" -# endif -# endif -#endif - -// #if defined(USART_DATA) && defined(USART_CLOCK) -// template<uint32_t SPI_SPEED> -// class AVRSPIOutput<USART_DATA, USART_CLOCK, SPI_SPEED> : public AVRUSARTSPIOutput<USART_DATA, USART_CLOCK, SPI_SPEED> {}; -// #endif - -#else -# if !defined(FASTLED_INTERNAL) && !defined(FASTLED_ALL_PINS_HARDWARE_SPI) -# ifdef FASTLED_HAS_PRAGMA_MESSAGE -# pragma message "Forcing software SPI - no hardware SPI for you!" -# else -# warning "Forcing software SPI - no hardware SPI for you!" -# endif -# endif -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/fastspi_bitbang.h b/FastLED/src/fastspi_bitbang.h deleted file mode 100644 index 86663f17bdae289dc66dc9a700d7490412021d50..0000000000000000000000000000000000000000 --- a/FastLED/src/fastspi_bitbang.h +++ /dev/null @@ -1,381 +0,0 @@ -#ifndef __INC_FASTSPI_BITBANG_H -#define __INC_FASTSPI_BITBANG_H - -#include "FastLED.h" - -#include "fastled_delay.h" - -FASTLED_NAMESPACE_BEGIN - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Software SPI (aka bit-banging) support - with aggressive optimizations for when the clock and data pin are on the same port -// -// TODO: Replace the select pin definition with a set of pins, to allow using mux hardware for routing in the future -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, uint32_t SPI_SPEED> -class AVRSoftwareSPIOutput { - // The data types for pointers to the pin port - typedef'd here from the Pin definition because on avr these - // are pointers to 8 bit values, while on arm they are 32 bit - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<CLOCK_PIN>::port_ptr_t clock_ptr_t; - - // The data type for what's at a pin's port - typedef'd here from the Pin definition because on avr the ports - // are 8 bits wide while on arm they are 32. - typedef typename FastPin<DATA_PIN>::port_t data_t; - typedef typename FastPin<CLOCK_PIN>::port_t clock_t; - Selectable *m_pSelect; - -public: - AVRSoftwareSPIOutput() { m_pSelect = NULL; } - AVRSoftwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - void init() { - // set the pins to output and make sure the select is released (which apparently means hi? This is a bit - // confusing to me) - FastPin<DATA_PIN>::setOutput(); - FastPin<CLOCK_PIN>::setOutput(); - release(); - } - - // stop the SPI output. Pretty much a NOP with software, as there's no registers to kick - static void stop() { } - - // wait until the SPI subsystem is ready for more data to write. A NOP when bitbanging - static void wait() __attribute__((always_inline)) { } - static void waitFully() __attribute__((always_inline)) { wait(); } - - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { writeByte(b); } - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { writeByte(b); wait(); } - - static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); } - - // naive writeByte implelentation, simply calls writeBit on the 8 bits in the byte. - static void writeByte(uint8_t b) { - writeBit<7>(b); - writeBit<6>(b); - writeBit<5>(b); - writeBit<4>(b); - writeBit<3>(b); - writeBit<2>(b); - writeBit<1>(b); - writeBit<0>(b); - } - -private: - // writeByte implementation with data/clock registers passed in. - static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) { - writeBit<7>(b, clockpin, datapin); - writeBit<6>(b, clockpin, datapin); - writeBit<5>(b, clockpin, datapin); - writeBit<4>(b, clockpin, datapin); - writeBit<3>(b, clockpin, datapin); - writeBit<2>(b, clockpin, datapin); - writeBit<1>(b, clockpin, datapin); - writeBit<0>(b, clockpin, datapin); - } - - // writeByte implementation with the data register passed in and prebaked values for data hi w/clock hi and - // low and data lo w/clock hi and lo. This is to be used when clock and data are on the same GPIO register, - // can get close to getting a bit out the door in 2 clock cycles! - static void writeByte(uint8_t b, data_ptr_t datapin, - data_t hival, data_t loval, - clock_t hiclock, clock_t loclock) { - writeBit<7>(b, datapin, hival, loval, hiclock, loclock); - writeBit<6>(b, datapin, hival, loval, hiclock, loclock); - writeBit<5>(b, datapin, hival, loval, hiclock, loclock); - writeBit<4>(b, datapin, hival, loval, hiclock, loclock); - writeBit<3>(b, datapin, hival, loval, hiclock, loclock); - writeBit<2>(b, datapin, hival, loval, hiclock, loclock); - writeBit<1>(b, datapin, hival, loval, hiclock, loclock); - writeBit<0>(b, datapin, hival, loval, hiclock, loclock); - } - - // writeByte implementation with not just registers passed in, but pre-baked values for said registers for - // data hi/lo and clock hi/lo values. Note: weird things will happen if this method is called in cases where - // the data and clock pins are on the same port! Don't do that! - static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, - data_t hival, data_t loval, - clock_t hiclock, clock_t loclock) { - writeBit<7>(b, clockpin, datapin, hival, loval, hiclock, loclock); - writeBit<6>(b, clockpin, datapin, hival, loval, hiclock, loclock); - writeBit<5>(b, clockpin, datapin, hival, loval, hiclock, loclock); - writeBit<4>(b, clockpin, datapin, hival, loval, hiclock, loclock); - writeBit<3>(b, clockpin, datapin, hival, loval, hiclock, loclock); - writeBit<2>(b, clockpin, datapin, hival, loval, hiclock, loclock); - writeBit<1>(b, clockpin, datapin, hival, loval, hiclock, loclock); - writeBit<0>(b, clockpin, datapin, hival, loval, hiclock, loclock); - } - -public: - - // We want to make sure that the clock pulse is held high for a nininum of 35ns. -#if defined(FASTLED_TEENSY4) - #define DELAY_NS (1000 / (SPI_SPEED/1000000)) - #define CLOCK_HI_DELAY do { delayNanoseconds((DELAY_NS/4)); } while(0); - #define CLOCK_LO_DELAY do { delayNanoseconds((DELAY_NS/4)); } while(0); -#else - #define MIN_DELAY ((NS(35)>3) ? (NS(35) - 3) : 1) - - #define CLOCK_HI_DELAY do { delaycycles<MIN_DELAY>(); delaycycles<((SPI_SPEED > 10) ? (((SPI_SPEED-6) / 2) - MIN_DELAY) : (SPI_SPEED))>(); } while(0); - #define CLOCK_LO_DELAY do { delaycycles<((SPI_SPEED > 10) ? ((SPI_SPEED-6) / 2) : (SPI_SPEED))>(); } while(0); -#endif - - // write the BIT'th bit out via spi, setting the data pin then strobing the clcok - template <uint8_t BIT> __attribute__((always_inline, hot)) inline static void writeBit(uint8_t b) { - //cli(); - if(b & (1 << BIT)) { - FastPin<DATA_PIN>::hi(); -#ifdef ESP32 - // try to ensure we never have adjacent write opcodes to the same register - FastPin<CLOCK_PIN>::lo(); - FastPin<CLOCK_PIN>::hi(); CLOCK_HI_DELAY; - FastPin<CLOCK_PIN>::toggle(); CLOCK_LO_DELAY; -#else - FastPin<CLOCK_PIN>::hi(); CLOCK_HI_DELAY; - FastPin<CLOCK_PIN>::lo(); CLOCK_LO_DELAY; -#endif - } else { - FastPin<DATA_PIN>::lo(); - FastPin<CLOCK_PIN>::hi(); CLOCK_HI_DELAY; -#ifdef ESP32 - // try to ensure we never have adjacent write opcodes to the same register - FastPin<CLOCK_PIN>::toggle(); CLOCK_HI_DELAY; -#else - FastPin<CLOCK_PIN>::lo(); CLOCK_LO_DELAY; -#endif - } - //sei(); - } - -private: - // write the BIT'th bit out via spi, setting the data pin then strobing the clock, using the passed in pin registers to accelerate access if needed - template <uint8_t BIT> __attribute__((always_inline)) inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) { - if(b & (1 << BIT)) { - FastPin<DATA_PIN>::hi(datapin); - FastPin<CLOCK_PIN>::hi(clockpin); CLOCK_HI_DELAY; - FastPin<CLOCK_PIN>::lo(clockpin); CLOCK_LO_DELAY; - } else { - FastPin<DATA_PIN>::lo(datapin); - FastPin<CLOCK_PIN>::hi(clockpin); CLOCK_HI_DELAY; - FastPin<CLOCK_PIN>::lo(clockpin); CLOCK_LO_DELAY; - } - - } - - // the version of write to use when clock and data are on separate pins with precomputed values for setting - // the clock and data pins - template <uint8_t BIT> __attribute__((always_inline)) inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, - data_t hival, data_t loval, clock_t hiclock, clock_t loclock) { - // // only need to explicitly set clock hi if clock and data are on different ports - if(b & (1 << BIT)) { - FastPin<DATA_PIN>::fastset(datapin, hival); - FastPin<CLOCK_PIN>::fastset(clockpin, hiclock); CLOCK_HI_DELAY; - FastPin<CLOCK_PIN>::fastset(clockpin, loclock); CLOCK_LO_DELAY; - } else { - // FL_NOP; - FastPin<DATA_PIN>::fastset(datapin, loval); - FastPin<CLOCK_PIN>::fastset(clockpin, hiclock); CLOCK_HI_DELAY; - FastPin<CLOCK_PIN>::fastset(clockpin, loclock); CLOCK_LO_DELAY; - } - } - - // the version of write to use when clock and data are on the same port with precomputed values for the various - // combinations - template <uint8_t BIT> __attribute__((always_inline)) inline static void writeBit(uint8_t b, data_ptr_t clockdatapin, - data_t datahiclockhi, data_t dataloclockhi, - data_t datahiclocklo, data_t dataloclocklo) { -#if 0 - writeBit<BIT>(b); -#else - if(b & (1 << BIT)) { - FastPin<DATA_PIN>::fastset(clockdatapin, datahiclocklo); - FastPin<DATA_PIN>::fastset(clockdatapin, datahiclockhi); CLOCK_HI_DELAY; - FastPin<DATA_PIN>::fastset(clockdatapin, datahiclocklo); CLOCK_LO_DELAY; - } else { - // FL_NOP; - FastPin<DATA_PIN>::fastset(clockdatapin, dataloclocklo); - FastPin<DATA_PIN>::fastset(clockdatapin, dataloclockhi); CLOCK_HI_DELAY; - FastPin<DATA_PIN>::fastset(clockdatapin, dataloclocklo); CLOCK_LO_DELAY; - } -#endif - } - -public: - - // select the SPI output (TODO: research whether this really means hi or lo. Alt TODO: move select responsibility out of the SPI classes - // entirely, make it up to the caller to remember to lock/select the line?) - void select() { if(m_pSelect != NULL) { m_pSelect->select(); } } // FastPin<SELECT_PIN>::hi(); } - - // release the SPI line - void release() { if(m_pSelect != NULL) { m_pSelect->release(); } } // FastPin<SELECT_PIN>::lo(); } - - // Write out len bytes of the given value out over SPI. Useful for quickly flushing, say, a line of 0's down the line. - void writeBytesValue(uint8_t value, int len) { - select(); - writeBytesValueRaw(value, len); - release(); - } - - static void writeBytesValueRaw(uint8_t value, int len) { -#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS - // TODO: Weird things may happen if software bitbanging SPI output and other pins on the output reigsters are being twiddled. Need - // to allow specifying whether or not exclusive i/o access is allowed during this process, and if i/o access is not allowed fall - // back to the degenerative code below - while(len--) { - writeByte(value); - } -#else - register data_ptr_t datapin = FastPin<DATA_PIN>::port(); - - if(FastPin<DATA_PIN>::port() != FastPin<CLOCK_PIN>::port()) { - // If data and clock are on different ports, then writing a bit will consist of writing the value foor - // the bit (hi or low) to the data pin port, and then two writes to the clock port to strobe the clock line - register clock_ptr_t clockpin = FastPin<CLOCK_PIN>::port(); - register data_t datahi = FastPin<DATA_PIN>::hival(); - register data_t datalo = FastPin<DATA_PIN>::loval(); - register clock_t clockhi = FastPin<CLOCK_PIN>::hival(); - register clock_t clocklo = FastPin<CLOCK_PIN>::loval(); - while(len--) { - writeByte(value, clockpin, datapin, datahi, datalo, clockhi, clocklo); - } - - } else { - // If data and clock are on the same port then we can combine setting the data and clock pins - register data_t datahi_clockhi = FastPin<DATA_PIN>::hival() | FastPin<CLOCK_PIN>::mask(); - register data_t datalo_clockhi = FastPin<DATA_PIN>::loval() | FastPin<CLOCK_PIN>::mask(); - register data_t datahi_clocklo = FastPin<DATA_PIN>::hival() & ~FastPin<CLOCK_PIN>::mask(); - register data_t datalo_clocklo = FastPin<DATA_PIN>::loval() & ~FastPin<CLOCK_PIN>::mask(); - - while(len--) { - writeByte(value, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - } - } -#endif - } - - // write a block of len uint8_ts out. Need to type this better so that explicit casts into the call aren't required. - // note that this template version takes a class parameter for a per-byte modifier to the data. - template <class D> void writeBytes(register uint8_t *data, int len) { - select(); -#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS - uint8_t *end = data + len; - while(data != end) { - writeByte(D::adjust(*data++)); - } -#else - register clock_ptr_t clockpin = FastPin<CLOCK_PIN>::port(); - register data_ptr_t datapin = FastPin<DATA_PIN>::port(); - - if(FastPin<DATA_PIN>::port() != FastPin<CLOCK_PIN>::port()) { - // If data and clock are on different ports, then writing a bit will consist of writing the value foor - // the bit (hi or low) to the data pin port, and then two writes to the clock port to strobe the clock line - register data_t datahi = FastPin<DATA_PIN>::hival(); - register data_t datalo = FastPin<DATA_PIN>::loval(); - register clock_t clockhi = FastPin<CLOCK_PIN>::hival(); - register clock_t clocklo = FastPin<CLOCK_PIN>::loval(); - uint8_t *end = data + len; - - while(data != end) { - writeByte(D::adjust(*data++), clockpin, datapin, datahi, datalo, clockhi, clocklo); - } - - } else { - // FastPin<CLOCK_PIN>::hi(); - // If data and clock are on the same port then we can combine setting the data and clock pins - register data_t datahi_clockhi = FastPin<DATA_PIN>::hival() | FastPin<CLOCK_PIN>::mask(); - register data_t datalo_clockhi = FastPin<DATA_PIN>::loval() | FastPin<CLOCK_PIN>::mask(); - register data_t datahi_clocklo = FastPin<DATA_PIN>::hival() & ~FastPin<CLOCK_PIN>::mask(); - register data_t datalo_clocklo = FastPin<DATA_PIN>::loval() & ~FastPin<CLOCK_PIN>::mask(); - - uint8_t *end = data + len; - - while(data != end) { - writeByte(D::adjust(*data++), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - } - // FastPin<CLOCK_PIN>::lo(); - } -#endif - D::postBlock(len); - release(); - } - - // default version of writing a block of data out to the SPI port, with no data modifications being made - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning of each grouping, as well as a class specifying a per - // byte of data modification to be made. (See DATA_NOP above) - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> __attribute__((noinline)) void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - int len = pixels.mLen; - -#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS - // If interrupts or other things may be generating output while we're working on things, then we need - // to use this block - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - } - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - pixels.advanceData(); - pixels.stepDithering(); - } -#else - // If we can guaruntee that no one else will be writing data while we are running (namely, changing the values of the PORT/PDOR pins) - // then we can use a bunch of optimizations in here - register data_ptr_t datapin = FastPin<DATA_PIN>::port(); - - if(FastPin<DATA_PIN>::port() != FastPin<CLOCK_PIN>::port()) { - register clock_ptr_t clockpin = FastPin<CLOCK_PIN>::port(); - // If data and clock are on different ports, then writing a bit will consist of writing the value foor - // the bit (hi or low) to the data pin port, and then two writes to the clock port to strobe the clock line - register data_t datahi = FastPin<DATA_PIN>::hival(); - register data_t datalo = FastPin<DATA_PIN>::loval(); - register clock_t clockhi = FastPin<CLOCK_PIN>::hival(); - register clock_t clocklo = FastPin<CLOCK_PIN>::loval(); - - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1, clockpin, datapin, datahi, datalo, clockhi, clocklo); - } - writeByte(D::adjust(pixels.loadAndScale0()), clockpin, datapin, datahi, datalo, clockhi, clocklo); - writeByte(D::adjust(pixels.loadAndScale1()), clockpin, datapin, datahi, datalo, clockhi, clocklo); - writeByte(D::adjust(pixels.loadAndScale2()), clockpin, datapin, datahi, datalo, clockhi, clocklo); - pixels.advanceData(); - pixels.stepDithering(); - } - - } else { - // If data and clock are on the same port then we can combine setting the data and clock pins - register data_t datahi_clockhi = FastPin<DATA_PIN>::hival() | FastPin<CLOCK_PIN>::mask(); - register data_t datalo_clockhi = FastPin<DATA_PIN>::loval() | FastPin<CLOCK_PIN>::mask(); - register data_t datahi_clocklo = FastPin<DATA_PIN>::hival() & ~FastPin<CLOCK_PIN>::mask(); - register data_t datalo_clocklo = FastPin<DATA_PIN>::loval() & ~FastPin<CLOCK_PIN>::mask(); - - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - } - writeByte(D::adjust(pixels.loadAndScale0()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - writeByte(D::adjust(pixels.loadAndScale1()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - writeByte(D::adjust(pixels.loadAndScale2()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - pixels.advanceData(); - pixels.stepDithering(); - } - } -#endif - D::postBlock(len); - release(); - } -}; - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/fastspi_dma.h b/FastLED/src/fastspi_dma.h deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/FastLED/src/fastspi_nop.h b/FastLED/src/fastspi_nop.h deleted file mode 100644 index 1dcd2961e0f84ea67cc3db0cce2b868caae91bf8..0000000000000000000000000000000000000000 --- a/FastLED/src/fastspi_nop.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef __INC_FASTSPI_NOP_H -#define __INC_FASTSPI_NOP_H - -#if 0 // Guard against the arduino ide idiotically including every header file - -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -/// A nop/stub class, mostly to show the SPI methods that are needed/used by the various SPI chipset implementations. Should -/// be used as a definition for the set of methods that the spi implementation classes should use (since C++ doesn't support the -/// idea of interfaces - it's possible this could be done with virtual classes, need to decide if i want that overhead) -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class NOPSPIOutput { - Selectable *m_pSelect; - -public: - NOPSPIOutput() { m_pSelect = NULL; } - NOPSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - - /// set the object representing the selectable - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - /// initialize the SPI subssytem - void init() { /* TODO */ } - - /// latch the CS select - void select() { /* TODO */ } - - /// release the CS select - void release() { /* TODO */ } - - /// wait until all queued up data has been written - void waitFully(); - - /// not the most efficient mechanism in the world - but should be enough for sm16716 and friends - template <uint8_t BIT> inline static void writeBit(uint8_t b) { /* TODO */ } - - /// write a byte out via SPI (returns immediately on writing register) - void writeByte(uint8_t b) { /* TODO */ } - /// write a word out via SPI (returns immediately on writing register) - void writeWord(uint16_t w) { /* TODO */ } - - /// A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes) - static void writeBytesValueRaw(uint8_t value, int len) { /* TODO */ } - - /// A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytesValue(uint8_t value, int len) { /* TODO */ } - - /// A full cycle of writing a raw block of data out, including select, release, and waiting - void writeBytes(uint8_t *data, int len) { /* TODO */ } - - /// write a single bit out, which bit from the passed in byte is determined by template parameter - template <uint8_t BIT> inline static void writeBit(uint8_t b) { /* TODO */ } - - /// write out pixel data from the given PixelController object - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { /* TODO */ } - -}; - -FASTLED_NAMESPACE_END - -#endif -#endif diff --git a/FastLED/src/fastspi_ref.h b/FastLED/src/fastspi_ref.h deleted file mode 100644 index a12a962ae8d126a62622b1d5bdfbf09eb703f7e2..0000000000000000000000000000000000000000 --- a/FastLED/src/fastspi_ref.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef __INC_FASTSPI_ARM_SAM_H -#define __INC_FASTSPI_ARM_SAM_H - -#if 0 // guard against the arduino ide idiotically including every header file -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -// A skeletal implementation of hardware SPI support. Fill in the necessary code for init, waiting, and writing. The rest of -// the method implementations should provide a starting point, even if not hte most efficient to start with -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class REFHardwareSPIOutput { - Selectable *m_pSelect; - -public: - SAMHardwareSPIOutput() { m_pSelect = NULL; } - SAMHArdwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - - // set the object representing the selectable - void setSelect(Selectable *pSelect) { /* TODO */ } - - // initialize the SPI subssytem - void init() { /* TODO */ } - - // latch the CS select - void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->select(); } } - - // release the CS select - void inline release() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->release(); } } - - // wait until all queued up data has been written - static void waitFully() { /* TODO */ } - - // write a byte out via SPI (returns immediately on writing register) - static void writeByte(uint8_t b) { /* TODO */ } - - // write a word out via SPI (returns immediately on writing register) - static void writeWord(uint16_t w) { /* TODO */ } - - // A raw set of writing byte values, assumes setup/init/waiting done elsewhere - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { writeByte(value); } - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytesValue(uint8_t value, int len) { - select(); writeBytesValueRaw(value, len); release(); - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - template <class D> void writeBytes(register uint8_t *data, int len) { - uint8_t *end = data + len; - select(); - // could be optimized to write 16bit words out instead of 8bit bytes - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a single bit out, which bit from the passed in byte is determined by template parameter - template <uint8_t BIT> inline static void writeBit(uint8_t b) { /* TODO */ } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - while(data != end) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - } - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - - pixels.advanceData(); - pixels.stepDithering(); - data += (3+skip); - } - D::postBlock(len); - release(); - } - -}; - -FASTLED_NAMESPACE_END - -#endif - -#endif - diff --git a/FastLED/src/fastspi_types.h b/FastLED/src/fastspi_types.h deleted file mode 100644 index ea7d46ce39925d43e0e55c6054e48c6263c0af27..0000000000000000000000000000000000000000 --- a/FastLED/src/fastspi_types.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __INC_FASTSPI_TYPES_H -#define __INC_FASTSPI_TYPES_H - -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -// Some helper macros for getting at mis-ordered byte values -#define SPI_B0 (RGB_BYTE0(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) -#define SPI_B1 (RGB_BYTE1(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) -#define SPI_B2 (RGB_BYTE2(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) -#define SPI_ADVANCE (3 + (MASK_SKIP_BITS & SKIP)) - -/// Some of the SPI controllers will need to perform a transform on each byte before doing -/// anyting with it. Creating a class of this form and passing it in as a template parameter to -/// writeBytes/writeBytes3 below will ensure that the body of this method will get called on every -/// byte worked on. Recommendation, make the adjust method aggressively inlined. -/// -/// TODO: Convinience macro for building these -class DATA_NOP { -public: - static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data) { return data; } - static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data, register uint8_t scale) { return scale8(data, scale); } - static __attribute__((always_inline)) inline void postBlock(int /* len */) { } -}; - -#define FLAG_START_BIT 0x80 -#define MASK_SKIP_BITS 0x3F - -// Clock speed dividers -#define SPEED_DIV_2 2 -#define SPEED_DIV_4 4 -#define SPEED_DIV_8 8 -#define SPEED_DIV_16 16 -#define SPEED_DIV_32 32 -#define SPEED_DIV_64 64 -#define SPEED_DIV_128 128 - -#define MAX_DATA_RATE 0 - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/hsv2rgb.cpp b/FastLED/src/hsv2rgb.cpp deleted file mode 100644 index 1fb8d56b775ff424e6794070fb1a81a2249a626b..0000000000000000000000000000000000000000 --- a/FastLED/src/hsv2rgb.cpp +++ /dev/null @@ -1,714 +0,0 @@ -#define FASTLED_INTERNAL -#include <stdint.h> - -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -// Functions to convert HSV colors to RGB colors. -// -// The basically fall into two groups: spectra, and rainbows. -// Spectra and rainbows are not the same thing. Wikipedia has a good -// illustration here -// http://upload.wikimedia.org/wikipedia/commons/f/f6/Prism_compare_rainbow_01.png -// from this article -// http://en.wikipedia.org/wiki/Rainbow#Number_of_colours_in_spectrum_or_rainbow -// that shows a 'spectrum' and a 'rainbow' side by side. Among other -// differences, you'll see that a 'rainbow' has much more yellow than -// a plain spectrum. "Classic" LED color washes are spectrum based, and -// usually show very little yellow. -// -// Wikipedia's page on HSV color space, with pseudocode for conversion -// to RGB color space -// http://en.wikipedia.org/wiki/HSL_and_HSV -// Note that their conversion algorithm, which is (naturally) very popular -// is in the "maximum brightness at any given hue" style, vs the "uniform -// brightness for all hues" style. -// -// You can't have both; either purple is the same brightness as red, e.g -// red = #FF0000 and purple = #800080 -> same "total light" output -// OR purple is 'as bright as it can be', e.g. -// red = #FF0000 and purple = #FF00FF -> purple is much brighter than red. -// The colorspace conversions here try to keep the apparent brightness -// constant even as the hue varies. -// -// Adafruit's "Wheel" function, discussed here -// http://forums.adafruit.com/viewtopic.php?f=47&t=22483 -// is also of the "constant apparent brightness" variety. -// -// TODO: provide the 'maximum brightness no matter what' variation. -// -// See also some good, clear Arduino C code from Kasper Kamperman -// http://www.kasperkamperman.com/blog/arduino/arduino-programming-hsb-to-rgb/ -// which in turn was was based on Windows C code from "nico80" -// http://www.codeproject.com/Articles/9207/An-HSB-RGBA-colour-picker - - - - - -void hsv2rgb_raw_C (const struct CHSV & hsv, struct CRGB & rgb); -void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb); - -#if defined(__AVR__) && !defined( LIB8_ATTINY ) -void hsv2rgb_raw(const struct CHSV & hsv, struct CRGB & rgb) -{ - hsv2rgb_raw_avr( hsv, rgb); -} -#else -void hsv2rgb_raw(const struct CHSV & hsv, struct CRGB & rgb) -{ - hsv2rgb_raw_C( hsv, rgb); -} -#endif - - - -#define APPLY_DIMMING(X) (X) -#define HSV_SECTION_6 (0x20) -#define HSV_SECTION_3 (0x40) - -void hsv2rgb_raw_C (const struct CHSV & hsv, struct CRGB & rgb) -{ - // Convert hue, saturation and brightness ( HSV/HSB ) to RGB - // "Dimming" is used on saturation and brightness to make - // the output more visually linear. - - // Apply dimming curves - uint8_t value = APPLY_DIMMING( hsv.val); - uint8_t saturation = hsv.sat; - - // The brightness floor is minimum number that all of - // R, G, and B will be set to. - uint8_t invsat = APPLY_DIMMING( 255 - saturation); - uint8_t brightness_floor = (value * invsat) / 256; - - // The color amplitude is the maximum amount of R, G, and B - // that will be added on top of the brightness_floor to - // create the specific hue desired. - uint8_t color_amplitude = value - brightness_floor; - - // Figure out which section of the hue wheel we're in, - // and how far offset we are withing that section - uint8_t section = hsv.hue / HSV_SECTION_3; // 0..2 - uint8_t offset = hsv.hue % HSV_SECTION_3; // 0..63 - - uint8_t rampup = offset; // 0..63 - uint8_t rampdown = (HSV_SECTION_3 - 1) - offset; // 63..0 - - // We now scale rampup and rampdown to a 0-255 range -- at least - // in theory, but here's where architecture-specific decsions - // come in to play: - // To scale them up to 0-255, we'd want to multiply by 4. - // But in the very next step, we multiply the ramps by other - // values and then divide the resulting product by 256. - // So which is faster? - // ((ramp * 4) * othervalue) / 256 - // or - // ((ramp ) * othervalue) / 64 - // It depends on your processor architecture. - // On 8-bit AVR, the "/ 256" is just a one-cycle register move, - // but the "/ 64" might be a multicycle shift process. So on AVR - // it's faster do multiply the ramp values by four, and then - // divide by 256. - // On ARM, the "/ 256" and "/ 64" are one cycle each, so it's - // faster to NOT multiply the ramp values by four, and just to - // divide the resulting product by 64 (instead of 256). - // Moral of the story: trust your profiler, not your insticts. - - // Since there's an AVR assembly version elsewhere, we'll - // assume what we're on an architecture where any number of - // bit shifts has roughly the same cost, and we'll remove the - // redundant math at the source level: - - // // scale up to 255 range - // //rampup *= 4; // 0..252 - // //rampdown *= 4; // 0..252 - - // compute color-amplitude-scaled-down versions of rampup and rampdown - uint8_t rampup_amp_adj = (rampup * color_amplitude) / (256 / 4); - uint8_t rampdown_amp_adj = (rampdown * color_amplitude) / (256 / 4); - - // add brightness_floor offset to everything - uint8_t rampup_adj_with_floor = rampup_amp_adj + brightness_floor; - uint8_t rampdown_adj_with_floor = rampdown_amp_adj + brightness_floor; - - - if( section ) { - if( section == 1) { - // section 1: 0x40..0x7F - rgb.r = brightness_floor; - rgb.g = rampdown_adj_with_floor; - rgb.b = rampup_adj_with_floor; - } else { - // section 2; 0x80..0xBF - rgb.r = rampup_adj_with_floor; - rgb.g = brightness_floor; - rgb.b = rampdown_adj_with_floor; - } - } else { - // section 0: 0x00..0x3F - rgb.r = rampdown_adj_with_floor; - rgb.g = rampup_adj_with_floor; - rgb.b = brightness_floor; - } -} - - - -#if defined(__AVR__) && !defined( LIB8_ATTINY ) -void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb) -{ - uint8_t hue, saturation, value; - - hue = hsv.hue; - saturation = hsv.sat; - value = hsv.val; - - // Saturation more useful the other way around - saturation = 255 - saturation; - uint8_t invsat = APPLY_DIMMING( saturation ); - - // Apply dimming curves - value = APPLY_DIMMING( value ); - - // The brightness floor is minimum number that all of - // R, G, and B will be set to, which is value * invsat - uint8_t brightness_floor; - - asm volatile( - "mul %[value], %[invsat] \n" - "mov %[brightness_floor], r1 \n" - : [brightness_floor] "=r" (brightness_floor) - : [value] "r" (value), - [invsat] "r" (invsat) - : "r0", "r1" - ); - - // The color amplitude is the maximum amount of R, G, and B - // that will be added on top of the brightness_floor to - // create the specific hue desired. - uint8_t color_amplitude = value - brightness_floor; - - // Figure how far we are offset into the section of the - // color wheel that we're in - uint8_t offset = hsv.hue & (HSV_SECTION_3 - 1); // 0..63 - uint8_t rampup = offset * 4; // 0..252 - - - // compute color-amplitude-scaled-down versions of rampup and rampdown - uint8_t rampup_amp_adj; - uint8_t rampdown_amp_adj; - - asm volatile( - "mul %[rampup], %[color_amplitude] \n" - "mov %[rampup_amp_adj], r1 \n" - "com %[rampup] \n" - "mul %[rampup], %[color_amplitude] \n" - "mov %[rampdown_amp_adj], r1 \n" - : [rampup_amp_adj] "=&r" (rampup_amp_adj), - [rampdown_amp_adj] "=&r" (rampdown_amp_adj), - [rampup] "+r" (rampup) - : [color_amplitude] "r" (color_amplitude) - : "r0", "r1" - ); - - - // add brightness_floor offset to everything - uint8_t rampup_adj_with_floor = rampup_amp_adj + brightness_floor; - uint8_t rampdown_adj_with_floor = rampdown_amp_adj + brightness_floor; - - - // keep gcc from using "X" as the index register for storing - // results back in the return structure. AVR's X register can't - // do "std X+q, rnn", but the Y and Z registers can. - // if the pointer to 'rgb' is in X, gcc will add all kinds of crazy - // extra instructions. Simply killing X here seems to help it - // try Y or Z first. - asm volatile( "" : : : "r26", "r27" ); - - - if( hue & 0x80 ) { - // section 2: 0x80..0xBF - rgb.r = rampup_adj_with_floor; - rgb.g = brightness_floor; - rgb.b = rampdown_adj_with_floor; - } else { - if( hue & 0x40) { - // section 1: 0x40..0x7F - rgb.r = brightness_floor; - rgb.g = rampdown_adj_with_floor; - rgb.b = rampup_adj_with_floor; - } else { - // section 0: 0x00..0x3F - rgb.r = rampdown_adj_with_floor; - rgb.g = rampup_adj_with_floor; - rgb.b = brightness_floor; - } - } - - cleanup_R1(); -} -// End of AVR asm implementation - -#endif - -void hsv2rgb_spectrum( const CHSV& hsv, CRGB& rgb) -{ - CHSV hsv2(hsv); - hsv2.hue = scale8( hsv2.hue, 191); - hsv2rgb_raw(hsv2, rgb); -} - - -// Sometimes the compiler will do clever things to reduce -// code size that result in a net slowdown, if it thinks that -// a variable is not used in a certain location. -// This macro does its best to convince the compiler that -// the variable is used in this location, to help control -// code motion and de-duplication that would result in a slowdown. -#define FORCE_REFERENCE(var) asm volatile( "" : : "r" (var) ) - - -#define K255 255 -#define K171 171 -#define K170 170 -#define K85 85 - -void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) -{ - // Yellow has a higher inherent brightness than - // any other color; 'pure' yellow is perceived to - // be 93% as bright as white. In order to make - // yellow appear the correct relative brightness, - // it has to be rendered brighter than all other - // colors. - // Level Y1 is a moderate boost, the default. - // Level Y2 is a strong boost. - const uint8_t Y1 = 1; - const uint8_t Y2 = 0; - - // G2: Whether to divide all greens by two. - // Depends GREATLY on your particular LEDs - const uint8_t G2 = 0; - - // Gscale: what to scale green down by. - // Depends GREATLY on your particular LEDs - const uint8_t Gscale = 0; - - - uint8_t hue = hsv.hue; - uint8_t sat = hsv.sat; - uint8_t val = hsv.val; - - uint8_t offset = hue & 0x1F; // 0..31 - - // offset8 = offset * 8 - uint8_t offset8 = offset; - { -#if defined(__AVR__) - // Left to its own devices, gcc turns "x <<= 3" into a loop - // It's much faster and smaller to just do three single-bit shifts - // So this business is to force that. - offset8 <<= 1; - asm volatile(""); - offset8 <<= 1; - asm volatile(""); - offset8 <<= 1; -#else - // On ARM and other non-AVR platforms, we just shift 3. - offset8 <<= 3; -#endif - } - - uint8_t third = scale8( offset8, (256 / 3)); // max = 85 - - uint8_t r, g, b; - - if( ! (hue & 0x80) ) { - // 0XX - if( ! (hue & 0x40) ) { - // 00X - //section 0-1 - if( ! (hue & 0x20) ) { - // 000 - //case 0: // R -> O - r = K255 - third; - g = third; - b = 0; - FORCE_REFERENCE(b); - } else { - // 001 - //case 1: // O -> Y - if( Y1 ) { - r = K171; - g = K85 + third ; - b = 0; - FORCE_REFERENCE(b); - } - if( Y2 ) { - r = K170 + third; - //uint8_t twothirds = (third << 1); - uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170 - g = K85 + twothirds; - b = 0; - FORCE_REFERENCE(b); - } - } - } else { - //01X - // section 2-3 - if( ! (hue & 0x20) ) { - // 010 - //case 2: // Y -> G - if( Y1 ) { - //uint8_t twothirds = (third << 1); - uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170 - r = K171 - twothirds; - g = K170 + third; - b = 0; - FORCE_REFERENCE(b); - } - if( Y2 ) { - r = K255 - offset8; - g = K255; - b = 0; - FORCE_REFERENCE(b); - } - } else { - // 011 - // case 3: // G -> A - r = 0; - FORCE_REFERENCE(r); - g = K255 - third; - b = third; - } - } - } else { - // section 4-7 - // 1XX - if( ! (hue & 0x40) ) { - // 10X - if( ! ( hue & 0x20) ) { - // 100 - //case 4: // A -> B - r = 0; - FORCE_REFERENCE(r); - //uint8_t twothirds = (third << 1); - uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170 - g = K171 - twothirds; //K170? - b = K85 + twothirds; - - } else { - // 101 - //case 5: // B -> P - r = third; - g = 0; - FORCE_REFERENCE(g); - b = K255 - third; - - } - } else { - if( ! (hue & 0x20) ) { - // 110 - //case 6: // P -- K - r = K85 + third; - g = 0; - FORCE_REFERENCE(g); - b = K171 - third; - - } else { - // 111 - //case 7: // K -> R - r = K170 + third; - g = 0; - FORCE_REFERENCE(g); - b = K85 - third; - - } - } - } - - // This is one of the good places to scale the green down, - // although the client can scale green down as well. - if( G2 ) g = g >> 1; - if( Gscale ) g = scale8_video_LEAVING_R1_DIRTY( g, Gscale); - - // Scale down colors if we're desaturated at all - // and add the brightness_floor to r, g, and b. - if( sat != 255 ) { - if( sat == 0) { - r = 255; b = 255; g = 255; - } else { - //nscale8x3_video( r, g, b, sat); -#if (FASTLED_SCALE8_FIXED==1) - if( r ) r = scale8_LEAVING_R1_DIRTY( r, sat); - if( g ) g = scale8_LEAVING_R1_DIRTY( g, sat); - if( b ) b = scale8_LEAVING_R1_DIRTY( b, sat); -#else - if( r ) r = scale8_LEAVING_R1_DIRTY( r, sat) + 1; - if( g ) g = scale8_LEAVING_R1_DIRTY( g, sat) + 1; - if( b ) b = scale8_LEAVING_R1_DIRTY( b, sat) + 1; -#endif - cleanup_R1(); - - uint8_t desat = 255 - sat; - desat = scale8( desat, desat); - - uint8_t brightness_floor = desat; - r += brightness_floor; - g += brightness_floor; - b += brightness_floor; - } - } - - // Now scale everything down if we're at value < 255. - if( val != 255 ) { - - val = scale8_video_LEAVING_R1_DIRTY( val, val); - if( val == 0 ) { - r=0; g=0; b=0; - } else { - // nscale8x3_video( r, g, b, val); -#if (FASTLED_SCALE8_FIXED==1) - if( r ) r = scale8_LEAVING_R1_DIRTY( r, val); - if( g ) g = scale8_LEAVING_R1_DIRTY( g, val); - if( b ) b = scale8_LEAVING_R1_DIRTY( b, val); -#else - if( r ) r = scale8_LEAVING_R1_DIRTY( r, val) + 1; - if( g ) g = scale8_LEAVING_R1_DIRTY( g, val) + 1; - if( b ) b = scale8_LEAVING_R1_DIRTY( b, val) + 1; -#endif - cleanup_R1(); - } - } - - // Here we have the old AVR "missing std X+n" problem again - // It turns out that fixing it winds up costing more than - // not fixing it. - // To paraphrase Dr Bronner, profile! profile! profile! - //asm volatile( "" : : : "r26", "r27" ); - //asm volatile (" movw r30, r26 \n" : : : "r30", "r31"); - rgb.r = r; - rgb.g = g; - rgb.b = b; -} - - -void hsv2rgb_raw(const struct CHSV * phsv, struct CRGB * prgb, int numLeds) { - for(int i = 0; i < numLeds; ++i) { - hsv2rgb_raw(phsv[i], prgb[i]); - } -} - -void hsv2rgb_rainbow( const struct CHSV* phsv, struct CRGB * prgb, int numLeds) { - for(int i = 0; i < numLeds; ++i) { - hsv2rgb_rainbow(phsv[i], prgb[i]); - } -} - -void hsv2rgb_spectrum( const struct CHSV* phsv, struct CRGB * prgb, int numLeds) { - for(int i = 0; i < numLeds; ++i) { - hsv2rgb_spectrum(phsv[i], prgb[i]); - } -} - - - -#define FIXFRAC8(N,D) (((N)*256)/(D)) - -// This function is only an approximation, and it is not -// nearly as fast as the normal HSV-to-RGB conversion. -// See extended notes in the .h file. -CHSV rgb2hsv_approximate( const CRGB& rgb) -{ - uint8_t r = rgb.r; - uint8_t g = rgb.g; - uint8_t b = rgb.b; - uint8_t h, s, v; - - // find desaturation - uint8_t desat = 255; - if( r < desat) desat = r; - if( g < desat) desat = g; - if( b < desat) desat = b; - - // remove saturation from all channels - r -= desat; - g -= desat; - b -= desat; - - //Serial.print("desat="); Serial.print(desat); Serial.println(""); - - //uint8_t orig_desat = sqrt16( desat * 256); - //Serial.print("orig_desat="); Serial.print(orig_desat); Serial.println(""); - - // saturation is opposite of desaturation - s = 255 - desat; - //Serial.print("s.1="); Serial.print(s); Serial.println(""); - - if( s != 255 ) { - // undo 'dimming' of saturation - s = 255 - sqrt16( (255-s) * 256); - } - // without lib8tion: float ... ew ... sqrt... double ew, or rather, ew ^ 0.5 - // if( s != 255 ) s = (255 - (256.0 * sqrt( (float)(255-s) / 256.0))); - //Serial.print("s.2="); Serial.print(s); Serial.println(""); - - - // at least one channel is now zero - // if all three channels are zero, we had a - // shade of gray. - if( (r + g + b) == 0) { - // we pick hue zero for no special reason - return CHSV( 0, 0, 255 - s); - } - - // scale all channels up to compensate for desaturation - if( s < 255) { - if( s == 0) s = 1; - uint32_t scaleup = 65535 / (s); - r = ((uint32_t)(r) * scaleup) / 256; - g = ((uint32_t)(g) * scaleup) / 256; - b = ((uint32_t)(b) * scaleup) / 256; - } - //Serial.print("r.2="); Serial.print(r); Serial.println(""); - //Serial.print("g.2="); Serial.print(g); Serial.println(""); - //Serial.print("b.2="); Serial.print(b); Serial.println(""); - - uint16_t total = r + g + b; - - //Serial.print("total="); Serial.print(total); Serial.println(""); - - // scale all channels up to compensate for low values - if( total < 255) { - if( total == 0) total = 1; - uint32_t scaleup = 65535 / (total); - r = ((uint32_t)(r) * scaleup) / 256; - g = ((uint32_t)(g) * scaleup) / 256; - b = ((uint32_t)(b) * scaleup) / 256; - } - //Serial.print("r.3="); Serial.print(r); Serial.println(""); - //Serial.print("g.3="); Serial.print(g); Serial.println(""); - //Serial.print("b.3="); Serial.print(b); Serial.println(""); - - if( total > 255 ) { - v = 255; - } else { - v = qadd8(desat,total); - // undo 'dimming' of brightness - if( v != 255) v = sqrt16( v * 256); - // without lib8tion: float ... ew ... sqrt... double ew, or rather, ew ^ 0.5 - // if( v != 255) v = (256.0 * sqrt( (float)(v) / 256.0)); - - } - - //Serial.print("v="); Serial.print(v); Serial.println(""); - - -#if 0 - - //#else - if( v != 255) { - // this part could probably use refinement/rethinking, - // (but it doesn't overflow & wrap anymore) - uint16_t s16; - s16 = (s * 256); - s16 /= v; - //Serial.print("s16="); Serial.print(s16); Serial.println(""); - if( s16 < 256) { - s = s16; - } else { - s = 255; // clamp to prevent overflow - } - } -#endif - - //Serial.print("s.3="); Serial.print(s); Serial.println(""); - - - // since this wasn't a pure shade of gray, - // the interesting question is what hue is it - - - - // start with which channel is highest - // (ties don't matter) - uint8_t highest = r; - if( g > highest) highest = g; - if( b > highest) highest = b; - - if( highest == r ) { - // Red is highest. - // Hue could be Purple/Pink-Red,Red-Orange,Orange-Yellow - if( g == 0 ) { - // if green is zero, we're in Purple/Pink-Red - h = (HUE_PURPLE + HUE_PINK) / 2; - h += scale8( qsub8(r, 128), FIXFRAC8(48,128)); - } else if ( (r - g) > g) { - // if R-G > G then we're in Red-Orange - h = HUE_RED; - h += scale8( g, FIXFRAC8(32,85)); - } else { - // R-G < G, we're in Orange-Yellow - h = HUE_ORANGE; - h += scale8( qsub8((g - 85) + (171 - r), 4), FIXFRAC8(32,85)); //221 - } - - } else if ( highest == g) { - // Green is highest - // Hue could be Yellow-Green, Green-Aqua - if( b == 0) { - // if Blue is zero, we're in Yellow-Green - // G = 171..255 - // R = 171.. 0 - h = HUE_YELLOW; - uint8_t radj = scale8( qsub8(171,r), 47); //171..0 -> 0..171 -> 0..31 - uint8_t gadj = scale8( qsub8(g,171), 96); //171..255 -> 0..84 -> 0..31; - uint8_t rgadj = radj + gadj; - uint8_t hueadv = rgadj / 2; - h += hueadv; - //h += scale8( qadd8( 4, qadd8((g - 128), (128 - r))), - // FIXFRAC8(32,255)); // - } else { - // if Blue is nonzero we're in Green-Aqua - if( (g-b) > b) { - h = HUE_GREEN; - h += scale8( b, FIXFRAC8(32,85)); - } else { - h = HUE_AQUA; - h += scale8( qsub8(b, 85), FIXFRAC8(8,42)); - } - } - - } else /* highest == b */ { - // Blue is highest - // Hue could be Aqua/Blue-Blue, Blue-Purple, Purple-Pink - if( r == 0) { - // if red is zero, we're in Aqua/Blue-Blue - h = HUE_AQUA + ((HUE_BLUE - HUE_AQUA) / 4); - h += scale8( qsub8(b, 128), FIXFRAC8(24,128)); - } else if ( (b-r) > r) { - // B-R > R, we're in Blue-Purple - h = HUE_BLUE; - h += scale8( r, FIXFRAC8(32,85)); - } else { - // B-R < R, we're in Purple-Pink - h = HUE_PURPLE; - h += scale8( qsub8(r, 85), FIXFRAC8(32,85)); - } - } - - h += 1; - return CHSV( h, s, v); -} - -// Examples that need work: -// 0,192,192 -// 192,64,64 -// 224,32,32 -// 252,0,126 -// 252,252,0 -// 252,252,126 - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/hsv2rgb.h b/FastLED/src/hsv2rgb.h deleted file mode 100644 index ddc63baf862ac0d46f88f33a746612aaf363dd73..0000000000000000000000000000000000000000 --- a/FastLED/src/hsv2rgb.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef __INC_HSV2RGB_H -#define __INC_HSV2RGB_H - -#include "FastLED.h" - -#include "pixeltypes.h" - -FASTLED_NAMESPACE_BEGIN - -// hsv2rgb_rainbow - convert a hue, saturation, and value to RGB -// using a visually balanced rainbow (vs a straight -// mathematical spectrum). -// This 'rainbow' yields better yellow and orange -// than a straight 'spectrum'. -// -// NOTE: here hue is 0-255, not just 0-191 - -void hsv2rgb_rainbow( const struct CHSV& hsv, struct CRGB& rgb); -void hsv2rgb_rainbow( const struct CHSV* phsv, struct CRGB * prgb, int numLeds); -#define HUE_MAX_RAINBOW 255 - - -// hsv2rgb_spectrum - convert a hue, saturation, and value to RGB -// using a mathematically straight spectrum (vs -// a visually balanced rainbow). -// This 'spectrum' will have more green & blue -// than a 'rainbow', and less yellow and orange. -// -// NOTE: here hue is 0-255, not just 0-191 - -void hsv2rgb_spectrum( const struct CHSV& hsv, struct CRGB& rgb); -void hsv2rgb_spectrum( const struct CHSV* phsv, struct CRGB * prgb, int numLeds); -#define HUE_MAX_SPECTRUM 255 - - -// hsv2rgb_raw - convert hue, saturation, and value to RGB. -// This 'spectrum' conversion will be more green & blue -// than a real 'rainbow', and the hue is specified just -// in the range 0-191. Together, these result in a -// slightly faster conversion speed, at the expense of -// color balance. -// -// NOTE: Hue is 0-191 only! -// Saturation & value are 0-255 each. -// - -void hsv2rgb_raw(const struct CHSV& hsv, struct CRGB & rgb); -void hsv2rgb_raw(const struct CHSV* phsv, struct CRGB * prgb, int numLeds); -#define HUE_MAX 191 - - -// rgb2hsv_approximate - recover _approximate_ HSV values from RGB. -// -// NOTE 1: This function is a long-term work in process; expect -// results to change slightly over time as this function is -// refined and improved. -// -// NOTE 2: This function is most accurate when the input is an -// RGB color that came from a fully-saturated HSV color to start -// with. E.g. CHSV( hue, 255, 255) -> CRGB -> CHSV will give -// best results. -// -// NOTE 3: This function is not nearly as fast as HSV-to-RGB. -// It is provided for those situations when the need for this -// function cannot be avoided, or when extremely high performance -// is not needed. -// -// NOTE 4: Why is this 'only' an "approximation"? -// Not all RGB colors have HSV equivalents! For example, there -// is no HSV value that will ever convert to RGB(255,255,0) using -// the code provided in this library. So if you try to -// convert RGB(255,255,0) 'back' to HSV, you'll necessarily get -// only an approximation. Emphasis has been placed on getting -// the 'hue' as close as usefully possible, but even that's a bit -// of a challenge. The 8-bit HSV and 8-bit RGB color spaces -// are not a "bijection". -// -// Nevertheless, this function does a pretty good job, particularly -// at recovering the 'hue' from fully saturated RGB colors that -// originally came from HSV rainbow colors. So if you start -// with CHSV(hue_in,255,255), and convert that to RGB, and then -// convert it back to HSV using this function, the resulting output -// hue will either exactly the same, or very close (+/-1). -// The more desaturated the original RGB color is, the rougher the -// approximation, and the less accurate the results. -// -CHSV rgb2hsv_approximate( const CRGB& rgb); - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/led_sysdefs.h b/FastLED/src/led_sysdefs.h deleted file mode 100644 index 8ee568bfcac560dbd5e854c85b5b7a3fbf5ad5db..0000000000000000000000000000000000000000 --- a/FastLED/src/led_sysdefs.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_H -#define __INC_LED_SYSDEFS_H - -#include "FastLED.h" - -#include "fastled_config.h" - -#if defined(NRF51) || defined(__RFduino__) || defined (__Simblee__) -#include "platforms/arm/nrf51/led_sysdefs_arm_nrf51.h" -#elif defined(NRF52_SERIES) -#include "platforms/arm/nrf52/led_sysdefs_arm_nrf52.h" -#elif defined(__MK20DX128__) || defined(__MK20DX256__) -// Include k20/T3 headers -#include "platforms/arm/k20/led_sysdefs_arm_k20.h" -#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) -// Include k66/T3.6 headers -#include "platforms/arm/k66/led_sysdefs_arm_k66.h" -#elif defined(__MKL26Z64__) -// Include kl26/T-LC headers -#include "platforms/arm/kl26/led_sysdefs_arm_kl26.h" -#elif defined(__IMXRT1062__) -// teensy4 -#include "platforms/arm/mxrt1062/led_sysdefs_arm_mxrt1062.h" -#elif defined(__SAM3X8E__) -// Include sam/due headers -#include "platforms/arm/sam/led_sysdefs_arm_sam.h" -#elif defined(STM32F10X_MD) || defined(__STM32F1__) -#include "platforms/arm/stm32/led_sysdefs_arm_stm32.h" -#elif defined(__SAMD21G18A__) || defined(__SAMD21J18A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__) || defined(__SAMD51G19A__) || defined(__SAMD51J19A__) -#include "platforms/arm/d21/led_sysdefs_arm_d21.h" -#elif defined(ESP8266) -#include "platforms/esp/8266/led_sysdefs_esp8266.h" -#elif defined(ESP32) -#include "platforms/esp/32/led_sysdefs_esp32.h" -#elif defined(__AVR__) || defined(__AVR_ATmega4809__) -// AVR platforms -#include "platforms/avr/led_sysdefs_avr.h" -#elif defined(ARDUINO_ARCH_APOLLO3) -// Apollo3 platforms (e.g. the Ambiq Micro Apollo3 Blue as used by the SparkFun Artemis platforms) -#include "platforms/apollo3/led_sysdefs_apollo3.h" -#else -// -// We got here because we don't recognize the platform that you're -// trying to compile for: it's not AVR, or an ESP or ARM that we recognize. -// -// If you're reading this because you got the error below, -// and if this new platform is just a minor variant of an -// existing supported ARM platform, you may be able to add -// a new 'defined(XXX)' selector in the apporpriate code above. -// -// If this platform is a new microcontroller, see "PORTING.md". -// -#error "This platform isn't recognized by FastLED... yet. See comments in FastLED/led_sysdefs.h for options." -#endif - -#ifndef FASTLED_NAMESPACE_BEGIN -#define FASTLED_NAMESPACE_BEGIN -#define FASTLED_NAMESPACE_END -#define FASTLED_USING_NAMESPACE -#endif - -// Arduino.h needed for convenience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. -#ifdef ARDUINO -#include <Arduino.h> -#endif - -#define CLKS_PER_US (F_CPU/1000000) - -#endif diff --git a/FastLED/src/lib8tion.cpp b/FastLED/src/lib8tion.cpp deleted file mode 100644 index ecb051d80a0e2035bad0b68012232da91f772fd9..0000000000000000000000000000000000000000 --- a/FastLED/src/lib8tion.cpp +++ /dev/null @@ -1,251 +0,0 @@ -#define FASTLED_INTERNAL -#include <stdint.h> -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -#define RAND16_SEED 1337 -uint16_t rand16seed = RAND16_SEED; - - -// memset8, memcpy8, memmove8: -// optimized avr replacements for the standard "C" library -// routines memset, memcpy, and memmove. -// -// There are two techniques that make these routines -// faster than the standard avr-libc routines. -// First, the loops are unrolled 2X, meaning that -// the average loop overhead is cut in half. -// And second, the compare-and-branch at the bottom -// of each loop decrements the low byte of the -// counter, and if the carry is clear, it branches -// back up immediately. Only if the low byte math -// causes carry do we bother to decrement the high -// byte and check that result for carry as well. -// Results for a 100-byte buffer are 20-40% faster -// than standard avr-libc, at a cost of a few extra -// bytes of code. - -#if defined(__AVR__) -extern "C" { -//__attribute__ ((noinline)) -void * memset8 ( void * ptr, uint8_t val, uint16_t num ) -{ - asm volatile( - " movw r26, %[ptr] \n\t" - " sbrs %A[num], 0 \n\t" - " rjmp Lseteven_%= \n\t" - " rjmp Lsetodd_%= \n\t" - "Lsetloop_%=: \n\t" - " st X+, %[val] \n\t" - "Lsetodd_%=: \n\t" - " st X+, %[val] \n\t" - "Lseteven_%=: \n\t" - " subi %A[num], 2 \n\t" - " brcc Lsetloop_%= \n\t" - " sbci %B[num], 0 \n\t" - " brcc Lsetloop_%= \n\t" - : [num] "+r" (num) - : [ptr] "r" (ptr), - [val] "r" (val) - : "memory" - ); - return ptr; -} - - - -//__attribute__ ((noinline)) -void * memcpy8 ( void * dst, const void* src, uint16_t num ) -{ - asm volatile( - " movw r30, %[src] \n\t" - " movw r26, %[dst] \n\t" - " sbrs %A[num], 0 \n\t" - " rjmp Lcpyeven_%= \n\t" - " rjmp Lcpyodd_%= \n\t" - "Lcpyloop_%=: \n\t" - " ld __tmp_reg__, Z+ \n\t" - " st X+, __tmp_reg__ \n\t" - "Lcpyodd_%=: \n\t" - " ld __tmp_reg__, Z+ \n\t" - " st X+, __tmp_reg__ \n\t" - "Lcpyeven_%=: \n\t" - " subi %A[num], 2 \n\t" - " brcc Lcpyloop_%= \n\t" - " sbci %B[num], 0 \n\t" - " brcc Lcpyloop_%= \n\t" - : [num] "+r" (num) - : [src] "r" (src), - [dst] "r" (dst) - : "memory" - ); - return dst; -} - -//__attribute__ ((noinline)) -void * memmove8 ( void * dst, const void* src, uint16_t num ) -{ - if( src > dst) { - // if src > dst then we can use the forward-stepping memcpy8 - return memcpy8( dst, src, num); - } else { - // if src < dst then we have to step backward: - dst = (char*)dst + num; - src = (char*)src + num; - asm volatile( - " movw r30, %[src] \n\t" - " movw r26, %[dst] \n\t" - " sbrs %A[num], 0 \n\t" - " rjmp Lmoveven_%= \n\t" - " rjmp Lmovodd_%= \n\t" - "Lmovloop_%=: \n\t" - " ld __tmp_reg__, -Z \n\t" - " st -X, __tmp_reg__ \n\t" - "Lmovodd_%=: \n\t" - " ld __tmp_reg__, -Z \n\t" - " st -X, __tmp_reg__ \n\t" - "Lmoveven_%=: \n\t" - " subi %A[num], 2 \n\t" - " brcc Lmovloop_%= \n\t" - " sbci %B[num], 0 \n\t" - " brcc Lmovloop_%= \n\t" - : [num] "+r" (num) - : [src] "r" (src), - [dst] "r" (dst) - : "memory" - ); - return dst; - } -} - - -} /* end extern "C" */ - -#endif /* AVR */ - - - - -#if 0 -// TEST / VERIFICATION CODE ONLY BELOW THIS POINT -#include <Arduino.h> -#include "lib8tion.h" - -void test1abs( int8_t i) -{ - Serial.print("abs("); Serial.print(i); Serial.print(") = "); - int8_t j = abs8(i); - Serial.print(j); Serial.println(" "); -} - -void testabs() -{ - delay(5000); - for( int8_t q = -128; q != 127; ++q) { - test1abs(q); - } - for(;;){}; -} - - -void testmul8() -{ - delay(5000); - byte r, c; - - Serial.println("mul8:"); - for( r = 0; r <= 20; r += 1) { - Serial.print(r); Serial.print(" : "); - for( c = 0; c <= 20; c += 1) { - byte t; - t = mul8( r, c); - Serial.print(t); Serial.print(' '); - } - Serial.println(' '); - } - Serial.println("done."); - for(;;){}; -} - - -void testscale8() -{ - delay(5000); - byte r, c; - - Serial.println("scale8:"); - for( r = 0; r <= 240; r += 10) { - Serial.print(r); Serial.print(" : "); - for( c = 0; c <= 240; c += 10) { - byte t; - t = scale8( r, c); - Serial.print(t); Serial.print(' '); - } - Serial.println(' '); - } - - Serial.println(' '); - Serial.println("scale8_video:"); - - for( r = 0; r <= 100; r += 4) { - Serial.print(r); Serial.print(" : "); - for( c = 0; c <= 100; c += 4) { - byte t; - t = scale8_video( r, c); - Serial.print(t); Serial.print(' '); - } - Serial.println(' '); - } - - Serial.println("done."); - for(;;){}; -} - - - -void testqadd8() -{ - delay(5000); - byte r, c; - for( r = 0; r <= 240; r += 10) { - Serial.print(r); Serial.print(" : "); - for( c = 0; c <= 240; c += 10) { - byte t; - t = qadd8( r, c); - Serial.print(t); Serial.print(' '); - } - Serial.println(' '); - } - Serial.println("done."); - for(;;){}; -} - -void testnscale8x3() -{ - delay(5000); - byte r, g, b, sc; - for( byte z = 0; z < 10; ++z) { - r = random8(); g = random8(); b = random8(); sc = random8(); - - Serial.print("nscale8x3_video( "); - Serial.print(r); Serial.print(", "); - Serial.print(g); Serial.print(", "); - Serial.print(b); Serial.print(", "); - Serial.print(sc); Serial.print(") = [ "); - - nscale8x3_video( r, g, b, sc); - - Serial.print(r); Serial.print(", "); - Serial.print(g); Serial.print(", "); - Serial.print(b); Serial.print("]"); - - Serial.println(' '); - } - Serial.println("done."); - for(;;){}; -} - -#endif - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/lib8tion.h b/FastLED/src/lib8tion.h deleted file mode 100644 index 0cc3baa4fca8a7fe64d3640ea3d1129a6ead39a2..0000000000000000000000000000000000000000 --- a/FastLED/src/lib8tion.h +++ /dev/null @@ -1,1173 +0,0 @@ -#ifndef __INC_LIB8TION_H -#define __INC_LIB8TION_H - -#include "FastLED.h" - -#ifndef __INC_LED_SYSDEFS_H -#error WTH? led_sysdefs needs to be included first -#endif - -FASTLED_NAMESPACE_BEGIN - -/* - - Fast, efficient 8-bit math functions specifically - designed for high-performance LED programming. - - Because of the AVR(Arduino) and ARM assembly language - implementations provided, using these functions often - results in smaller and faster code than the equivalent - program using plain "C" arithmetic and logic. - - - Included are: - - - - Saturating unsigned 8-bit add and subtract. - Instead of wrapping around if an overflow occurs, - these routines just 'clamp' the output at a maxumum - of 255, or a minimum of 0. Useful for adding pixel - values. E.g., qadd8( 200, 100) = 255. - - qadd8( i, j) == MIN( (i + j), 0xFF ) - qsub8( i, j) == MAX( (i - j), 0 ) - - - Saturating signed 8-bit ("7-bit") add. - qadd7( i, j) == MIN( (i + j), 0x7F) - - - - Scaling (down) of unsigned 8- and 16- bit values. - Scaledown value is specified in 1/256ths. - scale8( i, sc) == (i * sc) / 256 - scale16by8( i, sc) == (i * sc) / 256 - - Example: scaling a 0-255 value down into a - range from 0-99: - downscaled = scale8( originalnumber, 100); - - A special version of scale8 is provided for scaling - LED brightness values, to make sure that they don't - accidentally scale down to total black at low - dimming levels, since that would look wrong: - scale8_video( i, sc) = ((i * sc) / 256) +? 1 - - Example: reducing an LED brightness by a - dimming factor: - new_bright = scale8_video( orig_bright, dimming); - - - - Fast 8- and 16- bit unsigned random numbers. - Significantly faster than Arduino random(), but - also somewhat less random. You can add entropy. - random8() == random from 0..255 - random8( n) == random from 0..(N-1) - random8( n, m) == random from N..(M-1) - - random16() == random from 0..65535 - random16( n) == random from 0..(N-1) - random16( n, m) == random from N..(M-1) - - random16_set_seed( k) == seed = k - random16_add_entropy( k) == seed += k - - - - Absolute value of a signed 8-bit value. - abs8( i) == abs( i) - - - - 8-bit math operations which return 8-bit values. - These are provided mostly for completeness, - not particularly for performance. - mul8( i, j) == (i * j) & 0xFF - add8( i, j) == (i + j) & 0xFF - sub8( i, j) == (i - j) & 0xFF - - - - Fast 16-bit approximations of sin and cos. - Input angle is a uint16_t from 0-65535. - Output is a signed int16_t from -32767 to 32767. - sin16( x) == sin( (x/32768.0) * pi) * 32767 - cos16( x) == cos( (x/32768.0) * pi) * 32767 - Accurate to more than 99% in all cases. - - - Fast 8-bit approximations of sin and cos. - Input angle is a uint8_t from 0-255. - Output is an UNsigned uint8_t from 0 to 255. - sin8( x) == (sin( (x/128.0) * pi) * 128) + 128 - cos8( x) == (cos( (x/128.0) * pi) * 128) + 128 - Accurate to within about 2%. - - - - Fast 8-bit "easing in/out" function. - ease8InOutCubic(x) == 3(x^i) - 2(x^3) - ease8InOutApprox(x) == - faster, rougher, approximation of cubic easing - ease8InOutQuad(x) == quadratic (vs cubic) easing - - - Cubic, Quadratic, and Triangle wave functions. - Input is a uint8_t representing phase withing the wave, - similar to how sin8 takes an angle 'theta'. - Output is a uint8_t representing the amplitude of - the wave at that point. - cubicwave8( x) - quadwave8( x) - triwave8( x) - - - Square root for 16-bit integers. About three times - faster and five times smaller than Arduino's built-in - generic 32-bit sqrt routine. - sqrt16( uint16_t x ) == sqrt( x) - - - Dimming and brightening functions for 8-bit - light values. - dim8_video( x) == scale8_video( x, x) - dim8_raw( x) == scale8( x, x) - dim8_lin( x) == (x<128) ? ((x+1)/2) : scale8(x,x) - brighten8_video( x) == 255 - dim8_video( 255 - x) - brighten8_raw( x) == 255 - dim8_raw( 255 - x) - brighten8_lin( x) == 255 - dim8_lin( 255 - x) - The dimming functions in particular are suitable - for making LED light output appear more 'linear'. - - - - Linear interpolation between two values, with the - fraction between them expressed as an 8- or 16-bit - fixed point fraction (fract8 or fract16). - lerp8by8( fromU8, toU8, fract8 ) - lerp16by8( fromU16, toU16, fract8 ) - lerp15by8( fromS16, toS16, fract8 ) - == from + (( to - from ) * fract8) / 256) - lerp16by16( fromU16, toU16, fract16 ) - == from + (( to - from ) * fract16) / 65536) - map8( in, rangeStart, rangeEnd) - == map( in, 0, 255, rangeStart, rangeEnd); - - - Optimized memmove, memcpy, and memset, that are - faster than standard avr-libc 1.8. - memmove8( dest, src, bytecount) - memcpy8( dest, src, bytecount) - memset8( buf, value, bytecount) - - - Beat generators which return sine or sawtooth - waves in a specified number of Beats Per Minute. - Sine wave beat generators can specify a low and - high range for the output. Sawtooth wave beat - generators always range 0-255 or 0-65535. - beatsin8( BPM, low8, high8) - = (sine(beatphase) * (high8-low8)) + low8 - beatsin16( BPM, low16, high16) - = (sine(beatphase) * (high16-low16)) + low16 - beatsin88( BPM88, low16, high16) - = (sine(beatphase) * (high16-low16)) + low16 - beat8( BPM) = 8-bit repeating sawtooth wave - beat16( BPM) = 16-bit repeating sawtooth wave - beat88( BPM88) = 16-bit repeating sawtooth wave - BPM is beats per minute in either simple form - e.g. 120, or Q8.8 fixed-point form. - BPM88 is beats per minute in ONLY Q8.8 fixed-point - form. - -Lib8tion is pronounced like 'libation': lie-BAY-shun - -*/ - - - -#include <stdint.h> - -#define LIB8STATIC __attribute__ ((unused)) static inline -#define LIB8STATIC_ALWAYS_INLINE __attribute__ ((always_inline)) static inline - -#if !defined(__AVR__) -#include <string.h> -// for memmove, memcpy, and memset if not defined here -#endif // end of !defined(__AVR__) - -#if defined(__arm__) - -#if defined(FASTLED_TEENSY3) -// Can use Cortex M4 DSP instructions -#define QADD8_C 0 -#define QADD7_C 0 -#define QADD8_ARM_DSP_ASM 1 -#define QADD7_ARM_DSP_ASM 1 -#else -// Generic ARM -#define QADD8_C 1 -#define QADD7_C 1 -#endif // end of defined(FASTLED_TEENSY3) - -#define QSUB8_C 1 -#define SCALE8_C 1 -#define SCALE16BY8_C 1 -#define SCALE16_C 1 -#define ABS8_C 1 -#define MUL8_C 1 -#define QMUL8_C 1 -#define ADD8_C 1 -#define SUB8_C 1 -#define EASE8_C 1 -#define AVG8_C 1 -#define AVG7_C 1 -#define AVG16_C 1 -#define AVG15_C 1 -#define BLEND8_C 1 - -// end of #if defined(__arm__) - -#elif defined(ARDUINO_ARCH_APOLLO3) - -// Default to using the standard C functions for now -#define QADD8_C 1 -#define QADD7_C 1 -#define QSUB8_C 1 -#define SCALE8_C 1 -#define SCALE16BY8_C 1 -#define SCALE16_C 1 -#define ABS8_C 1 -#define MUL8_C 1 -#define QMUL8_C 1 -#define ADD8_C 1 -#define SUB8_C 1 -#define EASE8_C 1 -#define AVG8_C 1 -#define AVG7_C 1 -#define AVG16_C 1 -#define AVG15_C 1 -#define BLEND8_C 1 - -// end of #elif defined(ARDUINO_ARCH_APOLLO3) - -#elif defined(__AVR__) - -// AVR ATmega and friends Arduino - -#define QADD8_C 0 -#define QADD7_C 0 -#define QSUB8_C 0 -#define ABS8_C 0 -#define ADD8_C 0 -#define SUB8_C 0 -#define AVG8_C 0 -#define AVG7_C 0 -#define AVG16_C 0 -#define AVG15_C 0 - -#define QADD8_AVRASM 1 -#define QADD7_AVRASM 1 -#define QSUB8_AVRASM 1 -#define ABS8_AVRASM 1 -#define ADD8_AVRASM 1 -#define SUB8_AVRASM 1 -#define AVG8_AVRASM 1 -#define AVG7_AVRASM 1 -#define AVG16_AVRASM 1 -#define AVG15_AVRASM 1 - -// Note: these require hardware MUL instruction -// -- sorry, ATtiny! -#if !defined(LIB8_ATTINY) -#define SCALE8_C 0 -#define SCALE16BY8_C 0 -#define SCALE16_C 0 -#define MUL8_C 0 -#define QMUL8_C 0 -#define EASE8_C 0 -#define BLEND8_C 0 -#define SCALE8_AVRASM 1 -#define SCALE16BY8_AVRASM 1 -#define SCALE16_AVRASM 1 -#define MUL8_AVRASM 1 -#define QMUL8_AVRASM 1 -#define EASE8_AVRASM 1 -#define CLEANUP_R1_AVRASM 1 -#define BLEND8_AVRASM 1 -#else -// On ATtiny, we just use C implementations -#define SCALE8_C 1 -#define SCALE16BY8_C 1 -#define SCALE16_C 1 -#define MUL8_C 1 -#define QMUL8_C 1 -#define EASE8_C 1 -#define BLEND8_C 1 -#define SCALE8_AVRASM 0 -#define SCALE16BY8_AVRASM 0 -#define SCALE16_AVRASM 0 -#define MUL8_AVRASM 0 -#define QMUL8_AVRASM 0 -#define EASE8_AVRASM 0 -#define BLEND8_AVRASM 0 -#endif // end of !defined(LIB8_ATTINY) - -// end of #elif defined(__AVR__) - -#else - -// unspecified architecture, so -// no ASM, everything in C -#define QADD8_C 1 -#define QADD7_C 1 -#define QSUB8_C 1 -#define SCALE8_C 1 -#define SCALE16BY8_C 1 -#define SCALE16_C 1 -#define ABS8_C 1 -#define MUL8_C 1 -#define QMUL8_C 1 -#define ADD8_C 1 -#define SUB8_C 1 -#define EASE8_C 1 -#define AVG8_C 1 -#define AVG7_C 1 -#define AVG16_C 1 -#define AVG15_C 1 -#define BLEND8_C 1 - -#endif - -///@defgroup lib8tion Fast math functions -///A variety of functions for working with numbers. -///@{ - - -/////////////////////////////////////////////////////////////////////// -// -// typdefs for fixed-point fractional types. -// -// sfract7 should be interpreted as signed 128ths. -// fract8 should be interpreted as unsigned 256ths. -// sfract15 should be interpreted as signed 32768ths. -// fract16 should be interpreted as unsigned 65536ths. -// -// Example: if a fract8 has the value "64", that should be interpreted -// as 64/256ths, or one-quarter. -// -// -// fract8 range is 0 to 0.99609375 -// in steps of 0.00390625 -// -// sfract7 range is -0.9921875 to 0.9921875 -// in steps of 0.0078125 -// -// fract16 range is 0 to 0.99998474121 -// in steps of 0.00001525878 -// -// sfract15 range is -0.99996948242 to 0.99996948242 -// in steps of 0.00003051757 -// - -/// ANSI unsigned short _Fract. range is 0 to 0.99609375 -/// in steps of 0.00390625 -typedef uint8_t fract8; ///< ANSI: unsigned short _Fract - -/// ANSI: signed short _Fract. range is -0.9921875 to 0.9921875 -/// in steps of 0.0078125 -typedef int8_t sfract7; ///< ANSI: signed short _Fract - -/// ANSI: unsigned _Fract. range is 0 to 0.99998474121 -/// in steps of 0.00001525878 -typedef uint16_t fract16; ///< ANSI: unsigned _Fract - -/// ANSI: signed _Fract. range is -0.99996948242 to 0.99996948242 -/// in steps of 0.00003051757 -typedef int16_t sfract15; ///< ANSI: signed _Fract - - -// accumXY types should be interpreted as X bits of integer, -// and Y bits of fraction. -// E.g., accum88 has 8 bits of int, 8 bits of fraction - -typedef uint16_t accum88; ///< ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction -typedef int16_t saccum78; ///< ANSI: signed short _Accum. 7 bits int, 8 bits fraction -typedef uint32_t accum1616;///< ANSI: signed _Accum. 16 bits int, 16 bits fraction -typedef int32_t saccum1516;///< ANSI: signed _Accum. 15 bits int, 16 bits fraction -typedef uint16_t accum124; ///< no direct ANSI counterpart. 12 bits int, 4 bits fraction -typedef int32_t saccum114;///< no direct ANSI counterpart. 1 bit int, 14 bits fraction - - -/// typedef for IEEE754 "binary32" float type internals -typedef union { - uint32_t i; - float f; - struct { - uint32_t mantissa: 23; - uint32_t exponent: 8; - uint32_t signbit: 1; - }; - struct { - uint32_t mant7 : 7; - uint32_t mant16: 16; - uint32_t exp_ : 8; - uint32_t sb_ : 1; - }; - struct { - uint32_t mant_lo8 : 8; - uint32_t mant_hi16_exp_lo1 : 16; - uint32_t sb_exphi7 : 8; - }; -} IEEE754binary32_t; - -#include "lib8tion/math8.h" -#include "lib8tion/scale8.h" -#include "lib8tion/random8.h" -#include "lib8tion/trig8.h" - -/////////////////////////////////////////////////////////////////////// - - - - - - - -/////////////////////////////////////////////////////////////////////// -// -// float-to-fixed and fixed-to-float conversions -// -// Note that anything involving a 'float' on AVR will be slower. - -/// sfract15ToFloat: conversion from sfract15 fixed point to -/// IEEE754 32-bit float. -LIB8STATIC float sfract15ToFloat( sfract15 y) -{ - return y / 32768.0; -} - -/// conversion from IEEE754 float in the range (-1,1) -/// to 16-bit fixed point. Note that the extremes of -/// one and negative one are NOT representable. The -/// representable range is basically -LIB8STATIC sfract15 floatToSfract15( float f) -{ - return f * 32768.0; -} - - - -/////////////////////////////////////////////////////////////////////// -// -// memmove8, memcpy8, and memset8: -// alternatives to memmove, memcpy, and memset that are -// faster on AVR than standard avr-libc 1.8 - -#if defined(__AVR__) -extern "C" { -void * memmove8( void * dst, const void * src, uint16_t num ); -void * memcpy8 ( void * dst, const void * src, uint16_t num ) __attribute__ ((noinline)); -void * memset8 ( void * ptr, uint8_t value, uint16_t num ) __attribute__ ((noinline)) ; -} -#else -// on non-AVR platforms, these names just call standard libc. -#define memmove8 memmove -#define memcpy8 memcpy -#define memset8 memset -#endif - - -/////////////////////////////////////////////////////////////////////// -// -// linear interpolation, such as could be used for Perlin noise, etc. -// - -// A note on the structure of the lerp functions: -// The cases for b>a and b<=a are handled separately for -// speed: without knowing the relative order of a and b, -// the value (a-b) might be overflow the width of a or b, -// and have to be promoted to a wider, slower type. -// To avoid that, we separate the two cases, and are able -// to do all the math in the same width as the arguments, -// which is much faster and smaller on AVR. - -/// linear interpolation between two unsigned 8-bit values, -/// with 8-bit fraction -LIB8STATIC uint8_t lerp8by8( uint8_t a, uint8_t b, fract8 frac) -{ - uint8_t result; - if( b > a) { - uint8_t delta = b - a; - uint8_t scaled = scale8( delta, frac); - result = a + scaled; - } else { - uint8_t delta = a - b; - uint8_t scaled = scale8( delta, frac); - result = a - scaled; - } - return result; -} - -/// linear interpolation between two unsigned 16-bit values, -/// with 16-bit fraction -LIB8STATIC uint16_t lerp16by16( uint16_t a, uint16_t b, fract16 frac) -{ - uint16_t result; - if( b > a ) { - uint16_t delta = b - a; - uint16_t scaled = scale16(delta, frac); - result = a + scaled; - } else { - uint16_t delta = a - b; - uint16_t scaled = scale16( delta, frac); - result = a - scaled; - } - return result; -} - -/// linear interpolation between two unsigned 16-bit values, -/// with 8-bit fraction -LIB8STATIC uint16_t lerp16by8( uint16_t a, uint16_t b, fract8 frac) -{ - uint16_t result; - if( b > a) { - uint16_t delta = b - a; - uint16_t scaled = scale16by8( delta, frac); - result = a + scaled; - } else { - uint16_t delta = a - b; - uint16_t scaled = scale16by8( delta, frac); - result = a - scaled; - } - return result; -} - -/// linear interpolation between two signed 15-bit values, -/// with 8-bit fraction -LIB8STATIC int16_t lerp15by8( int16_t a, int16_t b, fract8 frac) -{ - int16_t result; - if( b > a) { - uint16_t delta = b - a; - uint16_t scaled = scale16by8( delta, frac); - result = a + scaled; - } else { - uint16_t delta = a - b; - uint16_t scaled = scale16by8( delta, frac); - result = a - scaled; - } - return result; -} - -/// linear interpolation between two signed 15-bit values, -/// with 8-bit fraction -LIB8STATIC int16_t lerp15by16( int16_t a, int16_t b, fract16 frac) -{ - int16_t result; - if( b > a) { - uint16_t delta = b - a; - uint16_t scaled = scale16( delta, frac); - result = a + scaled; - } else { - uint16_t delta = a - b; - uint16_t scaled = scale16( delta, frac); - result = a - scaled; - } - return result; -} - -/// map8: map from one full-range 8-bit value into a narrower -/// range of 8-bit values, possibly a range of hues. -/// -/// E.g. map myValue into a hue in the range blue..purple..pink..red -/// hue = map8( myValue, HUE_BLUE, HUE_RED); -/// -/// Combines nicely with the waveform functions (like sin8, etc) -/// to produce continuous hue gradients back and forth: -/// -/// hue = map8( sin8( myValue), HUE_BLUE, HUE_RED); -/// -/// Mathematically simiar to lerp8by8, but arguments are more -/// like Arduino's "map"; this function is similar to -/// -/// map( in, 0, 255, rangeStart, rangeEnd) -/// -/// but faster and specifically designed for 8-bit values. -LIB8STATIC uint8_t map8( uint8_t in, uint8_t rangeStart, uint8_t rangeEnd) -{ - uint8_t rangeWidth = rangeEnd - rangeStart; - uint8_t out = scale8( in, rangeWidth); - out += rangeStart; - return out; -} - - -/////////////////////////////////////////////////////////////////////// -// -// easing functions; see http://easings.net -// - -/// ease8InOutQuad: 8-bit quadratic ease-in / ease-out function -/// Takes around 13 cycles on AVR -#if EASE8_C == 1 -LIB8STATIC uint8_t ease8InOutQuad( uint8_t i) -{ - uint8_t j = i; - if( j & 0x80 ) { - j = 255 - j; - } - uint8_t jj = scale8( j, j); - uint8_t jj2 = jj << 1; - if( i & 0x80 ) { - jj2 = 255 - jj2; - } - return jj2; -} - -#elif EASE8_AVRASM == 1 -// This AVR asm version of ease8InOutQuad preserves one more -// low-bit of precision than the C version, and is also slightly -// smaller and faster. -LIB8STATIC uint8_t ease8InOutQuad(uint8_t val) { - uint8_t j=val; - asm volatile ( - "sbrc %[val], 7 \n" - "com %[j] \n" - "mul %[j], %[j] \n" - "add r0, %[j] \n" - "ldi %[j], 0 \n" - "adc %[j], r1 \n" - "lsl r0 \n" // carry = high bit of low byte of mul product - "rol %[j] \n" // j = (j * 2) + carry // preserve add'l bit of precision - "sbrc %[val], 7 \n" - "com %[j] \n" - "clr __zero_reg__ \n" - : [j] "+&a" (j) - : [val] "a" (val) - : "r0", "r1" - ); - return j; -} - -#else -#error "No implementation for ease8InOutQuad available." -#endif - -/// ease16InOutQuad: 16-bit quadratic ease-in / ease-out function -// C implementation at this point -LIB8STATIC uint16_t ease16InOutQuad( uint16_t i) -{ - uint16_t j = i; - if( j & 0x8000 ) { - j = 65535 - j; - } - uint16_t jj = scale16( j, j); - uint16_t jj2 = jj << 1; - if( i & 0x8000 ) { - jj2 = 65535 - jj2; - } - return jj2; -} - - -/// ease8InOutCubic: 8-bit cubic ease-in / ease-out function -/// Takes around 18 cycles on AVR -LIB8STATIC fract8 ease8InOutCubic( fract8 i) -{ - uint8_t ii = scale8_LEAVING_R1_DIRTY( i, i); - uint8_t iii = scale8_LEAVING_R1_DIRTY( ii, i); - - uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii)); - - /* the code generated for the above *'s automatically - cleans up R1, so there's no need to explicitily call - cleanup_R1(); */ - - uint8_t result = r1; - - // if we got "256", return 255: - if( r1 & 0x100 ) { - result = 255; - } - return result; -} - -/// ease8InOutApprox: fast, rough 8-bit ease-in/ease-out function -/// shaped approximately like 'ease8InOutCubic', -/// it's never off by more than a couple of percent -/// from the actual cubic S-curve, and it executes -/// more than twice as fast. Use when the cycles -/// are more important than visual smoothness. -/// Asm version takes around 7 cycles on AVR. - -#if EASE8_C == 1 -LIB8STATIC fract8 ease8InOutApprox( fract8 i) -{ - if( i < 64) { - // start with slope 0.5 - i /= 2; - } else if( i > (255 - 64)) { - // end with slope 0.5 - i = 255 - i; - i /= 2; - i = 255 - i; - } else { - // in the middle, use slope 192/128 = 1.5 - i -= 64; - i += (i / 2); - i += 32; - } - - return i; -} - -#elif EASE8_AVRASM == 1 -LIB8STATIC uint8_t ease8InOutApprox( fract8 i) -{ - // takes around 7 cycles on AVR - asm volatile ( - " subi %[i], 64 \n\t" - " cpi %[i], 128 \n\t" - " brcc Lshift_%= \n\t" - - // middle case - " mov __tmp_reg__, %[i] \n\t" - " lsr __tmp_reg__ \n\t" - " add %[i], __tmp_reg__ \n\t" - " subi %[i], 224 \n\t" - " rjmp Ldone_%= \n\t" - - // start or end case - "Lshift_%=: \n\t" - " lsr %[i] \n\t" - " subi %[i], 96 \n\t" - - "Ldone_%=: \n\t" - - : [i] "+&a" (i) - : - : "r0", "r1" - ); - return i; -} -#else -#error "No implementation for ease8 available." -#endif - - - -/// triwave8: triangle (sawtooth) wave generator. Useful for -/// turning a one-byte ever-increasing value into a -/// one-byte value that oscillates up and down. -/// -/// input output -/// 0..127 0..254 (positive slope) -/// 128..255 254..0 (negative slope) -/// -/// On AVR this function takes just three cycles. -/// -LIB8STATIC uint8_t triwave8(uint8_t in) -{ - if( in & 0x80) { - in = 255 - in; - } - uint8_t out = in << 1; - return out; -} - - -// quadwave8 and cubicwave8: S-shaped wave generators (like 'sine'). -// Useful for turning a one-byte 'counter' value into a -// one-byte oscillating value that moves smoothly up and down, -// with an 'acceleration' and 'deceleration' curve. -// -// These are even faster than 'sin8', and have -// slightly different curve shapes. -// - -/// quadwave8: quadratic waveform generator. Spends just a little more -/// time at the limits than 'sine' does. -LIB8STATIC uint8_t quadwave8(uint8_t in) -{ - return ease8InOutQuad( triwave8( in)); -} - -/// cubicwave8: cubic waveform generator. Spends visibly more time -/// at the limits than 'sine' does. -LIB8STATIC uint8_t cubicwave8(uint8_t in) -{ - return ease8InOutCubic( triwave8( in)); -} - -/// squarewave8: square wave generator. Useful for -/// turning a one-byte ever-increasing value -/// into a one-byte value that is either 0 or 255. -/// The width of the output 'pulse' is -/// determined by the pulsewidth argument: -/// -///~~~ -/// If pulsewidth is 255, output is always 255. -/// If pulsewidth < 255, then -/// if input < pulsewidth then output is 255 -/// if input >= pulsewidth then output is 0 -///~~~ -/// -/// the output looking like: -/// -///~~~ -/// 255 +--pulsewidth--+ -/// . | | -/// 0 0 +--------(256-pulsewidth)-------- -///~~~ -/// -/// @param in -/// @param pulsewidth -/// @returns square wave output -LIB8STATIC uint8_t squarewave8( uint8_t in, uint8_t pulsewidth=128) -{ - if( in < pulsewidth || (pulsewidth == 255)) { - return 255; - } else { - return 0; - } -} - - - - -/// Template class for represneting fractional ints. -template<class T, int F, int I> class q { - T i:I; - T f:F; -public: - q(float fx) { i = fx; f = (fx-i) * (1<<F); } - q(uint8_t _i, uint8_t _f) {i=_i; f=_f; } - uint32_t operator*(uint32_t v) { return (v*i) + ((v*f)>>F); } - uint16_t operator*(uint16_t v) { return (v*i) + ((v*f)>>F); } - int32_t operator*(int32_t v) { return (v*i) + ((v*f)>>F); } - int16_t operator*(int16_t v) { return (v*i) + ((v*f)>>F); } -#ifdef FASTLED_ARM - int operator*(int v) { return (v*i) + ((v*f)>>F); } -#endif -#ifdef FASTLED_APOLLO3 - int operator*(int v) { return (v*i) + ((v*f)>>F); } -#endif -}; - -template<class T, int F, int I> static uint32_t operator*(uint32_t v, q<T,F,I> & q) { return q * v; } -template<class T, int F, int I> static uint16_t operator*(uint16_t v, q<T,F,I> & q) { return q * v; } -template<class T, int F, int I> static int32_t operator*(int32_t v, q<T,F,I> & q) { return q * v; } -template<class T, int F, int I> static int16_t operator*(int16_t v, q<T,F,I> & q) { return q * v; } -#ifdef FASTLED_ARM -template<class T, int F, int I> static int operator*(int v, q<T,F,I> & q) { return q * v; } -#endif -#ifdef FASTLED_APOLLO3 -template<class T, int F, int I> static int operator*(int v, q<T,F,I> & q) { return q * v; } -#endif - -/// A 4.4 integer (4 bits integer, 4 bits fraction) -typedef q<uint8_t, 4,4> q44; -/// A 6.2 integer (6 bits integer, 2 bits fraction) -typedef q<uint8_t, 6,2> q62; -/// A 8.8 integer (8 bits integer, 8 bits fraction) -typedef q<uint16_t, 8,8> q88; -/// A 12.4 integer (12 bits integer, 4 bits fraction) -typedef q<uint16_t, 12,4> q124; - - - -// Beat generators - These functions produce waves at a given -// number of 'beats per minute'. Internally, they use -// the Arduino function 'millis' to track elapsed time. -// Accuracy is a bit better than one part in a thousand. -// -// beat8( BPM ) returns an 8-bit value that cycles 'BPM' times -// per minute, rising from 0 to 255, resetting to zero, -// rising up again, etc.. The output of this function -// is suitable for feeding directly into sin8, and cos8, -// triwave8, quadwave8, and cubicwave8. -// beat16( BPM ) returns a 16-bit value that cycles 'BPM' times -// per minute, rising from 0 to 65535, resetting to zero, -// rising up again, etc. The output of this function is -// suitable for feeding directly into sin16 and cos16. -// beat88( BPM88) is the same as beat16, except that the BPM88 argument -// MUST be in Q8.8 fixed point format, e.g. 120BPM must -// be specified as 120*256 = 30720. -// beatsin8( BPM, uint8_t low, uint8_t high) returns an 8-bit value that -// rises and falls in a sine wave, 'BPM' times per minute, -// between the values of 'low' and 'high'. -// beatsin16( BPM, uint16_t low, uint16_t high) returns a 16-bit value -// that rises and falls in a sine wave, 'BPM' times per -// minute, between the values of 'low' and 'high'. -// beatsin88( BPM88, ...) is the same as beatsin16, except that the -// BPM88 argument MUST be in Q8.8 fixed point format, -// e.g. 120BPM must be specified as 120*256 = 30720. -// -// BPM can be supplied two ways. The simpler way of specifying BPM is as -// a simple 8-bit integer from 1-255, (e.g., "120"). -// The more sophisticated way of specifying BPM allows for fractional -// "Q8.8" fixed point number (an 'accum88') with an 8-bit integer part and -// an 8-bit fractional part. The easiest way to construct this is to multiply -// a floating point BPM value (e.g. 120.3) by 256, (e.g. resulting in 30796 -// in this case), and pass that as the 16-bit BPM argument. -// "BPM88" MUST always be specified in Q8.8 format. -// -// Originally designed to make an entire animation project pulse with brightness. -// For that effect, add this line just above your existing call to "FastLED.show()": -// -// uint8_t bright = beatsin8( 60 /*BPM*/, 192 /*dimmest*/, 255 /*brightest*/ )); -// FastLED.setBrightness( bright ); -// FastLED.show(); -// -// The entire animation will now pulse between brightness 192 and 255 once per second. - - -// The beat generators need access to a millisecond counter. -// On Arduino, this is "millis()". On other platforms, you'll -// need to provide a function with this signature: -// uint32_t get_millisecond_timer(); -// that provides similar functionality. -// You can also force use of the get_millisecond_timer function -// by #defining USE_GET_MILLISECOND_TIMER. -#if (defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER) -// Forward declaration of Arduino function 'millis'. -//uint32_t millis(); -#define GET_MILLIS millis -#else -uint32_t get_millisecond_timer(); -#define GET_MILLIS get_millisecond_timer -#endif - -// beat16 generates a 16-bit 'sawtooth' wave at a given BPM, -/// with BPM specified in Q8.8 fixed-point format; e.g. -/// for this function, 120 BPM MUST BE specified as -/// 120*256 = 30720. -/// If you just want to specify "120", use beat16 or beat8. -LIB8STATIC uint16_t beat88( accum88 beats_per_minute_88, uint32_t timebase = 0) -{ - // BPM is 'beats per minute', or 'beats per 60000ms'. - // To avoid using the (slower) division operator, we - // want to convert 'beats per 60000ms' to 'beats per 65536ms', - // and then use a simple, fast bit-shift to divide by 65536. - // - // The ratio 65536:60000 is 279.620266667:256; we'll call it 280:256. - // The conversion is accurate to about 0.05%, more or less, - // e.g. if you ask for "120 BPM", you'll get about "119.93". - return (((GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16; -} - -/// beat16 generates a 16-bit 'sawtooth' wave at a given BPM -LIB8STATIC uint16_t beat16( accum88 beats_per_minute, uint32_t timebase = 0) -{ - // Convert simple 8-bit BPM's to full Q8.8 accum88's if needed - if( beats_per_minute < 256) beats_per_minute <<= 8; - return beat88(beats_per_minute, timebase); -} - -/// beat8 generates an 8-bit 'sawtooth' wave at a given BPM -LIB8STATIC uint8_t beat8( accum88 beats_per_minute, uint32_t timebase = 0) -{ - return beat16( beats_per_minute, timebase) >> 8; -} - -/// beatsin88 generates a 16-bit sine wave at a given BPM, -/// that oscillates within a given range. -/// For this function, BPM MUST BE SPECIFIED as -/// a Q8.8 fixed-point value; e.g. 120BPM must be -/// specified as 120*256 = 30720. -/// If you just want to specify "120", use beatsin16 or beatsin8. -LIB8STATIC uint16_t beatsin88( accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535, - uint32_t timebase = 0, uint16_t phase_offset = 0) -{ - uint16_t beat = beat88( beats_per_minute_88, timebase); - uint16_t beatsin = (sin16( beat + phase_offset) + 32768); - uint16_t rangewidth = highest - lowest; - uint16_t scaledbeat = scale16( beatsin, rangewidth); - uint16_t result = lowest + scaledbeat; - return result; -} - -/// beatsin16 generates a 16-bit sine wave at a given BPM, -/// that oscillates within a given range. -LIB8STATIC uint16_t beatsin16( accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535, - uint32_t timebase = 0, uint16_t phase_offset = 0) -{ - uint16_t beat = beat16( beats_per_minute, timebase); - uint16_t beatsin = (sin16( beat + phase_offset) + 32768); - uint16_t rangewidth = highest - lowest; - uint16_t scaledbeat = scale16( beatsin, rangewidth); - uint16_t result = lowest + scaledbeat; - return result; -} - -/// beatsin8 generates an 8-bit sine wave at a given BPM, -/// that oscillates within a given range. -LIB8STATIC uint8_t beatsin8( accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, - uint32_t timebase = 0, uint8_t phase_offset = 0) -{ - uint8_t beat = beat8( beats_per_minute, timebase); - uint8_t beatsin = sin8( beat + phase_offset); - uint8_t rangewidth = highest - lowest; - uint8_t scaledbeat = scale8( beatsin, rangewidth); - uint8_t result = lowest + scaledbeat; - return result; -} - - -/// Return the current seconds since boot in a 16-bit value. Used as part of the -/// "every N time-periods" mechanism -LIB8STATIC uint16_t seconds16() -{ - uint32_t ms = GET_MILLIS(); - uint16_t s16; - s16 = ms / 1000; - return s16; -} - -/// Return the current minutes since boot in a 16-bit value. Used as part of the -/// "every N time-periods" mechanism -LIB8STATIC uint16_t minutes16() -{ - uint32_t ms = GET_MILLIS(); - uint16_t m16; - m16 = (ms / (60000L)) & 0xFFFF; - return m16; -} - -/// Return the current hours since boot in an 8-bit value. Used as part of the -/// "every N time-periods" mechanism -LIB8STATIC uint8_t hours8() -{ - uint32_t ms = GET_MILLIS(); - uint8_t h8; - h8 = (ms / (3600000L)) & 0xFF; - return h8; -} - - -/// Helper routine to divide a 32-bit value by 1024, returning -/// only the low 16 bits. You'd think this would be just -/// result = (in32 >> 10) & 0xFFFF; -/// and on ARM, that's what you want and all is well. -/// But on AVR that code turns into a loop that executes -/// a four-byte shift ten times: 40 shifts in all, plus loop -/// overhead. This routine gets exactly the same result with -/// just six shifts (vs 40), and no loop overhead. -/// Used to convert millis to 'binary seconds' aka bseconds: -/// one bsecond == 1024 millis. -LIB8STATIC uint16_t div1024_32_16( uint32_t in32) -{ - uint16_t out16; -#if defined(__AVR__) - asm volatile ( - " lsr %D[in] \n\t" - " ror %C[in] \n\t" - " ror %B[in] \n\t" - " lsr %D[in] \n\t" - " ror %C[in] \n\t" - " ror %B[in] \n\t" - " mov %B[out],%C[in] \n\t" - " mov %A[out],%B[in] \n\t" - : [in] "+r" (in32), - [out] "=r" (out16) - ); -#else - out16 = (in32 >> 10) & 0xFFFF; -#endif - return out16; -} - -/// bseconds16 returns the current time-since-boot in -/// "binary seconds", which are actually 1024/1000 of a -/// second long. -LIB8STATIC uint16_t bseconds16() -{ - uint32_t ms = GET_MILLIS(); - uint16_t s16; - s16 = div1024_32_16( ms); - return s16; -} - - -// Classes to implement "Every N Milliseconds", "Every N Seconds", -// "Every N Minutes", "Every N Hours", and "Every N BSeconds". -#if 1 -#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \ -class NAME { \ -public: \ - TIMETYPE mPrevTrigger; \ - TIMETYPE mPeriod; \ - \ - NAME() { reset(); mPeriod = 1; }; \ - NAME(TIMETYPE period) { reset(); setPeriod(period); }; \ - void setPeriod( TIMETYPE period) { mPeriod = period; }; \ - TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); }; \ - TIMETYPE getPeriod() { return mPeriod; }; \ - TIMETYPE getElapsed() { return getTime() - mPrevTrigger; } \ - TIMETYPE getRemaining() { return mPeriod - getElapsed(); } \ - TIMETYPE getLastTriggerTime() { return mPrevTrigger; } \ - bool ready() { \ - bool isReady = (getElapsed() >= mPeriod); \ - if( isReady ) { reset(); } \ - return isReady; \ - } \ - void reset() { mPrevTrigger = getTime(); }; \ - void trigger() { mPrevTrigger = getTime() - mPeriod; }; \ - \ - operator bool() { return ready(); } \ -}; -INSTANTIATE_EVERY_N_TIME_PERIODS(CEveryNMillis,uint32_t,GET_MILLIS); -INSTANTIATE_EVERY_N_TIME_PERIODS(CEveryNSeconds,uint16_t,seconds16); -INSTANTIATE_EVERY_N_TIME_PERIODS(CEveryNBSeconds,uint16_t,bseconds16); -INSTANTIATE_EVERY_N_TIME_PERIODS(CEveryNMinutes,uint16_t,minutes16); -INSTANTIATE_EVERY_N_TIME_PERIODS(CEveryNHours,uint8_t,hours8); -#else - -// Under C++11 rules, we would be allowed to use not-external -// -linkage-type symbols as template arguments, -// e.g., LIB8STATIC seconds16, and we'd be able to use these -// templates as shown below. -// However, under C++03 rules, we cannot do that, and thus we -// have to resort to the preprocessor to 'instantiate' 'templates', -// as handled above. -template<typename timeType,timeType (*timeGetter)()> -class CEveryNTimePeriods { -public: - timeType mPrevTrigger; - timeType mPeriod; - - CEveryNTimePeriods() { reset(); mPeriod = 1; }; - CEveryNTimePeriods(timeType period) { reset(); setPeriod(period); }; - void setPeriod( timeType period) { mPeriod = period; }; - timeType getTime() { return (timeType)(timeGetter()); }; - timeType getPeriod() { return mPeriod; }; - timeType getElapsed() { return getTime() - mPrevTrigger; } - timeType getRemaining() { return mPeriod - getElapsed(); } - timeType getLastTriggerTime() { return mPrevTrigger; } - bool ready() { - bool isReady = (getElapsed() >= mPeriod); - if( isReady ) { reset(); } - return isReady; - } - void reset() { mPrevTrigger = getTime(); }; - void trigger() { mPrevTrigger = getTime() - mPeriod; }; - - operator bool() { return ready(); } -}; -typedef CEveryNTimePeriods<uint16_t,seconds16> CEveryNSeconds; -typedef CEveryNTimePeriods<uint16_t,bseconds16> CEveryNBSeconds; -typedef CEveryNTimePeriods<uint32_t,millis> CEveryNMillis; -typedef CEveryNTimePeriods<uint16_t,minutes16> CEveryNMinutes; -typedef CEveryNTimePeriods<uint8_t,hours8> CEveryNHours; -#endif - - -#define CONCAT_HELPER( x, y ) x##y -#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y ) -#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N) -#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME ) -#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N) -#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME ) -#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N) -#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME ) -#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N) -#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME ) -#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N) -#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME ) - -#define CEveryNMilliseconds CEveryNMillis -#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N) -#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N) - -FASTLED_NAMESPACE_END -///@} - -#endif diff --git a/FastLED/src/lib8tion/math8.h b/FastLED/src/lib8tion/math8.h deleted file mode 100644 index a83b1ad253bd23a22eb48a7cad2af7e15075eec2..0000000000000000000000000000000000000000 --- a/FastLED/src/lib8tion/math8.h +++ /dev/null @@ -1,557 +0,0 @@ -#ifndef __INC_LIB8TION_MATH_H -#define __INC_LIB8TION_MATH_H - -#include "scale8.h" - -///@ingroup lib8tion - -///@defgroup Math Basic math operations -/// Fast, efficient 8-bit math functions specifically -/// designed for high-performance LED programming. -/// -/// Because of the AVR(Arduino) and ARM assembly language -/// implementations provided, using these functions often -/// results in smaller and faster code than the equivalent -/// program using plain "C" arithmetic and logic. -///@{ - - -/// add one byte to another, saturating at 0xFF -/// @param i - first byte to add -/// @param j - second byte to add -/// @returns the sum of i & j, capped at 0xFF -LIB8STATIC_ALWAYS_INLINE uint8_t qadd8( uint8_t i, uint8_t j) -{ -#if QADD8_C == 1 - unsigned int t = i + j; - if( t > 255) t = 255; - return t; -#elif QADD8_AVRASM == 1 - asm volatile( - /* First, add j to i, conditioning the C flag */ - "add %0, %1 \n\t" - - /* Now test the C flag. - If C is clear, we branch around a load of 0xFF into i. - If C is set, we go ahead and load 0xFF into i. - */ - "brcc L_%= \n\t" - "ldi %0, 0xFF \n\t" - "L_%=: " - : "+a" (i) - : "a" (j) - ); - return i; -#elif QADD8_ARM_DSP_ASM == 1 - asm volatile( "uqadd8 %0, %0, %1" : "+r" (i) : "r" (j)); - return i; -#else -#error "No implementation for qadd8 available." -#endif -} - -/// Add one byte to another, saturating at 0x7F -/// @param i - first byte to add -/// @param j - second byte to add -/// @returns the sum of i & j, capped at 0xFF -LIB8STATIC_ALWAYS_INLINE int8_t qadd7( int8_t i, int8_t j) -{ -#if QADD7_C == 1 - int16_t t = i + j; - if( t > 127) t = 127; - return t; -#elif QADD7_AVRASM == 1 - asm volatile( - /* First, add j to i, conditioning the V flag */ - "add %0, %1 \n\t" - - /* Now test the V flag. - If V is clear, we branch around a load of 0x7F into i. - If V is set, we go ahead and load 0x7F into i. - */ - "brvc L_%= \n\t" - "ldi %0, 0x7F \n\t" - "L_%=: " - : "+a" (i) - : "a" (j) - ); - return i; -#elif QADD7_ARM_DSP_ASM == 1 - asm volatile( "qadd8 %0, %0, %1" : "+r" (i) : "r" (j)); - return i; -#else -#error "No implementation for qadd7 available." -#endif -} - -/// subtract one byte from another, saturating at 0x00 -/// @returns i - j with a floor of 0 -LIB8STATIC_ALWAYS_INLINE uint8_t qsub8( uint8_t i, uint8_t j) -{ -#if QSUB8_C == 1 - int t = i - j; - if( t < 0) t = 0; - return t; -#elif QSUB8_AVRASM == 1 - - asm volatile( - /* First, subtract j from i, conditioning the C flag */ - "sub %0, %1 \n\t" - - /* Now test the C flag. - If C is clear, we branch around a load of 0x00 into i. - If C is set, we go ahead and load 0x00 into i. - */ - "brcc L_%= \n\t" - "ldi %0, 0x00 \n\t" - "L_%=: " - : "+a" (i) - : "a" (j) - ); - return i; -#else -#error "No implementation for qsub8 available." -#endif -} - -/// add one byte to another, with one byte result -LIB8STATIC_ALWAYS_INLINE uint8_t add8( uint8_t i, uint8_t j) -{ -#if ADD8_C == 1 - int t = i + j; - return t; -#elif ADD8_AVRASM == 1 - // Add j to i, period. - asm volatile( "add %0, %1" : "+a" (i) : "a" (j)); - return i; -#else -#error "No implementation for add8 available." -#endif -} - -/// add one byte to another, with one byte result -LIB8STATIC_ALWAYS_INLINE uint16_t add8to16( uint8_t i, uint16_t j) -{ -#if ADD8_C == 1 - uint16_t t = i + j; - return t; -#elif ADD8_AVRASM == 1 - // Add i(one byte) to j(two bytes) - asm volatile( - "add %A[j], %[i] \n\t" - "adc %B[j], __zero_reg__ \n\t" - : [j] "+a" (j) - : [i] "a" (i) - ); - return i; -#else -#error "No implementation for add8to16 available." -#endif -} - - -/// subtract one byte from another, 8-bit result -LIB8STATIC_ALWAYS_INLINE uint8_t sub8( uint8_t i, uint8_t j) -{ -#if SUB8_C == 1 - int t = i - j; - return t; -#elif SUB8_AVRASM == 1 - // Subtract j from i, period. - asm volatile( "sub %0, %1" : "+a" (i) : "a" (j)); - return i; -#else -#error "No implementation for sub8 available." -#endif -} - -/// Calculate an integer average of two unsigned -/// 8-bit integer values (uint8_t). -/// Fractional results are rounded down, e.g. avg8(20,41) = 30 -LIB8STATIC_ALWAYS_INLINE uint8_t avg8( uint8_t i, uint8_t j) -{ -#if AVG8_C == 1 - return (i + j) >> 1; -#elif AVG8_AVRASM == 1 - asm volatile( - /* First, add j to i, 9th bit overflows into C flag */ - "add %0, %1 \n\t" - /* Divide by two, moving C flag into high 8th bit */ - "ror %0 \n\t" - : "+a" (i) - : "a" (j) - ); - return i; -#else -#error "No implementation for avg8 available." -#endif -} - -/// Calculate an integer average of two unsigned -/// 16-bit integer values (uint16_t). -/// Fractional results are rounded down, e.g. avg16(20,41) = 30 -LIB8STATIC_ALWAYS_INLINE uint16_t avg16( uint16_t i, uint16_t j) -{ -#if AVG16_C == 1 - return (uint32_t)((uint32_t)(i) + (uint32_t)(j)) >> 1; -#elif AVG16_AVRASM == 1 - asm volatile( - /* First, add jLo (heh) to iLo, 9th bit overflows into C flag */ - "add %A[i], %A[j] \n\t" - /* Now, add C + jHi to iHi, 17th bit overflows into C flag */ - "adc %B[i], %B[j] \n\t" - /* Divide iHi by two, moving C flag into high 16th bit, old 9th bit now in C */ - "ror %B[i] \n\t" - /* Divide iLo by two, moving C flag into high 8th bit */ - "ror %A[i] \n\t" - : [i] "+a" (i) - : [j] "a" (j) - ); - return i; -#else -#error "No implementation for avg16 available." -#endif -} - - -/// Calculate an integer average of two signed 7-bit -/// integers (int8_t) -/// If the first argument is even, result is rounded down. -/// If the first argument is odd, result is result up. -LIB8STATIC_ALWAYS_INLINE int8_t avg7( int8_t i, int8_t j) -{ -#if AVG7_C == 1 - return ((i + j) >> 1) + (i & 0x1); -#elif AVG7_AVRASM == 1 - asm volatile( - "asr %1 \n\t" - "asr %0 \n\t" - "adc %0, %1 \n\t" - : "+a" (i) - : "a" (j) - ); - return i; -#else -#error "No implementation for avg7 available." -#endif -} - -/// Calculate an integer average of two signed 15-bit -/// integers (int16_t) -/// If the first argument is even, result is rounded down. -/// If the first argument is odd, result is result up. -LIB8STATIC_ALWAYS_INLINE int16_t avg15( int16_t i, int16_t j) -{ -#if AVG15_C == 1 - return ((int32_t)((int32_t)(i) + (int32_t)(j)) >> 1) + (i & 0x1); -#elif AVG15_AVRASM == 1 - asm volatile( - /* first divide j by 2, throwing away lowest bit */ - "asr %B[j] \n\t" - "ror %A[j] \n\t" - /* now divide i by 2, with lowest bit going into C */ - "asr %B[i] \n\t" - "ror %A[i] \n\t" - /* add j + C to i */ - "adc %A[i], %A[j] \n\t" - "adc %B[i], %B[j] \n\t" - : [i] "+a" (i) - : [j] "a" (j) - ); - return i; -#else -#error "No implementation for avg15 available." -#endif -} - - -/// Calculate the remainder of one unsigned 8-bit -/// value divided by anoter, aka A % M. -/// Implemented by repeated subtraction, which is -/// very compact, and very fast if A is 'probably' -/// less than M. If A is a large multiple of M, -/// the loop has to execute multiple times. However, -/// even in that case, the loop is only two -/// instructions long on AVR, i.e., quick. -LIB8STATIC_ALWAYS_INLINE uint8_t mod8( uint8_t a, uint8_t m) -{ -#if defined(__AVR__) - asm volatile ( - "L_%=: sub %[a],%[m] \n\t" - " brcc L_%= \n\t" - " add %[a],%[m] \n\t" - : [a] "+r" (a) - : [m] "r" (m) - ); -#else - while( a >= m) a -= m; -#endif - return a; -} - -/// Add two numbers, and calculate the modulo -/// of the sum and a third number, M. -/// In other words, it returns (A+B) % M. -/// It is designed as a compact mechanism for -/// incrementing a 'mode' switch and wrapping -/// around back to 'mode 0' when the switch -/// goes past the end of the available range. -/// e.g. if you have seven modes, this switches -/// to the next one and wraps around if needed: -/// mode = addmod8( mode, 1, 7); -///LIB8STATIC_ALWAYS_INLINESee 'mod8' for notes on performance. -LIB8STATIC uint8_t addmod8( uint8_t a, uint8_t b, uint8_t m) -{ -#if defined(__AVR__) - asm volatile ( - " add %[a],%[b] \n\t" - "L_%=: sub %[a],%[m] \n\t" - " brcc L_%= \n\t" - " add %[a],%[m] \n\t" - : [a] "+r" (a) - : [b] "r" (b), [m] "r" (m) - ); -#else - a += b; - while( a >= m) a -= m; -#endif - return a; -} - -/// Subtract two numbers, and calculate the modulo -/// of the difference and a third number, M. -/// In other words, it returns (A-B) % M. -/// It is designed as a compact mechanism for -/// incrementing a 'mode' switch and wrapping -/// around back to 'mode 0' when the switch -/// goes past the end of the available range. -/// e.g. if you have seven modes, this switches -/// to the next one and wraps around if needed: -/// mode = addmod8( mode, 1, 7); -///LIB8STATIC_ALWAYS_INLINESee 'mod8' for notes on performance. -LIB8STATIC uint8_t submod8( uint8_t a, uint8_t b, uint8_t m) -{ -#if defined(__AVR__) - asm volatile ( - " sub %[a],%[b] \n\t" - "L_%=: sub %[a],%[m] \n\t" - " brcc L_%= \n\t" - " add %[a],%[m] \n\t" - : [a] "+r" (a) - : [b] "r" (b), [m] "r" (m) - ); -#else - a -= b; - while( a >= m) a -= m; -#endif - return a; -} - -/// 8x8 bit multiplication, with 8 bit result -LIB8STATIC_ALWAYS_INLINE uint8_t mul8( uint8_t i, uint8_t j) -{ -#if MUL8_C == 1 - return ((int)i * (int)(j) ) & 0xFF; -#elif MUL8_AVRASM == 1 - asm volatile( - /* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */ - "mul %0, %1 \n\t" - /* Extract the LOW 8-bits (r0) */ - "mov %0, r0 \n\t" - /* Restore r1 to "0"; it's expected to always be that */ - "clr __zero_reg__ \n\t" - : "+a" (i) - : "a" (j) - : "r0", "r1" - ); - return i; -#else -#error "No implementation for mul8 available." -#endif -} - - -/// saturating 8x8 bit multiplication, with 8 bit result -/// @returns the product of i * j, capping at 0xFF -LIB8STATIC_ALWAYS_INLINE uint8_t qmul8( uint8_t i, uint8_t j) -{ -#if QMUL8_C == 1 - int p = ((int)i * (int)(j) ); - if( p > 255) p = 255; - return p; -#elif QMUL8_AVRASM == 1 - asm volatile( - /* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */ - " mul %0, %1 \n\t" - /* If high byte of result is zero, all is well. */ - " tst r1 \n\t" - " breq Lnospill_%= \n\t" - /* If high byte of result > 0, saturate low byte to 0xFF */ - " ldi %0,0xFF \n\t" - " rjmp Ldone_%= \n\t" - "Lnospill_%=: \n\t" - /* Extract the LOW 8-bits (r0) */ - " mov %0, r0 \n\t" - "Ldone_%=: \n\t" - /* Restore r1 to "0"; it's expected to always be that */ - " clr __zero_reg__ \n\t" - : "+a" (i) - : "a" (j) - : "r0", "r1" - ); - return i; -#else -#error "No implementation for qmul8 available." -#endif -} - - -/// take abs() of a signed 8-bit uint8_t -LIB8STATIC_ALWAYS_INLINE int8_t abs8( int8_t i) -{ -#if ABS8_C == 1 - if( i < 0) i = -i; - return i; -#elif ABS8_AVRASM == 1 - asm volatile( - /* First, check the high bit, and prepare to skip if it's clear */ - "sbrc %0, 7 \n" - - /* Negate the value */ - "neg %0 \n" - - : "+r" (i) : "r" (i) - ); - return i; -#else -#error "No implementation for abs8 available." -#endif -} - -/// square root for 16-bit integers -/// About three times faster and five times smaller -/// than Arduino's general sqrt on AVR. -LIB8STATIC uint8_t sqrt16(uint16_t x) -{ - if( x <= 1) { - return x; - } - - uint8_t low = 1; // lower bound - uint8_t hi, mid; - - if( x > 7904) { - hi = 255; - } else { - hi = (x >> 5) + 8; // initial estimate for upper bound - } - - do { - mid = (low + hi) >> 1; - if ((uint16_t)(mid * mid) > x) { - hi = mid - 1; - } else { - if( mid == 255) { - return 255; - } - low = mid + 1; - } - } while (hi >= low); - - return low - 1; -} - -/// blend a variable proproportion(0-255) of one byte to another -/// @param a - the starting byte value -/// @param b - the byte value to blend toward -/// @param amountOfB - the proportion (0-255) of b to blend -/// @returns a byte value between a and b, inclusive -#if (FASTLED_BLEND_FIXED == 1) -LIB8STATIC uint8_t blend8( uint8_t a, uint8_t b, uint8_t amountOfB) -{ -#if BLEND8_C == 1 - uint16_t partial; - uint8_t result; - - uint8_t amountOfA = 255 - amountOfB; - - partial = (a * amountOfA); -#if (FASTLED_SCALE8_FIXED == 1) - partial += a; - //partial = add8to16( a, partial); -#endif - - partial += (b * amountOfB); -#if (FASTLED_SCALE8_FIXED == 1) - partial += b; - //partial = add8to16( b, partial); -#endif - - result = partial >> 8; - - return result; - -#elif BLEND8_AVRASM == 1 - uint16_t partial; - uint8_t result; - - asm volatile ( - /* partial = b * amountOfB */ - " mul %[b], %[amountOfB] \n\t" - " movw %A[partial], r0 \n\t" - - /* amountOfB (aka amountOfA) = 255 - amountOfB */ - " com %[amountOfB] \n\t" - - /* partial += a * amountOfB (aka amountOfA) */ - " mul %[a], %[amountOfB] \n\t" - - " add %A[partial], r0 \n\t" - " adc %B[partial], r1 \n\t" - - " clr __zero_reg__ \n\t" - -#if (FASTLED_SCALE8_FIXED == 1) - /* partial += a */ - " add %A[partial], %[a] \n\t" - " adc %B[partial], __zero_reg__ \n\t" - - // partial += b - " add %A[partial], %[b] \n\t" - " adc %B[partial], __zero_reg__ \n\t" -#endif - - : [partial] "=r" (partial), - [amountOfB] "+a" (amountOfB) - : [a] "a" (a), - [b] "a" (b) - : "r0", "r1" - ); - - result = partial >> 8; - - return result; - -#else -#error "No implementation for blend8 available." -#endif -} - -#else -LIB8STATIC uint8_t blend8( uint8_t a, uint8_t b, uint8_t amountOfB) -{ - // This version loses precision in the integer math - // and can actually return results outside of the range - // from a to b. Its use is not recommended. - uint8_t result; - uint8_t amountOfA = 255 - amountOfB; - result = scale8_LEAVING_R1_DIRTY( a, amountOfA) - + scale8_LEAVING_R1_DIRTY( b, amountOfB); - cleanup_R1(); - return result; -} -#endif - - -///@} -#endif diff --git a/FastLED/src/lib8tion/random8.h b/FastLED/src/lib8tion/random8.h deleted file mode 100644 index d834abd51d2bb92c5fc101fe9dad1a25cbf64cd6..0000000000000000000000000000000000000000 --- a/FastLED/src/lib8tion/random8.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef __INC_LIB8TION_RANDOM_H -#define __INC_LIB8TION_RANDOM_H -///@ingroup lib8tion - -///@defgroup Random Fast random number generators -/// Fast 8- and 16- bit unsigned random numbers. -/// Significantly faster than Arduino random(), but -/// also somewhat less random. You can add entropy. -///@{ - -// X(n+1) = (2053 * X(n)) + 13849) -#define FASTLED_RAND16_2053 ((uint16_t)(2053)) -#define FASTLED_RAND16_13849 ((uint16_t)(13849)) - -#if defined(LIB8_ATTINY) -#define APPLY_FASTLED_RAND16_2053(x) (x << 11) + (x << 2) + x -#else -#define APPLY_FASTLED_RAND16_2053(x) (x * FASTLED_RAND16_2053) -#endif - -/// random number seed -extern uint16_t rand16seed;// = RAND16_SEED; - -/// Generate an 8-bit random number -LIB8STATIC uint8_t random8() -{ - rand16seed = APPLY_FASTLED_RAND16_2053(rand16seed) + FASTLED_RAND16_13849; - // return the sum of the high and low bytes, for better - // mixing and non-sequential correlation - return (uint8_t)(((uint8_t)(rand16seed & 0xFF)) + - ((uint8_t)(rand16seed >> 8))); -} - -/// Generate a 16 bit random number -LIB8STATIC uint16_t random16() -{ - rand16seed = APPLY_FASTLED_RAND16_2053(rand16seed) + FASTLED_RAND16_13849; - return rand16seed; -} - -/// Generate an 8-bit random number between 0 and lim -/// @param lim the upper bound for the result -LIB8STATIC uint8_t random8(uint8_t lim) -{ - uint8_t r = random8(); - r = (r*lim) >> 8; - return r; -} - -/// Generate an 8-bit random number in the given range -/// @param min the lower bound for the random number -/// @param lim the upper bound for the random number -LIB8STATIC uint8_t random8(uint8_t min, uint8_t lim) -{ - uint8_t delta = lim - min; - uint8_t r = random8(delta) + min; - return r; -} - -/// Generate an 16-bit random number between 0 and lim -/// @param lim the upper bound for the result -LIB8STATIC uint16_t random16( uint16_t lim) -{ - uint16_t r = random16(); - uint32_t p = (uint32_t)lim * (uint32_t)r; - r = p >> 16; - return r; -} - -/// Generate an 16-bit random number in the given range -/// @param min the lower bound for the random number -/// @param lim the upper bound for the random number -LIB8STATIC uint16_t random16( uint16_t min, uint16_t lim) -{ - uint16_t delta = lim - min; - uint16_t r = random16( delta) + min; - return r; -} - -/// Set the 16-bit seed used for the random number generator -LIB8STATIC void random16_set_seed( uint16_t seed) -{ - rand16seed = seed; -} - -/// Get the current seed value for the random number generator -LIB8STATIC uint16_t random16_get_seed() -{ - return rand16seed; -} - -/// Add entropy into the random number generator -LIB8STATIC void random16_add_entropy( uint16_t entropy) -{ - rand16seed += entropy; -} - -///@} - -#endif diff --git a/FastLED/src/lib8tion/scale8.h b/FastLED/src/lib8tion/scale8.h deleted file mode 100644 index 6324475b6634b7ab862fc92c355c1280b7141b1a..0000000000000000000000000000000000000000 --- a/FastLED/src/lib8tion/scale8.h +++ /dev/null @@ -1,709 +0,0 @@ -#ifndef __INC_LIB8TION_SCALE_H -#define __INC_LIB8TION_SCALE_H - -///@ingroup lib8tion - -///@defgroup Scaling Scaling functions -/// Fast, efficient 8-bit scaling functions specifically -/// designed for high-performance LED programming. -/// -/// Because of the AVR(Arduino) and ARM assembly language -/// implementations provided, using these functions often -/// results in smaller and faster code than the equivalent -/// program using plain "C" arithmetic and logic. -///@{ - -/// scale one byte by a second one, which is treated as -/// the numerator of a fraction whose denominator is 256 -/// In other words, it computes i * (scale / 256) -/// 4 clocks AVR with MUL, 2 clocks ARM -LIB8STATIC_ALWAYS_INLINE uint8_t scale8( uint8_t i, fract8 scale) -{ -#if SCALE8_C == 1 -#if (FASTLED_SCALE8_FIXED == 1) - return (((uint16_t)i) * (1+(uint16_t)(scale))) >> 8; -#else - return ((uint16_t)i * (uint16_t)(scale) ) >> 8; -#endif -#elif SCALE8_AVRASM == 1 -#if defined(LIB8_ATTINY) -#if (FASTLED_SCALE8_FIXED == 1) - uint8_t work=i; -#else - uint8_t work=0; -#endif - uint8_t cnt=0x80; - asm volatile( -#if (FASTLED_SCALE8_FIXED == 1) - " inc %[scale] \n\t" - " breq DONE_%= \n\t" - " clr %[work] \n\t" -#endif - "LOOP_%=: \n\t" - /*" sbrc %[scale], 0 \n\t" - " add %[work], %[i] \n\t" - " ror %[work] \n\t" - " lsr %[scale] \n\t" - " clc \n\t"*/ - " sbrc %[scale], 0 \n\t" - " add %[work], %[i] \n\t" - " ror %[work] \n\t" - " lsr %[scale] \n\t" - " lsr %[cnt] \n\t" - "brcc LOOP_%= \n\t" - "DONE_%=: \n\t" - : [work] "+r" (work), [cnt] "+r" (cnt) - : [scale] "r" (scale), [i] "r" (i) - : - ); - return work; -#else - asm volatile( -#if (FASTLED_SCALE8_FIXED==1) - // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 - "mul %0, %1 \n\t" - // Add i to r0, possibly setting the carry flag - "add r0, %0 \n\t" - // load the immediate 0 into i (note, this does _not_ touch any flags) - "ldi %0, 0x00 \n\t" - // walk and chew gum at the same time - "adc %0, r1 \n\t" -#else - /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */ - "mul %0, %1 \n\t" - /* Move the high 8-bits of the product (r1) back to i */ - "mov %0, r1 \n\t" - /* Restore r1 to "0"; it's expected to always be that */ -#endif - "clr __zero_reg__ \n\t" - - : "+a" (i) /* writes to i */ - : "a" (scale) /* uses scale */ - : "r0", "r1" /* clobbers r0, r1 */ - ); - /* Return the result */ - return i; -#endif -#else -#error "No implementation for scale8 available." -#endif -} - - -/// The "video" version of scale8 guarantees that the output will -/// be only be zero if one or both of the inputs are zero. If both -/// inputs are non-zero, the output is guaranteed to be non-zero. -/// This makes for better 'video'/LED dimming, at the cost of -/// several additional cycles. -LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video( uint8_t i, fract8 scale) -{ -#if SCALE8_C == 1 || defined(LIB8_ATTINY) - uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0); - // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; - return j; -#elif SCALE8_AVRASM == 1 - uint8_t j=0; - asm volatile( - " tst %[i]\n\t" - " breq L_%=\n\t" - " mul %[i], %[scale]\n\t" - " mov %[j], r1\n\t" - " clr __zero_reg__\n\t" - " cpse %[scale], r1\n\t" - " subi %[j], 0xFF\n\t" - "L_%=: \n\t" - : [j] "+a" (j) - : [i] "a" (i), [scale] "a" (scale) - : "r0", "r1" - ); - return j; - // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - // asm volatile( - // " tst %0 \n" - // " breq L_%= \n" - // " mul %0, %1 \n" - // " mov %0, r1 \n" - // " add %0, %2 \n" - // " clr __zero_reg__ \n" - // "L_%=: \n" - // : "+a" (i) - // : "a" (scale), "a" (nonzeroscale) - // : "r0", "r1"); - // // Return the result - // return i; -#else -#error "No implementation for scale8_video available." -#endif -} - - -/// This version of scale8 does not clean up the R1 register on AVR -/// If you are doing several 'scale8's in a row, use this, and -/// then explicitly call cleanup_R1. -LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY( uint8_t i, fract8 scale) -{ -#if SCALE8_C == 1 -#if (FASTLED_SCALE8_FIXED == 1) - return (((uint16_t)i) * ((uint16_t)(scale)+1)) >> 8; -#else - return ((int)i * (int)(scale) ) >> 8; -#endif -#elif SCALE8_AVRASM == 1 - asm volatile( -#if (FASTLED_SCALE8_FIXED==1) - // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 - "mul %0, %1 \n\t" - // Add i to r0, possibly setting the carry flag - "add r0, %0 \n\t" - // load the immediate 0 into i (note, this does _not_ touch any flags) - "ldi %0, 0x00 \n\t" - // walk and chew gum at the same time - "adc %0, r1 \n\t" -#else - /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */ - "mul %0, %1 \n\t" - /* Move the high 8-bits of the product (r1) back to i */ - "mov %0, r1 \n\t" -#endif - /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */ - /* "clr __zero_reg__ \n\t" */ - : "+a" (i) /* writes to i */ - : "a" (scale) /* uses scale */ - : "r0", "r1" /* clobbers r0, r1 */ - ); - // Return the result - return i; -#else -#error "No implementation for scale8_LEAVING_R1_DIRTY available." -#endif -} - -/// In place modifying version of scale8, also this version of nscale8 does not -/// clean up the R1 register on AVR -/// If you are doing several 'scale8's in a row, use this, and -/// then explicitly call cleanup_R1. - -LIB8STATIC_ALWAYS_INLINE void nscale8_LEAVING_R1_DIRTY( uint8_t& i, fract8 scale) -{ -#if SCALE8_C == 1 -#if (FASTLED_SCALE8_FIXED == 1) - i = (((uint16_t)i) * ((uint16_t)(scale)+1)) >> 8; -#else - i = ((int)i * (int)(scale) ) >> 8; -#endif -#elif SCALE8_AVRASM == 1 - asm volatile( -#if (FASTLED_SCALE8_FIXED==1) - // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 - "mul %0, %1 \n\t" - // Add i to r0, possibly setting the carry flag - "add r0, %0 \n\t" - // load the immediate 0 into i (note, this does _not_ touch any flags) - "ldi %0, 0x00 \n\t" - // walk and chew gum at the same time - "adc %0, r1 \n\t" -#else - /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */ - "mul %0, %1 \n\t" - /* Move the high 8-bits of the product (r1) back to i */ - "mov %0, r1 \n\t" -#endif - /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */ - /* "clr __zero_reg__ \n\t" */ - - : "+a" (i) /* writes to i */ - : "a" (scale) /* uses scale */ - : "r0", "r1" /* clobbers r0, r1 */ - ); -#else -#error "No implementation for nscale8_LEAVING_R1_DIRTY available." -#endif -} - - -/// This version of scale8_video does not clean up the R1 register on AVR -/// If you are doing several 'scale8_video's in a row, use this, and -/// then explicitly call cleanup_R1. -LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video_LEAVING_R1_DIRTY( uint8_t i, fract8 scale) -{ -#if SCALE8_C == 1 || defined(LIB8_ATTINY) - uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0); - // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; - return j; -#elif SCALE8_AVRASM == 1 - uint8_t j=0; - asm volatile( - " tst %[i]\n\t" - " breq L_%=\n\t" - " mul %[i], %[scale]\n\t" - " mov %[j], r1\n\t" - " breq L_%=\n\t" - " subi %[j], 0xFF\n\t" - "L_%=: \n\t" - : [j] "+a" (j) - : [i] "a" (i), [scale] "a" (scale) - : "r0", "r1" - ); - return j; - // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - // asm volatile( - // " tst %0 \n" - // " breq L_%= \n" - // " mul %0, %1 \n" - // " mov %0, r1 \n" - // " add %0, %2 \n" - // " clr __zero_reg__ \n" - // "L_%=: \n" - // : "+a" (i) - // : "a" (scale), "a" (nonzeroscale) - // : "r0", "r1"); - // // Return the result - // return i; -#else -#error "No implementation for scale8_video_LEAVING_R1_DIRTY available." -#endif -} - -/// In place modifying version of scale8_video, also this version of nscale8_video -/// does not clean up the R1 register on AVR -/// If you are doing several 'scale8_video's in a row, use this, and -/// then explicitly call cleanup_R1. -LIB8STATIC_ALWAYS_INLINE void nscale8_video_LEAVING_R1_DIRTY( uint8_t & i, fract8 scale) -{ -#if SCALE8_C == 1 || defined(LIB8_ATTINY) - i = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0); -#elif SCALE8_AVRASM == 1 - asm volatile( - " tst %[i]\n\t" - " breq L_%=\n\t" - " mul %[i], %[scale]\n\t" - " mov %[i], r1\n\t" - " breq L_%=\n\t" - " subi %[i], 0xFF\n\t" - "L_%=: \n\t" - : [i] "+a" (i) - : [scale] "a" (scale) - : "r0", "r1" - ); -#else -#error "No implementation for scale8_video_LEAVING_R1_DIRTY available." -#endif -} - -/// Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls -LIB8STATIC_ALWAYS_INLINE void cleanup_R1() -{ -#if CLEANUP_R1_AVRASM == 1 - // Restore r1 to "0"; it's expected to always be that - asm volatile( "clr __zero_reg__ \n\t" : : : "r1" ); -#endif -} - - -/// scale three one byte values by a fourth one, which is treated as -/// the numerator of a fraction whose demominator is 256 -/// In other words, it computes r,g,b * (scale / 256) -/// -/// THIS FUNCTION ALWAYS MODIFIES ITS ARGUMENTS IN PLACE - -LIB8STATIC void nscale8x3( uint8_t& r, uint8_t& g, uint8_t& b, fract8 scale) -{ -#if SCALE8_C == 1 -#if (FASTLED_SCALE8_FIXED == 1) - uint16_t scale_fixed = scale + 1; - r = (((uint16_t)r) * scale_fixed) >> 8; - g = (((uint16_t)g) * scale_fixed) >> 8; - b = (((uint16_t)b) * scale_fixed) >> 8; -#else - r = ((int)r * (int)(scale) ) >> 8; - g = ((int)g * (int)(scale) ) >> 8; - b = ((int)b * (int)(scale) ) >> 8; -#endif -#elif SCALE8_AVRASM == 1 - r = scale8_LEAVING_R1_DIRTY(r, scale); - g = scale8_LEAVING_R1_DIRTY(g, scale); - b = scale8_LEAVING_R1_DIRTY(b, scale); - cleanup_R1(); -#else -#error "No implementation for nscale8x3 available." -#endif -} - -/// scale three one byte values by a fourth one, which is treated as -/// the numerator of a fraction whose demominator is 256 -/// In other words, it computes r,g,b * (scale / 256), ensuring -/// that non-zero values passed in remain non zero, no matter how low the scale -/// argument. -/// -/// THIS FUNCTION ALWAYS MODIFIES ITS ARGUMENTS IN PLACE -LIB8STATIC void nscale8x3_video( uint8_t& r, uint8_t& g, uint8_t& b, fract8 scale) -{ -#if SCALE8_C == 1 - uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - r = (r == 0) ? 0 : (((int)r * (int)(scale) ) >> 8) + nonzeroscale; - g = (g == 0) ? 0 : (((int)g * (int)(scale) ) >> 8) + nonzeroscale; - b = (b == 0) ? 0 : (((int)b * (int)(scale) ) >> 8) + nonzeroscale; -#elif SCALE8_AVRASM == 1 - nscale8_video_LEAVING_R1_DIRTY( r, scale); - nscale8_video_LEAVING_R1_DIRTY( g, scale); - nscale8_video_LEAVING_R1_DIRTY( b, scale); - cleanup_R1(); -#else -#error "No implementation for nscale8x3 available." -#endif -} - -/// scale two one byte values by a third one, which is treated as -/// the numerator of a fraction whose demominator is 256 -/// In other words, it computes i,j * (scale / 256) -/// -/// THIS FUNCTION ALWAYS MODIFIES ITS ARGUMENTS IN PLACE - -LIB8STATIC void nscale8x2( uint8_t& i, uint8_t& j, fract8 scale) -{ -#if SCALE8_C == 1 -#if FASTLED_SCALE8_FIXED == 1 - uint16_t scale_fixed = scale + 1; - i = (((uint16_t)i) * scale_fixed ) >> 8; - j = (((uint16_t)j) * scale_fixed ) >> 8; -#else - i = ((uint16_t)i * (uint16_t)(scale) ) >> 8; - j = ((uint16_t)j * (uint16_t)(scale) ) >> 8; -#endif -#elif SCALE8_AVRASM == 1 - i = scale8_LEAVING_R1_DIRTY(i, scale); - j = scale8_LEAVING_R1_DIRTY(j, scale); - cleanup_R1(); -#else -#error "No implementation for nscale8x2 available." -#endif -} - -/// scale two one byte values by a third one, which is treated as -/// the numerator of a fraction whose demominator is 256 -/// In other words, it computes i,j * (scale / 256), ensuring -/// that non-zero values passed in remain non zero, no matter how low the scale -/// argument. -/// -/// THIS FUNCTION ALWAYS MODIFIES ITS ARGUMENTS IN PLACE - - -LIB8STATIC void nscale8x2_video( uint8_t& i, uint8_t& j, fract8 scale) -{ -#if SCALE8_C == 1 - uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - i = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; - j = (j == 0) ? 0 : (((int)j * (int)(scale) ) >> 8) + nonzeroscale; -#elif SCALE8_AVRASM == 1 - nscale8_video_LEAVING_R1_DIRTY( i, scale); - nscale8_video_LEAVING_R1_DIRTY( j, scale); - cleanup_R1(); -#else -#error "No implementation for nscale8x2 available." -#endif -} - - -/// scale a 16-bit unsigned value by an 8-bit value, -/// considered as numerator of a fraction whose denominator -/// is 256. In other words, it computes i * (scale / 256) - -LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8( uint16_t i, fract8 scale ) -{ -#if SCALE16BY8_C == 1 - uint16_t result; -#if FASTLED_SCALE8_FIXED == 1 - result = (i * (1+((uint16_t)scale))) >> 8; -#else - result = (i * scale) / 256; -#endif - return result; -#elif SCALE16BY8_AVRASM == 1 -#if FASTLED_SCALE8_FIXED == 1 - uint16_t result = 0; - asm volatile( - // result.A = HighByte( (i.A x scale) + i.A ) - " mul %A[i], %[scale] \n\t" - " add r0, %A[i] \n\t" - // " adc r1, [zero] \n\t" - // " mov %A[result], r1 \n\t" - " adc %A[result], r1 \n\t" - - // result.A-B += i.B x scale - " mul %B[i], %[scale] \n\t" - " add %A[result], r0 \n\t" - " adc %B[result], r1 \n\t" - - // cleanup r1 - " clr __zero_reg__ \n\t" - - // result.A-B += i.B - " add %A[result], %B[i] \n\t" - " adc %B[result], __zero_reg__ \n\t" - - : [result] "+r" (result) - : [i] "r" (i), [scale] "r" (scale) - : "r0", "r1" - ); - return result; -#else - uint16_t result = 0; - asm volatile( - // result.A = HighByte(i.A x j ) - " mul %A[i], %[scale] \n\t" - " mov %A[result], r1 \n\t" - //" clr %B[result] \n\t" - - // result.A-B += i.B x j - " mul %B[i], %[scale] \n\t" - " add %A[result], r0 \n\t" - " adc %B[result], r1 \n\t" - - // cleanup r1 - " clr __zero_reg__ \n\t" - - : [result] "+r" (result) - : [i] "r" (i), [scale] "r" (scale) - : "r0", "r1" - ); - return result; -#endif -#else - #error "No implementation for scale16by8 available." -#endif -} - -/// scale a 16-bit unsigned value by a 16-bit value, -/// considered as numerator of a fraction whose denominator -/// is 65536. In other words, it computes i * (scale / 65536) - -LIB8STATIC uint16_t scale16( uint16_t i, fract16 scale ) -{ - #if SCALE16_C == 1 - uint16_t result; -#if FASTLED_SCALE8_FIXED == 1 - result = ((uint32_t)(i) * (1+(uint32_t)(scale))) / 65536; -#else - result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536; -#endif - return result; -#elif SCALE16_AVRASM == 1 -#if FASTLED_SCALE8_FIXED == 1 - // implemented sort of like - // result = ((i * scale) + i ) / 65536 - // - // why not like this, you may ask? - // result = (i * (scale+1)) / 65536 - // the answer is that if scale is 65535, then scale+1 - // will be zero, which is not what we want. - uint32_t result; - asm volatile( - // result.A-B = i.A x scale.A - " mul %A[i], %A[scale] \n\t" - // save results... - // basic idea: - //" mov %A[result], r0 \n\t" - //" mov %B[result], r1 \n\t" - // which can be written as... - " movw %A[result], r0 \n\t" - // Because we're going to add i.A-B to - // result.A-D, we DO need to keep both - // the r0 and r1 portions of the product - // UNlike in the 'unfixed scale8' version. - // So the movw here is needed. - : [result] "=r" (result) - : [i] "r" (i), - [scale] "r" (scale) - : "r0", "r1" - ); - - asm volatile( - // result.C-D = i.B x scale.B - " mul %B[i], %B[scale] \n\t" - //" mov %C[result], r0 \n\t" - //" mov %D[result], r1 \n\t" - " movw %C[result], r0 \n\t" - : [result] "+r" (result) - : [i] "r" (i), - [scale] "r" (scale) - : "r0", "r1" -); - -const uint8_t zero = 0; -asm volatile( - // result.B-D += i.B x scale.A - " mul %B[i], %A[scale] \n\t" - - " add %B[result], r0 \n\t" - " adc %C[result], r1 \n\t" - " adc %D[result], %[zero] \n\t" - - // result.B-D += i.A x scale.B - " mul %A[i], %B[scale] \n\t" - - " add %B[result], r0 \n\t" - " adc %C[result], r1 \n\t" - " adc %D[result], %[zero] \n\t" - - // cleanup r1 - " clr r1 \n\t" - - : [result] "+r" (result) - : [i] "r" (i), - [scale] "r" (scale), - [zero] "r" (zero) - : "r0", "r1" - ); - - asm volatile( - // result.A-D += i.A-B - " add %A[result], %A[i] \n\t" - " adc %B[result], %B[i] \n\t" - " adc %C[result], %[zero] \n\t" - " adc %D[result], %[zero] \n\t" - : [result] "+r" (result) - : [i] "r" (i), - [zero] "r" (zero) - ); - - result = result >> 16; - return result; -#else - uint32_t result; - asm volatile( - // result.A-B = i.A x scale.A - " mul %A[i], %A[scale] \n\t" - // save results... - // basic idea: - //" mov %A[result], r0 \n\t" - //" mov %B[result], r1 \n\t" - // which can be written as... - " movw %A[result], r0 \n\t" - // We actually don't need to do anything with r0, - // as result.A is never used again here, so we - // could just move the high byte, but movw is - // one clock cycle, just like mov, so might as - // well, in case we want to use this code for - // a generic 16x16 multiply somewhere. - - : [result] "=r" (result) - : [i] "r" (i), - [scale] "r" (scale) - : "r0", "r1" - ); - - asm volatile( - // result.C-D = i.B x scale.B - " mul %B[i], %B[scale] \n\t" - //" mov %C[result], r0 \n\t" - //" mov %D[result], r1 \n\t" - " movw %C[result], r0 \n\t" - : [result] "+r" (result) - : [i] "r" (i), - [scale] "r" (scale) - : "r0", "r1" - ); - - const uint8_t zero = 0; - asm volatile( - // result.B-D += i.B x scale.A - " mul %B[i], %A[scale] \n\t" - - " add %B[result], r0 \n\t" - " adc %C[result], r1 \n\t" - " adc %D[result], %[zero] \n\t" - - // result.B-D += i.A x scale.B - " mul %A[i], %B[scale] \n\t" - - " add %B[result], r0 \n\t" - " adc %C[result], r1 \n\t" - " adc %D[result], %[zero] \n\t" - - // cleanup r1 - " clr r1 \n\t" - - : [result] "+r" (result) - : [i] "r" (i), - [scale] "r" (scale), - [zero] "r" (zero) - : "r0", "r1" - ); - - result = result >> 16; - return result; -#endif -#else - #error "No implementation for scale16 available." -#endif -} -///@} - -///@defgroup Dimming Dimming and brightening functions -/// -/// Dimming and brightening functions -/// -/// The eye does not respond in a linear way to light. -/// High speed PWM'd LEDs at 50% duty cycle appear far -/// brighter then the 'half as bright' you might expect. -/// -/// If you want your midpoint brightness leve (128) to -/// appear half as bright as 'full' brightness (255), you -/// have to apply a 'dimming function'. -///@{ - -/// Adjust a scaling value for dimming -LIB8STATIC uint8_t dim8_raw( uint8_t x) -{ - return scale8( x, x); -} - -/// Adjust a scaling value for dimming for video (value will never go below 1) -LIB8STATIC uint8_t dim8_video( uint8_t x) -{ - return scale8_video( x, x); -} - -/// Linear version of the dimming function that halves for values < 128 -LIB8STATIC uint8_t dim8_lin( uint8_t x ) -{ - if( x & 0x80 ) { - x = scale8( x, x); - } else { - x += 1; - x /= 2; - } - return x; -} - -/// inverse of the dimming function, brighten a value -LIB8STATIC uint8_t brighten8_raw( uint8_t x) -{ - uint8_t ix = 255 - x; - return 255 - scale8( ix, ix); -} - -/// inverse of the dimming function, brighten a value -LIB8STATIC uint8_t brighten8_video( uint8_t x) -{ - uint8_t ix = 255 - x; - return 255 - scale8_video( ix, ix); -} - -/// inverse of the dimming function, brighten a value -LIB8STATIC uint8_t brighten8_lin( uint8_t x ) -{ - uint8_t ix = 255 - x; - if( ix & 0x80 ) { - ix = scale8( ix, ix); - } else { - ix += 1; - ix /= 2; - } - return 255 - ix; -} - -///@} -#endif diff --git a/FastLED/src/lib8tion/trig8.h b/FastLED/src/lib8tion/trig8.h deleted file mode 100644 index c5896ef8e921c8835965e499e4da757e62aa0a5b..0000000000000000000000000000000000000000 --- a/FastLED/src/lib8tion/trig8.h +++ /dev/null @@ -1,259 +0,0 @@ -#ifndef __INC_LIB8TION_TRIG_H -#define __INC_LIB8TION_TRIG_H - -///@ingroup lib8tion - -///@defgroup Trig Fast trig functions -/// Fast 8 and 16-bit approximations of sin(x) and cos(x). -/// Don't use these approximations for calculating the -/// trajectory of a rocket to Mars, but they're great -/// for art projects and LED displays. -/// -/// On Arduino/AVR, the 16-bit approximation is more than -/// 10X faster than floating point sin(x) and cos(x), while -/// the 8-bit approximation is more than 20X faster. -///@{ - -#if defined(__AVR__) -#define sin16 sin16_avr -#else -#define sin16 sin16_C -#endif - -/// Fast 16-bit approximation of sin(x). This approximation never varies more than -/// 0.69% from the floating point value you'd get by doing -/// -/// float s = sin(x) * 32767.0; -/// -/// @param theta input angle from 0-65535 -/// @returns sin of theta, value between -32767 to 32767. -LIB8STATIC int16_t sin16_avr( uint16_t theta ) -{ - static const uint8_t data[] = - { 0, 0, 49, 0, 6393%256, 6393/256, 48, 0, - 12539%256, 12539/256, 44, 0, 18204%256, 18204/256, 38, 0, - 23170%256, 23170/256, 31, 0, 27245%256, 27245/256, 23, 0, - 30273%256, 30273/256, 14, 0, 32137%256, 32137/256, 4 /*,0*/ }; - - uint16_t offset = (theta & 0x3FFF); - - // AVR doesn't have a multi-bit shift instruction, - // so if we say "offset >>= 3", gcc makes a tiny loop. - // Inserting empty volatile statements between each - // bit shift forces gcc to unroll the loop. - offset >>= 1; // 0..8191 - asm volatile(""); - offset >>= 1; // 0..4095 - asm volatile(""); - offset >>= 1; // 0..2047 - - if( theta & 0x4000 ) offset = 2047 - offset; - - uint8_t sectionX4; - sectionX4 = offset / 256; - sectionX4 *= 4; - - uint8_t m; - - union { - uint16_t b; - struct { - uint8_t blo; - uint8_t bhi; - }; - } u; - - //in effect u.b = blo + (256 * bhi); - u.blo = data[ sectionX4 ]; - u.bhi = data[ sectionX4 + 1]; - m = data[ sectionX4 + 2]; - - uint8_t secoffset8 = (uint8_t)(offset) / 2; - - uint16_t mx = m * secoffset8; - - int16_t y = mx + u.b; - if( theta & 0x8000 ) y = -y; - - return y; -} - -/// Fast 16-bit approximation of sin(x). This approximation never varies more than -/// 0.69% from the floating point value you'd get by doing -/// -/// float s = sin(x) * 32767.0; -/// -/// @param theta input angle from 0-65535 -/// @returns sin of theta, value between -32767 to 32767. -LIB8STATIC int16_t sin16_C( uint16_t theta ) -{ - static const uint16_t base[] = - { 0, 6393, 12539, 18204, 23170, 27245, 30273, 32137 }; - static const uint8_t slope[] = - { 49, 48, 44, 38, 31, 23, 14, 4 }; - - uint16_t offset = (theta & 0x3FFF) >> 3; // 0..2047 - if( theta & 0x4000 ) offset = 2047 - offset; - - uint8_t section = offset / 256; // 0..7 - uint16_t b = base[section]; - uint8_t m = slope[section]; - - uint8_t secoffset8 = (uint8_t)(offset) / 2; - - uint16_t mx = m * secoffset8; - int16_t y = mx + b; - - if( theta & 0x8000 ) y = -y; - - return y; -} - - -/// Fast 16-bit approximation of cos(x). This approximation never varies more than -/// 0.69% from the floating point value you'd get by doing -/// -/// float s = cos(x) * 32767.0; -/// -/// @param theta input angle from 0-65535 -/// @returns sin of theta, value between -32767 to 32767. -LIB8STATIC int16_t cos16( uint16_t theta) -{ - return sin16( theta + 16384); -} - -/////////////////////////////////////////////////////////////////////// - -// sin8 & cos8 -// Fast 8-bit approximations of sin(x) & cos(x). -// Input angle is an unsigned int from 0-255. -// Output is an unsigned int from 0 to 255. -// -// This approximation can vary to to 2% -// from the floating point value you'd get by doing -// float s = (sin( x ) * 128.0) + 128; -// -// Don't use this approximation for calculating the -// "real" trigonometric calculations, but it's great -// for art projects and LED displays. -// -// On Arduino/AVR, this approximation is more than -// 20X faster than floating point sin(x) and cos(x) - -#if defined(__AVR__) && !defined(LIB8_ATTINY) -#define sin8 sin8_avr -#else -#define sin8 sin8_C -#endif - - -const uint8_t b_m16_interleave[] = { 0, 49, 49, 41, 90, 27, 117, 10 }; - -/// Fast 8-bit approximation of sin(x). This approximation never varies more than -/// 2% from the floating point value you'd get by doing -/// -/// float s = (sin(x) * 128.0) + 128; -/// -/// @param theta input angle from 0-255 -/// @returns sin of theta, value between 0 and 255 -LIB8STATIC uint8_t sin8_avr( uint8_t theta) -{ - uint8_t offset = theta; - - asm volatile( - "sbrc %[theta],6 \n\t" - "com %[offset] \n\t" - : [theta] "+r" (theta), [offset] "+r" (offset) - ); - - offset &= 0x3F; // 0..63 - - uint8_t secoffset = offset & 0x0F; // 0..15 - if( theta & 0x40) ++secoffset; - - uint8_t m16; uint8_t b; - - uint8_t section = offset >> 4; // 0..3 - uint8_t s2 = section * 2; - - const uint8_t* p = b_m16_interleave; - p += s2; - b = *p; - ++p; - m16 = *p; - - uint8_t mx; - uint8_t xr1; - asm volatile( - "mul %[m16],%[secoffset] \n\t" - "mov %[mx],r0 \n\t" - "mov %[xr1],r1 \n\t" - "eor r1, r1 \n\t" - "swap %[mx] \n\t" - "andi %[mx],0x0F \n\t" - "swap %[xr1] \n\t" - "andi %[xr1], 0xF0 \n\t" - "or %[mx], %[xr1] \n\t" - : [mx] "=d" (mx), [xr1] "=d" (xr1) - : [m16] "d" (m16), [secoffset] "d" (secoffset) - ); - - int8_t y = mx + b; - if( theta & 0x80 ) y = -y; - - y += 128; - - return y; -} - - -/// Fast 8-bit approximation of sin(x). This approximation never varies more than -/// 2% from the floating point value you'd get by doing -/// -/// float s = (sin(x) * 128.0) + 128; -/// -/// @param theta input angle from 0-255 -/// @returns sin of theta, value between 0 and 255 -LIB8STATIC uint8_t sin8_C( uint8_t theta) -{ - uint8_t offset = theta; - if( theta & 0x40 ) { - offset = (uint8_t)255 - offset; - } - offset &= 0x3F; // 0..63 - - uint8_t secoffset = offset & 0x0F; // 0..15 - if( theta & 0x40) ++secoffset; - - uint8_t section = offset >> 4; // 0..3 - uint8_t s2 = section * 2; - const uint8_t* p = b_m16_interleave; - p += s2; - uint8_t b = *p; - ++p; - uint8_t m16 = *p; - - uint8_t mx = (m16 * secoffset) >> 4; - - int8_t y = mx + b; - if( theta & 0x80 ) y = -y; - - y += 128; - - return y; -} - -/// Fast 8-bit approximation of cos(x). This approximation never varies more than -/// 2% from the floating point value you'd get by doing -/// -/// float s = (cos(x) * 128.0) + 128; -/// -/// @param theta input angle from 0-255 -/// @returns sin of theta, value between 0 and 255 -LIB8STATIC uint8_t cos8( uint8_t theta) -{ - return sin8( theta + 64); -} - -///@} -#endif diff --git a/FastLED/src/noise.cpp b/FastLED/src/noise.cpp deleted file mode 100644 index 3a40c476f3dc464e38f5d01b0153223a8c0bc8a4..0000000000000000000000000000000000000000 --- a/FastLED/src/noise.cpp +++ /dev/null @@ -1,810 +0,0 @@ -#define FASTLED_INTERNAL -#include "FastLED.h" -#include <string.h> - -FASTLED_NAMESPACE_BEGIN - -#define P(x) FL_PGM_READ_BYTE_NEAR(p + x) - -FL_PROGMEM static uint8_t const p[] = { - 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, - 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, - 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, - 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, - 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, - 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, - 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, - 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, - 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, - 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, - 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, - 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, - 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, - 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, - 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, - 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, - 151}; - -#if FASTLED_NOISE_ALLOW_AVERAGE_TO_OVERFLOW == 1 -#define AVG15(U,V) (((U)+(V)) >> 1) -#else -// See if we should use the inlined avg15 for AVR with MUL instruction -#if defined(__AVR__) && (LIB8_ATTINY == 0) -#define AVG15(U,V) (avg15_inline_avr_mul((U),(V))) -// inlined copy of avg15 for AVR with MUL instruction; cloned from math8.h -// Forcing this inline in the 3-D 16bit noise produces a 12% speedup overall, -// at a cost of just +8 bytes of net code size. -static int16_t inline __attribute__((always_inline)) avg15_inline_avr_mul( int16_t i, int16_t j) -{ - asm volatile( - /* first divide j by 2, throwing away lowest bit */ - "asr %B[j] \n\t" - "ror %A[j] \n\t" - /* now divide i by 2, with lowest bit going into C */ - "asr %B[i] \n\t" - "ror %A[i] \n\t" - /* add j + C to i */ - "adc %A[i], %A[j] \n\t" - "adc %B[i], %B[j] \n\t" - : [i] "+a" (i) - : [j] "a" (j) ); - return i; -} -#else -#define AVG15(U,V) (avg15((U),(V))) -#endif -#endif - -// See fastled_config.h for notes on this; -// "#define FASTLED_NOISE_FIXED 1" is the correct value -#if FASTLED_NOISE_FIXED == 0 -#define EASE8(x) (FADE(x) ) -#define EASE16(x) (FADE(x) ) -#else -#define EASE8(x) (ease8InOutQuad(x) ) -#define EASE16(x) (ease16InOutQuad(x)) -#endif -// -// #define FADE_12 -#define FADE_16 - -#ifdef FADE_12 -#define FADE logfade12 -#define LERP(a,b,u) lerp15by12(a,b,u) -#else -#define FADE(x) scale16(x,x) -#define LERP(a,b,u) lerp15by16(a,b,u) -#endif -static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y, int16_t z) { -#if 0 - switch(hash & 0xF) { - case 0: return (( x) + ( y))>>1; - case 1: return ((-x) + ( y))>>1; - case 2: return (( x) + (-y))>>1; - case 3: return ((-x) + (-y))>>1; - case 4: return (( x) + ( z))>>1; - case 5: return ((-x) + ( z))>>1; - case 6: return (( x) + (-z))>>1; - case 7: return ((-x) + (-z))>>1; - case 8: return (( y) + ( z))>>1; - case 9: return ((-y) + ( z))>>1; - case 10: return (( y) + (-z))>>1; - case 11: return ((-y) + (-z))>>1; - case 12: return (( y) + ( x))>>1; - case 13: return ((-y) + ( z))>>1; - case 14: return (( y) + (-x))>>1; - case 15: return ((-y) + (-z))>>1; - } -#else - hash = hash&15; - int16_t u = hash<8?x:y; - int16_t v = hash<4?y:hash==12||hash==14?x:z; - if(hash&1) { u = -u; } - if(hash&2) { v = -v; } - - return AVG15(u,v); -#endif -} - -static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y) { - hash = hash & 7; - int16_t u,v; - if(hash < 4) { u = x; v = y; } else { u = y; v = x; } - if(hash&1) { u = -u; } - if(hash&2) { v = -v; } - - return AVG15(u,v); -} - -static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x) { - hash = hash & 15; - int16_t u,v; - if(hash > 8) { u=x;v=x; } - else if(hash < 4) { u=x;v=1; } - else { u=1;v=x; } - if(hash&1) { u = -u; } - if(hash&2) { v = -v; } - - return AVG15(u,v); -} - -// selectBasedOnHashBit performs this: -// result = (hash & (1<<bitnumber)) ? a : b -// but with an AVR asm version that's smaller and quicker than C -// (and probably not worth including in lib8tion) -static int8_t inline __attribute__((always_inline)) selectBasedOnHashBit(uint8_t hash, uint8_t bitnumber, int8_t a, int8_t b) { - int8_t result; -#if !defined(__AVR__) - result = (hash & (1<<bitnumber)) ? a : b; -#else - asm volatile( - "mov %[result],%[a] \n\t" - "sbrs %[hash],%[bitnumber] \n\t" - "mov %[result],%[b] \n\t" - : [result] "=r" (result) - : [hash] "r" (hash), - [bitnumber] "M" (bitnumber), - [a] "r" (a), - [b] "r" (b) - ); -#endif - return result; -} - -static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y, int8_t z) { -#if 0 - switch(hash & 0xF) { - case 0: return (( x) + ( y))>>1; - case 1: return ((-x) + ( y))>>1; - case 2: return (( x) + (-y))>>1; - case 3: return ((-x) + (-y))>>1; - case 4: return (( x) + ( z))>>1; - case 5: return ((-x) + ( z))>>1; - case 6: return (( x) + (-z))>>1; - case 7: return ((-x) + (-z))>>1; - case 8: return (( y) + ( z))>>1; - case 9: return ((-y) + ( z))>>1; - case 10: return (( y) + (-z))>>1; - case 11: return ((-y) + (-z))>>1; - case 12: return (( y) + ( x))>>1; - case 13: return ((-y) + ( z))>>1; - case 14: return (( y) + (-x))>>1; - case 15: return ((-y) + (-z))>>1; - } -#else - - hash &= 0xF; - - int8_t u, v; - //u = (hash&8)?y:x; - u = selectBasedOnHashBit( hash, 3, y, x); - -#if 1 - v = hash<4?y:hash==12||hash==14?x:z; -#else - // Verbose version for analysis; generates idenitical code. - if( hash < 4) { // 00 01 02 03 - v = y; - } else { - if( hash==12 || hash==14) { // 0C 0E - v = x; - } else { - v = z; // 04 05 06 07 08 09 0A 0B 0D 0F - } - } -#endif - - if(hash&1) { u = -u; } - if(hash&2) { v = -v; } - - return avg7(u,v); -#endif -} - -static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y) -{ - // since the tests below can be done bit-wise on the bottom - // three bits, there's no need to mask off the higher bits - // hash = hash & 7; - - int8_t u,v; - if( hash & 4) { - u = y; v = x; - } else { - u = x; v = y; - } - - if(hash&1) { u = -u; } - if(hash&2) { v = -v; } - - return avg7(u,v); -} - -static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x) -{ - // since the tests below can be done bit-wise on the bottom - // four bits, there's no need to mask off the higher bits - // hash = hash & 15; - - int8_t u,v; - if(hash & 8) { - u=x; v=x; - } else { - if(hash & 4) { - u=1; v=x; - } else { - u=x; v=1; - } - } - - if(hash&1) { u = -u; } - if(hash&2) { v = -v; } - - return avg7(u,v); -} - - -#ifdef FADE_12 -uint16_t logfade12(uint16_t val) { - return scale16(val,val)>>4; -} - -static int16_t inline __attribute__((always_inline)) lerp15by12( int16_t a, int16_t b, fract16 frac) -{ - //if(1) return (lerp(frac,a,b)); - int16_t result; - if( b > a) { - uint16_t delta = b - a; - uint16_t scaled = scale16(delta,frac<<4); - result = a + scaled; - } else { - uint16_t delta = a - b; - uint16_t scaled = scale16(delta,frac<<4); - result = a - scaled; - } - return result; -} -#endif - -static int8_t inline __attribute__((always_inline)) lerp7by8( int8_t a, int8_t b, fract8 frac) -{ - // int8_t delta = b - a; - // int16_t prod = (uint16_t)delta * (uint16_t)frac; - // int8_t scaled = prod >> 8; - // int8_t result = a + scaled; - // return result; - int8_t result; - if( b > a) { - uint8_t delta = b - a; - uint8_t scaled = scale8( delta, frac); - result = a + scaled; - } else { - uint8_t delta = a - b; - uint8_t scaled = scale8( delta, frac); - result = a - scaled; - } - return result; -} - -int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z) -{ - // Find the unit cube containing the point - uint8_t X = (x>>16)&0xFF; - uint8_t Y = (y>>16)&0xFF; - uint8_t Z = (z>>16)&0xFF; - - // Hash cube corner coordinates - uint8_t A = P(X)+Y; - uint8_t AA = P(A)+Z; - uint8_t AB = P(A+1)+Z; - uint8_t B = P(X+1)+Y; - uint8_t BA = P(B) + Z; - uint8_t BB = P(B+1)+Z; - - // Get the relative position of the point in the cube - uint16_t u = x & 0xFFFF; - uint16_t v = y & 0xFFFF; - uint16_t w = z & 0xFFFF; - - // Get a signed version of the above for the grad function - int16_t xx = (u >> 1) & 0x7FFF; - int16_t yy = (v >> 1) & 0x7FFF; - int16_t zz = (w >> 1) & 0x7FFF; - uint16_t N = 0x8000L; - - u = EASE16(u); v = EASE16(v); w = EASE16(w); - - // skip the log fade adjustment for the moment, otherwise here we would - // adjust fade values for u,v,w - int16_t X1 = LERP(grad16(P(AA), xx, yy, zz), grad16(P(BA), xx - N, yy, zz), u); - int16_t X2 = LERP(grad16(P(AB), xx, yy-N, zz), grad16(P(BB), xx - N, yy - N, zz), u); - int16_t X3 = LERP(grad16(P(AA+1), xx, yy, zz-N), grad16(P(BA+1), xx - N, yy, zz-N), u); - int16_t X4 = LERP(grad16(P(AB+1), xx, yy-N, zz-N), grad16(P(BB+1), xx - N, yy - N, zz - N), u); - - int16_t Y1 = LERP(X1,X2,v); - int16_t Y2 = LERP(X3,X4,v); - - int16_t ans = LERP(Y1,Y2,w); - - return ans; -} - -uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) { - int32_t ans = inoise16_raw(x,y,z); - ans = ans + 19052L; - uint32_t pan = ans; - // pan = (ans * 220L) >> 7. That's the same as: - // pan = (ans * 440L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR. - // Identical math, except for the highest bit, which we don't care about anyway, - // since we're returning the 'middle' 16 out of a 32-bit value anyway. - pan *= 440L; - return (pan>>8); - - // // return scale16by8(pan,220)<<1; - // return ((inoise16_raw(x,y,z)+19052)*220)>>7; - // return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1; -} - -int16_t inoise16_raw(uint32_t x, uint32_t y) -{ - // Find the unit cube containing the point - uint8_t X = x>>16; - uint8_t Y = y>>16; - - // Hash cube corner coordinates - uint8_t A = P(X)+Y; - uint8_t AA = P(A); - uint8_t AB = P(A+1); - uint8_t B = P(X+1)+Y; - uint8_t BA = P(B); - uint8_t BB = P(B+1); - - // Get the relative position of the point in the cube - uint16_t u = x & 0xFFFF; - uint16_t v = y & 0xFFFF; - - // Get a signed version of the above for the grad function - int16_t xx = (u >> 1) & 0x7FFF; - int16_t yy = (v >> 1) & 0x7FFF; - uint16_t N = 0x8000L; - - u = EASE16(u); v = EASE16(v); - - int16_t X1 = LERP(grad16(P(AA), xx, yy), grad16(P(BA), xx - N, yy), u); - int16_t X2 = LERP(grad16(P(AB), xx, yy-N), grad16(P(BB), xx - N, yy - N), u); - - int16_t ans = LERP(X1,X2,v); - - return ans; -} - -uint16_t inoise16(uint32_t x, uint32_t y) { - int32_t ans = inoise16_raw(x,y); - ans = ans + 17308L; - uint32_t pan = ans; - // pan = (ans * 242L) >> 7. That's the same as: - // pan = (ans * 484L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR. - // Identical math, except for the highest bit, which we don't care about anyway, - // since we're returning the 'middle' 16 out of a 32-bit value anyway. - pan *= 484L; - return (pan>>8); - - // return (uint32_t)(((int32_t)inoise16_raw(x,y)+(uint32_t)17308)*242)>>7; - // return scale16by8(inoise16_raw(x,y)+17308,242)<<1; -} - -int16_t inoise16_raw(uint32_t x) -{ - // Find the unit cube containing the point - uint8_t X = x>>16; - - // Hash cube corner coordinates - uint8_t A = P(X); - uint8_t AA = P(A); - uint8_t B = P(X+1); - uint8_t BA = P(B); - - // Get the relative position of the point in the cube - uint16_t u = x & 0xFFFF; - - // Get a signed version of the above for the grad function - int16_t xx = (u >> 1) & 0x7FFF; - uint16_t N = 0x8000L; - - u = EASE16(u); - - int16_t ans = LERP(grad16(P(AA), xx), grad16(P(BA), xx - N), u); - - return ans; -} - -uint16_t inoise16(uint32_t x) { - return ((uint32_t)((int32_t)inoise16_raw(x) + 17308L)) << 1; -} - -int8_t inoise8_raw(uint16_t x, uint16_t y, uint16_t z) -{ - // Find the unit cube containing the point - uint8_t X = x>>8; - uint8_t Y = y>>8; - uint8_t Z = z>>8; - - // Hash cube corner coordinates - uint8_t A = P(X)+Y; - uint8_t AA = P(A)+Z; - uint8_t AB = P(A+1)+Z; - uint8_t B = P(X+1)+Y; - uint8_t BA = P(B) + Z; - uint8_t BB = P(B+1)+Z; - - // Get the relative position of the point in the cube - uint8_t u = x; - uint8_t v = y; - uint8_t w = z; - - // Get a signed version of the above for the grad function - int8_t xx = ((uint8_t)(x)>>1) & 0x7F; - int8_t yy = ((uint8_t)(y)>>1) & 0x7F; - int8_t zz = ((uint8_t)(z)>>1) & 0x7F; - uint8_t N = 0x80; - - u = EASE8(u); v = EASE8(v); w = EASE8(w); - - int8_t X1 = lerp7by8(grad8(P(AA), xx, yy, zz), grad8(P(BA), xx - N, yy, zz), u); - int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N, zz), grad8(P(BB), xx - N, yy - N, zz), u); - int8_t X3 = lerp7by8(grad8(P(AA+1), xx, yy, zz-N), grad8(P(BA+1), xx - N, yy, zz-N), u); - int8_t X4 = lerp7by8(grad8(P(AB+1), xx, yy-N, zz-N), grad8(P(BB+1), xx - N, yy - N, zz - N), u); - - int8_t Y1 = lerp7by8(X1,X2,v); - int8_t Y2 = lerp7by8(X3,X4,v); - - int8_t ans = lerp7by8(Y1,Y2,w); - - return ans; -} - -uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z) { - //return scale8(76+(inoise8_raw(x,y,z)),215)<<1; - int8_t n = inoise8_raw( x, y, z); // -64..+64 - n+= 64; // 0..128 - uint8_t ans = qadd8( n, n); // 0..255 - return ans; -} - -int8_t inoise8_raw(uint16_t x, uint16_t y) -{ - // Find the unit cube containing the point - uint8_t X = x>>8; - uint8_t Y = y>>8; - - // Hash cube corner coordinates - uint8_t A = P(X)+Y; - uint8_t AA = P(A); - uint8_t AB = P(A+1); - uint8_t B = P(X+1)+Y; - uint8_t BA = P(B); - uint8_t BB = P(B+1); - - // Get the relative position of the point in the cube - uint8_t u = x; - uint8_t v = y; - - // Get a signed version of the above for the grad function - int8_t xx = ((uint8_t)(x)>>1) & 0x7F; - int8_t yy = ((uint8_t)(y)>>1) & 0x7F; - uint8_t N = 0x80; - - u = EASE8(u); v = EASE8(v); - - int8_t X1 = lerp7by8(grad8(P(AA), xx, yy), grad8(P(BA), xx - N, yy), u); - int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N), grad8(P(BB), xx - N, yy - N), u); - - int8_t ans = lerp7by8(X1,X2,v); - - return ans; - // return scale8((70+(ans)),234)<<1; -} - - - -uint8_t inoise8(uint16_t x, uint16_t y) { - //return scale8(69+inoise8_raw(x,y),237)<<1; - int8_t n = inoise8_raw( x, y); // -64..+64 - n+= 64; // 0..128 - uint8_t ans = qadd8( n, n); // 0..255 - return ans; -} - -// output range = -64 .. +64 -int8_t inoise8_raw(uint16_t x) -{ - // Find the unit cube containing the point - uint8_t X = x>>8; - - // Hash cube corner coordinates - uint8_t A = P(X); - uint8_t AA = P(A); - uint8_t B = P(X+1); - uint8_t BA = P(B); - - // Get the relative position of the point in the cube - uint8_t u = x; - - // Get a signed version of the above for the grad function - int8_t xx = ((uint8_t)(x)>>1) & 0x7F; - uint8_t N = 0x80; - - u = EASE8( u); - - int8_t ans = lerp7by8(grad8(P(AA), xx), grad8(P(BA), xx - N), u); - - return ans; -} - -uint8_t inoise8(uint16_t x) { - int8_t n = inoise8_raw(x); //-64..+64 - n += 64; // 0..128 - uint8_t ans = qadd8(n,n); // 0..255 - return ans; -} - -// struct q44 { -// uint8_t i:4; -// uint8_t f:4; -// q44(uint8_t _i, uint8_t _f) {i=_i; f=_f; } -// }; - -// uint32_t mul44(uint32_t v, q44 mulby44) { -// return (v *mulby44.i) + ((v * mulby44.f) >> 4); -// } -// -// uint16_t mul44_16(uint16_t v, q44 mulby44) { -// return (v *mulby44.i) + ((v * mulby44.f) >> 4); -// } - -void fill_raw_noise8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint16_t x, int scale, uint16_t time) { - uint32_t _xx = x; - uint32_t scx = scale; - for(int o = 0; o < octaves; ++o) { - for(int i = 0,xx=_xx; i < num_points; ++i, xx+=scx) { - pData[i] = qadd8(pData[i],inoise8(xx,time)>>o); - } - - _xx <<= 1; - scx <<= 1; - } -} - -void fill_raw_noise16into8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint32_t x, int scale, uint32_t time) { - uint32_t _xx = x; - uint32_t scx = scale; - for(int o = 0; o < octaves; ++o) { - for(int i = 0,xx=_xx; i < num_points; ++i, xx+=scx) { - uint32_t accum = (inoise16(xx,time))>>o; - accum += (pData[i]<<8); - if(accum > 65535) { accum = 65535; } - pData[i] = accum>>8; - } - - _xx <<= 1; - scx <<= 1; - } -} - -void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) { - if(octaves > 1) { - fill_raw_2dnoise8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x*freq44, freq44 * scalex, y*freq44, freq44 * scaley, time); - } else { - // amplitude is always 255 on the lowest level - amplitude=255; - } - - scalex *= skip; - scaley *= skip; - - fract8 invamp = 255-amplitude; - uint16_t xx = x; - for(int i = 0; i < height; ++i, y+=scaley) { - uint8_t *pRow = pData + (i*width); - xx = x; - for(int j = 0; j < width; ++j, xx+=scalex) { - uint8_t noise_base = inoise8(xx,y,time); - noise_base = (0x80 & noise_base) ? (noise_base - 127) : (127 - noise_base); - noise_base = scale8(noise_base<<1,amplitude); - if(skip == 1) { - pRow[j] = scale8(pRow[j],invamp) + noise_base; - } else { - for(int ii = i; ii<(i+skip) && ii<height; ++ii) { - uint8_t *pRow = pData + (ii*width); - for(int jj=j; jj<(j+skip) && jj<width; ++jj) { - pRow[jj] = scale8(pRow[jj],invamp) + noise_base; - } - } - } - } - } -} - -void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) { - fill_raw_2dnoise8(pData, width, height, octaves, q44(2,0), 128, 1, x, scalex, y, scaley, time); -} - -void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, q88 freq88, fract16 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { - if(octaves > 1) { - fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip, x *freq88 , scalex *freq88, y * freq88, scaley * freq88, time); - } else { - // amplitude is always 255 on the lowest level - amplitude=65535; - } - - scalex *= skip; - scaley *= skip; - fract16 invamp = 65535-amplitude; - for(int i = 0; i < height; i+=skip, y+=scaley) { - uint16_t *pRow = pData + (i*width); - for(int j = 0,xx=x; j < width; j+=skip, xx+=scalex) { - uint16_t noise_base = inoise16(xx,y,time); - noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base; - noise_base = scale16(noise_base<<1, amplitude); - if(skip==1) { - pRow[j] = scale16(pRow[j],invamp) + noise_base; - } else { - for(int ii = i; ii<(i+skip) && ii<height; ++ii) { - uint16_t *pRow = pData + (ii*width); - for(int jj=j; jj<(j+skip) && jj<width; ++jj) { - pRow[jj] = scale16(pRow[jj],invamp) + noise_base; - } - } - } - } - } -} - -int32_t nmin=11111110; -int32_t nmax=0; - -void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { - if(octaves > 1) { - fill_raw_2dnoise16into8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x*freq44, scalex *freq44, y*freq44, scaley * freq44, time); - } else { - // amplitude is always 255 on the lowest level - amplitude=255; - } - - scalex *= skip; - scaley *= skip; - uint32_t xx; - fract8 invamp = 255-amplitude; - for(int i = 0; i < height; i+=skip, y+=scaley) { - uint8_t *pRow = pData + (i*width); - xx = x; - for(int j = 0; j < width; j+=skip, xx+=scalex) { - uint16_t noise_base = inoise16(xx,y,time); - noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base; - noise_base = scale8(noise_base>>7,amplitude); - if(skip==1) { - pRow[j] = qadd8(scale8(pRow[j],invamp),noise_base); - } else { - for(int ii = i; ii<(i+skip) && ii<height; ++ii) { - uint8_t *pRow = pData + (ii*width); - for(int jj=j; jj<(j+skip) && jj<width; ++jj) { - pRow[jj] = scale8(pRow[jj],invamp) + noise_base; - } - } - } - } - } -} - -void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { - fill_raw_2dnoise16into8(pData, width, height, octaves, q44(2,0), 171, 1, x, scalex, y, scaley, time); -} - -void fill_noise8(CRGB *leds, int num_leds, - uint8_t octaves, uint16_t x, int scale, - uint8_t hue_octaves, uint16_t hue_x, int hue_scale, - uint16_t time) { - uint8_t V[num_leds]; - uint8_t H[num_leds]; - - memset(V,0,num_leds); - memset(H,0,num_leds); - - fill_raw_noise8(V,num_leds,octaves,x,scale,time); - fill_raw_noise8(H,num_leds,hue_octaves,hue_x,hue_scale,time); - - for(int i = 0; i < num_leds; ++i) { - leds[i] = CHSV(H[i],255,V[i]); - } -} - -void fill_noise16(CRGB *leds, int num_leds, - uint8_t octaves, uint16_t x, int scale, - uint8_t hue_octaves, uint16_t hue_x, int hue_scale, - uint16_t time, uint8_t hue_shift) { - uint8_t V[num_leds]; - uint8_t H[num_leds]; - - memset(V,0,num_leds); - memset(H,0,num_leds); - - fill_raw_noise16into8(V,num_leds,octaves,x,scale,time); - fill_raw_noise8(H,num_leds,hue_octaves,hue_x,hue_scale,time); - - for(int i = 0; i < num_leds; ++i) { - leds[i] = CHSV(H[i] + hue_shift,255,V[i]); - } -} - -void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, - uint8_t octaves, uint16_t x, int xscale, uint16_t y, int yscale, uint16_t time, - uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time,bool blend) { - uint8_t V[height][width]; - uint8_t H[height][width]; - - memset(V,0,height*width); - memset(H,0,height*width); - - fill_raw_2dnoise8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time); - fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); - - int w1 = width-1; - int h1 = height-1; - for(int i = 0; i < height; ++i) { - int wb = i*width; - for(int j = 0; j < width; ++j) { - CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); - - int pos = j; - if(serpentine && (i & 0x1)) { - pos = w1-j; - } - - if(blend) { - leds[wb+pos] >>= 1; leds[wb+pos] += (led>>=1); - } else { - leds[wb+pos] = led; - } - } - } -} - -void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, - uint8_t octaves, uint32_t x, int xscale, uint32_t y, int yscale, uint32_t time, - uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend, uint16_t hue_shift) { - uint8_t V[height][width]; - uint8_t H[height][width]; - - memset(V,0,height*width); - memset(H,0,height*width); - - fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2,0),171,1,x,xscale,y,yscale,time); - // fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time); - // fill_raw_2dnoise8((uint8_t*)V,width,height,hue_octaves,x,xscale,y,yscale,time); - fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); - - - int w1 = width-1; - int h1 = height-1; - hue_shift >>= 8; - - for(int i = 0; i < height; ++i) { - int wb = i*width; - for(int j = 0; j < width; ++j) { - CRGB led(CHSV(hue_shift + (H[h1-i][w1-j]),196,V[i][j])); - - int pos = j; - if(serpentine && (i & 0x1)) { - pos = w1-j; - } - - if(blend) { - leds[wb+pos] >>= 1; leds[wb+pos] += (led>>=1); - } else { - leds[wb+pos] = led; - } - } - } -} - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/noise.h b/FastLED/src/noise.h deleted file mode 100644 index 7355e23ec017c607e529d16d8f28b334983b0ce7..0000000000000000000000000000000000000000 --- a/FastLED/src/noise.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef __INC_NOISE_H -#define __INC_NOISE_H - -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -///@file noise.h -/// Noise functions provided by the library. - -///@defgroup Noise Noise functions -///Simplex noise function definitions -///@{ -/// @name scaled 16 bit noise functions -///@{ -/// 16 bit, fixed point implementation of perlin's Simplex Noise. Coordinates are -/// 16.16 fixed point values, 32 bit integers with integral coordinates in the high 16 -/// bits and fractional in the low 16 bits, and the function takes 1d, 2d, and 3d coordinate -/// values. These functions are scaled to return 0-65535 - -extern uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z); -extern uint16_t inoise16(uint32_t x, uint32_t y); -extern uint16_t inoise16(uint32_t x); -///@} - -/// @name raw 16 bit noise functions -//@{ -/// 16 bit raw versions of the noise functions. These values are not scaled/altered and have -/// output values roughly in the range (-18k,18k) -extern int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z); -extern int16_t inoise16_raw(uint32_t x, uint32_t y); -extern int16_t inoise16_raw(uint32_t x); -///@} - -/// @name 8 bit scaled noise functions -///@{ -/// 8 bit, fixed point implementation of perlin's Simplex Noise. Coordinates are -/// 8.8 fixed point values, 16 bit integers with integral coordinates in the high 8 -/// bits and fractional in the low 8 bits, and the function takes 1d, 2d, and 3d coordinate -/// values. These functions are scaled to return 0-255 -extern uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z); -extern uint8_t inoise8(uint16_t x, uint16_t y); -extern uint8_t inoise8(uint16_t x); -///@} - -/// @name 8 bit raw noise functions -///@{ -/// 8 bit raw versions of the noise functions. These values are not scaled/altered and have -/// output values roughly in the range (-70,70) -extern int8_t inoise8_raw(uint16_t x, uint16_t y, uint16_t z); -extern int8_t inoise8_raw(uint16_t x, uint16_t y); -extern int8_t inoise8_raw(uint16_t x); -///@} - -///@name raw fill functions -///@{ -/// Raw noise fill functions - fill into a 1d or 2d array of 8-bit values using either 8-bit noise or 16-bit noise -/// functions. -///@param pData the array of data to write into -///@param num_points the number of points of noise to compute -///@param octaves the number of octaves to use for noise -///@param x the x position in the noise field -///@param y the y position in the noise field for 2d functions -///@param scalex the scale (distance) between x points when filling in noise -///@param scaley the scale (distance) between y points when filling in noise -///@param time the time position for the noise field -void fill_raw_noise8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint16_t x, int scalex, uint16_t time); -void fill_raw_noise16into8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint32_t x, int scalex, uint32_t time); -void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time); -void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time); - -void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, q88 freq88, fract16 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time); -void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time); -///@} - -///@name fill functions -///@{ -/// fill functions to fill leds with values based on noise functions. These functions use the fill_raw_* functions as appropriate. -void fill_noise8(CRGB *leds, int num_leds, - uint8_t octaves, uint16_t x, int scale, - uint8_t hue_octaves, uint16_t hue_x, int hue_scale, - uint16_t time); -void fill_noise16(CRGB *leds, int num_leds, - uint8_t octaves, uint16_t x, int scale, - uint8_t hue_octaves, uint16_t hue_x, int hue_scale, - uint16_t time, uint8_t hue_shift=0); -void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, - uint8_t octaves, uint16_t x, int xscale, uint16_t y, int yscale, uint16_t time, - uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time,bool blend); -void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, - uint8_t octaves, uint32_t x, int xscale, uint32_t y, int yscale, uint32_t time, - uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend, uint16_t hue_shift=0); - -FASTLED_NAMESPACE_END -///@} - -#endif diff --git a/FastLED/src/pixelset.h b/FastLED/src/pixelset.h deleted file mode 100644 index b8488c2ced415a43691bd2ec6e093ebadf4f4fd3..0000000000000000000000000000000000000000 --- a/FastLED/src/pixelset.h +++ /dev/null @@ -1,306 +0,0 @@ -#ifndef __INC_PIXELSET_H -#define __INC_PIXELSET_H - -#include "FastLED.h" - -#ifndef abs -#include <stdlib.h> -#endif - -///// Represents a set of CRGB led objects. Provides the [] array operator, and works like a normal array in that case. -///// This should be kept in sync with the set of functions provided by CRGB as well as functions in colorutils. Note -///// that a pixel set is a window into another set of led data, it is not its own set of led data. -template<class PIXEL_TYPE> -class CPixelView { -public: - const int8_t dir; - const int len; - PIXEL_TYPE * const leds; - PIXEL_TYPE * const end_pos; - -public: - /// PixelSet copy constructor - inline CPixelView(const CPixelView & other) : dir(other.dir), len(other.len), leds(other.leds), end_pos(other.end_pos) {} - - /// pixelset constructor for a pixel set starting at the given PIXEL_TYPE* and going for _len leds. Note that the length - /// can be backwards, creating a PixelSet that walks backwards over the data - /// @param leds point to the raw led data - /// @param len how many leds in this set - inline CPixelView(PIXEL_TYPE *_leds, int _len) : dir(_len < 0 ? -1 : 1), len(_len), leds(_leds), end_pos(_leds + _len) {} - - /// PixelSet constructor for the given set of leds, with start and end boundaries. Note that start can be after - /// end, resulting in a set that will iterate backwards - /// @param leds point to the raw led data - /// @param start the start index of the leds for this array - /// @param end the end index of the leds for this array - inline CPixelView(PIXEL_TYPE *_leds, int _start, int _end) : dir(((_end-_start)<0) ? -1 : 1), len((_end - _start) + dir), leds(_leds + _start), end_pos(_leds + _start + len) {} - - /// Get the size of this set - /// @return the size of the set - int size() { return abs(len); } - - /// Whether or not this set goes backwards - /// @return whether or not the set is backwards - bool reversed() { return len < 0; } - - /// do these sets point to the same thing (note, this is different from the contents of the set being the same) - bool operator==(const CPixelView & rhs) const { return leds == rhs.leds && len == rhs.len && dir == rhs.dir; } - - /// do these sets point to the different things (note, this is different from the contents of the set being the same) - bool operator!=(const CPixelView & rhs) const { return leds != rhs.leds || len != rhs.len || dir != rhs.dir; } - - /// access a single element in this set, just like an array operator - inline PIXEL_TYPE & operator[](int x) const { if(dir & 0x80) { return leds[-x]; } else { return leds[x]; } } - - /// Access an inclusive subset of the leds in this set. Note that start can be greater than end, which will - /// result in a reverse ordering for many functions (useful for mirroring) - /// @param start the first element from this set for the new subset - /// @param end the last element for the new subset - inline CPixelView operator()(int start, int end) { return CPixelView(leds, start, end); } - - /// Access an inclusive subset of the leds in this set, starting from the first. - /// @param end the last element for the new subset - /// Not sure i want this? inline CPixelView operator()(int end) { return CPixelView(leds, 0, end); } - - /// Return the reverse ordering of this set - inline CPixelView operator-() { return CPixelView(leds, len - dir, 0); } - - /// Return a pointer to the first element in this set - inline operator PIXEL_TYPE* () const { return leds; } - - /// Assign the passed in color to all elements in this set - /// @param color the new color for the elements in the set - inline CPixelView & operator=(const PIXEL_TYPE & color) { - for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) = color; } - return *this; - } - - - void dump() const { - /** - Serial.print("len: "); Serial.print(len); Serial.print(", dir:"); Serial.print((int)dir); - Serial.print(", range:"); Serial.print((uint32_t)leds); Serial.print("-"); Serial.print((uint32_t)end_pos); - Serial.print(", diff:"); Serial.print((int32_t)(end_pos - leds)); - Serial.println(""); - **/ - } - - /// Copy the contents of the passed in set to our set. Note if one set is smaller than the other, only the - /// smallest number of items will be copied over. - inline CPixelView & operator=(const CPixelView & rhs) { - for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { - (*pixel) = (*rhspixel); - } - return *this; - } - - /// @name modification/scaling operators - //@{ - /// Add the passed in value to r,g, b for all the pixels in this set - inline CPixelView & addToRGB(uint8_t inc) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) += inc; } return *this; } - /// Add every pixel in the other set to this set - inline CPixelView & operator+=(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) += (*rhspixel); } return *this; } - - /// Subtract the passed in value from r,g,b for all pixels in this set - inline CPixelView & subFromRGB(uint8_t inc) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) -= inc; } return *this; } - /// Subtract every pixel in the other set from this set - inline CPixelView & operator-=(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) -= (*rhspixel); } return *this; } - - /// Increment every pixel value in this set - inline CPixelView & operator++() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)++; } return *this; } - /// Increment every pixel value in this set - inline CPixelView & operator++(int DUMMY_ARG) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)++; } return *this; } - - /// Decrement every pixel value in this set - inline CPixelView & operator--() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)--; } return *this; } - /// Decrement every pixel value in this set - inline CPixelView & operator--(int DUMMY_ARG) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)--; } return *this; } - - /// Divide every led by the given value - inline CPixelView & operator/=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) /= d; } return *this; } - /// Shift every led in this set right by the given number of bits - inline CPixelView & operator>>=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) >>= d; } return *this; } - /// Multiply every led in this set by the given value - inline CPixelView & operator*=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) *= d; } return *this; } - - /// Scale every led by the given scale - inline CPixelView & nscale8_video(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8_video(scaledown); } return *this;} - /// Scale down every led by the given scale - inline CPixelView & operator%=(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8_video(scaledown); } return *this; } - /// Fade every led down by the given scale - inline CPixelView & fadeLightBy(uint8_t fadefactor) { return nscale8_video(255 - fadefactor); } - - /// Scale every led by the given scale - inline CPixelView & nscale8(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8(scaledown); } return *this; } - /// Scale every led by the given scale - inline CPixelView & nscale8(PIXEL_TYPE & scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8(scaledown); } return *this; } - /// Scale every led in this set by every led in the other set - inline CPixelView & nscale8(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel).nscale8((*rhspixel)); } return *this; } - - /// Fade every led down by the given scale - inline CPixelView & fadeToBlackBy(uint8_t fade) { return nscale8(255 - fade); } - - /// Apply the PIXEL_TYPE |= operator to every pixel in this set with the given PIXEL_TYPE value (bringing each channel to the higher of the two values) - inline CPixelView & operator|=(const PIXEL_TYPE & rhs) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) |= rhs; } return *this; } - /// Apply the PIXEL_TYPE |= operator to every pixel in this set with every pixel in the passed in set - inline CPixelView & operator|=(const CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) |= (*rhspixel); } return *this; } - /// Apply the PIXEL_TYPE |= operator to every pixel in this set - inline CPixelView & operator|=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) |= d; } return *this; } - - /// Apply the PIXEL_TYPE &= operator to every pixel in this set with the given PIXEL_TYPE value (bringing each channel down to the lower of the two values) - inline CPixelView & operator&=(const PIXEL_TYPE & rhs) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) &= rhs; } return *this; } - /// Apply the PIXEL_TYPE &= operator to every pixel in this set with every pixel in the passed in set - inline CPixelView & operator&=(const CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) &= (*rhspixel); } return *this; } - /// APply the PIXEL_TYPE &= operator to every pixel in this set with the passed in value - inline CPixelView & operator&=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) &= d; } return *this; } - //@} - - /// Returns whether or not any leds in this set are non-zero - inline operator bool() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { if((*pixel)) return true; } return false; } - - // Color util functions - inline CPixelView & fill_solid(const PIXEL_TYPE & color) { *this = color; return *this; } - inline CPixelView & fill_solid(const CHSV & color) { if(dir>0) { *this = color; return *this; } } - - inline CPixelView & fill_rainbow(uint8_t initialhue, uint8_t deltahue=5) { - if(dir >= 0) { - ::fill_rainbow(leds,len,initialhue,deltahue); - } else { - ::fill_rainbow(leds+len+1,-len,initialhue,deltahue); - } - return *this; - } - - inline CPixelView & fill_gradient(const CHSV & startcolor, const CHSV & endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES) { - if(dir >= 0) { - ::fill_gradient(leds,len,startcolor, endcolor, directionCode); - } else { - ::fill_gradient(leds + len + 1, (-len), endcolor, startcolor, directionCode); - } - return *this; - } - - inline CPixelView & fill_gradient(const CHSV & c1, const CHSV & c2, const CHSV & c3, TGradientDirectionCode directionCode = SHORTEST_HUES) { - if(dir >= 0) { - ::fill_gradient(leds, len, c1, c2, c3, directionCode); - } else { - ::fill_gradient(leds + len + 1, -len, c3, c2, c1, directionCode); - } - return *this; - } - - inline CPixelView & fill_gradient(const CHSV & c1, const CHSV & c2, const CHSV & c3, const CHSV & c4, TGradientDirectionCode directionCode = SHORTEST_HUES) { - if(dir >= 0) { - ::fill_gradient(leds, len, c1, c2, c3, c4, directionCode); - } else { - ::fill_gradient(leds + len + 1, -len, c4, c3, c2, c1, directionCode); - } - return *this; - } - - inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & startcolor, const PIXEL_TYPE & endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES) { - if(dir >= 0) { - ::fill_gradient_RGB(leds,len,startcolor, endcolor); - } else { - ::fill_gradient_RGB(leds + len + 1, (-len), endcolor, startcolor); - } - return *this; - } - - inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & c1, const PIXEL_TYPE & c2, const PIXEL_TYPE & c3) { - if(dir >= 0) { - ::fill_gradient_RGB(leds, len, c1, c2, c3); - } else { - ::fill_gradient_RGB(leds + len + 1, -len, c3, c2, c1); - } - return *this; - } - - inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & c1, const PIXEL_TYPE & c2, const PIXEL_TYPE & c3, const PIXEL_TYPE & c4) { - if(dir >= 0) { - ::fill_gradient_RGB(leds, len, c1, c2, c3, c4); - } else { - ::fill_gradient_RGB(leds + len + 1, -len, c4, c3, c2, c1); - } - return *this; - } - - inline CPixelView & nblend(const PIXEL_TYPE & overlay, fract8 amountOfOverlay) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { ::nblend((*pixel), overlay, amountOfOverlay); } return *this; } - inline CPixelView & nblend(const CPixelView & rhs, fract8 amountOfOverlay) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { ::nblend((*pixel), (*rhspixel), amountOfOverlay); } return *this; } - - // Note: only bringing in a 1d blur, not sure 2d blur makes sense when looking at sub arrays - inline CPixelView & blur1d(fract8 blur_amount) { - if(dir >= 0) { - ::blur1d(leds, len, blur_amount); - } else { - ::blur1d(leds + len + 1, -len, blur_amount); - } - return *this; - } - - inline CPixelView & napplyGamma_video(float gamma) { - if(dir >= 0) { - ::napplyGamma_video(leds, len, gamma); - } else { - ::napplyGamma_video(leds + len + 1, -len, gamma); - } - return *this; - } - - inline CPixelView & napplyGamma_video(float gammaR, float gammaG, float gammaB) { - if(dir >= 0) { - ::napplyGamma_video(leds, len, gammaR, gammaG, gammaB); - } else { - ::napplyGamma_video(leds + len + 1, -len, gammaR, gammaG, gammaB); - } - return *this; - } - - // TODO: Make this a fully specified/proper iterator - template <class T> - class pixelset_iterator_base { - T * leds; - const int8_t dir; - - public: - __attribute__((always_inline)) inline pixelset_iterator_base(const pixelset_iterator_base & rhs) : leds(rhs.leds), dir(rhs.dir) {} - __attribute__((always_inline)) inline pixelset_iterator_base(T * _leds, const char _dir) : leds(_leds), dir(_dir) {} - - __attribute__((always_inline)) inline pixelset_iterator_base& operator++() { leds += dir; return *this; } - __attribute__((always_inline)) inline pixelset_iterator_base operator++(int) { pixelset_iterator_base tmp(*this); leds += dir; return tmp; } - - __attribute__((always_inline)) inline bool operator==(pixelset_iterator_base & other) const { return leds == other.leds; } // && set==other.set; } - __attribute__((always_inline)) inline bool operator!=(pixelset_iterator_base & other) const { return leds != other.leds; } // || set != other.set; } - - __attribute__((always_inline)) inline PIXEL_TYPE& operator*() const { return *leds; } - }; - - typedef pixelset_iterator_base<PIXEL_TYPE> iterator; - typedef pixelset_iterator_base<const PIXEL_TYPE> const_iterator; - - iterator begin() { return iterator(leds, dir); } - iterator end() { return iterator(end_pos, dir); } - - iterator begin() const { return iterator(leds, dir); } - iterator end() const { return iterator(end_pos, dir); } - - const_iterator cbegin() const { return const_iterator(leds, dir); } - const_iterator cend() const { return const_iterator(end_pos, dir); } -}; - -typedef CPixelView<CRGB> CRGBSet; - -__attribute__((always_inline)) -inline CRGB *operator+(const CRGBSet & pixels, int offset) { return (CRGB*)pixels + offset; } - - -template<int SIZE> -class CRGBArray : public CPixelView<CRGB> { - CRGB rawleds[SIZE]; - -public: - CRGBArray() : CPixelView<CRGB>(rawleds, SIZE) {} - using CPixelView::operator=; -}; - -#endif diff --git a/FastLED/src/pixeltypes.h b/FastLED/src/pixeltypes.h deleted file mode 100644 index 6e91723df0d10be8f5887242f8b5d91b101a58f4..0000000000000000000000000000000000000000 --- a/FastLED/src/pixeltypes.h +++ /dev/null @@ -1,856 +0,0 @@ -#ifndef __INC_PIXELS_H -#define __INC_PIXELS_H - -#include "FastLED.h" - -#include <stdint.h> -#include "lib8tion.h" -#include "color.h" - -FASTLED_NAMESPACE_BEGIN - -struct CRGB; -struct CHSV; - -///@defgroup Pixeltypes CHSV and CRGB type definitions -///@{ - -/// Forward declaration of hsv2rgb_rainbow here, -/// to avoid circular dependencies. -extern void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb); - -/// Representation of an HSV pixel (hue, saturation, value (aka brightness)). -struct CHSV { - union { - struct { - union { - uint8_t hue; - uint8_t h; }; - union { - uint8_t saturation; - uint8_t sat; - uint8_t s; }; - union { - uint8_t value; - uint8_t val; - uint8_t v; }; - }; - uint8_t raw[3]; - }; - - /// Array access operator to index into the chsv object - inline uint8_t& operator[] (uint8_t x) __attribute__((always_inline)) - { - return raw[x]; - } - - /// Array access operator to index into the chsv object - inline const uint8_t& operator[] (uint8_t x) const __attribute__((always_inline)) - { - return raw[x]; - } - - /// default values are UNITIALIZED - inline CHSV() __attribute__((always_inline)) = default; - - /// allow construction from H, S, V - inline CHSV( uint8_t ih, uint8_t is, uint8_t iv) __attribute__((always_inline)) - : h(ih), s(is), v(iv) - { - } - - /// allow copy construction - inline CHSV(const CHSV& rhs) __attribute__((always_inline)) = default; - - inline CHSV& operator= (const CHSV& rhs) __attribute__((always_inline)) = default; - - inline CHSV& setHSV(uint8_t ih, uint8_t is, uint8_t iv) __attribute__((always_inline)) - { - h = ih; - s = is; - v = iv; - return *this; - } -}; - -/// Pre-defined hue values for HSV objects -typedef enum { - HUE_RED = 0, - HUE_ORANGE = 32, - HUE_YELLOW = 64, - HUE_GREEN = 96, - HUE_AQUA = 128, - HUE_BLUE = 160, - HUE_PURPLE = 192, - HUE_PINK = 224 -} HSVHue; - -/// Representation of an RGB pixel (Red, Green, Blue) -struct CRGB { - union { - struct { - union { - uint8_t r; - uint8_t red; - }; - union { - uint8_t g; - uint8_t green; - }; - union { - uint8_t b; - uint8_t blue; - }; - }; - uint8_t raw[3]; - }; - - /// Array access operator to index into the crgb object - inline uint8_t& operator[] (uint8_t x) __attribute__((always_inline)) - { - return raw[x]; - } - - /// Array access operator to index into the crgb object - inline const uint8_t& operator[] (uint8_t x) const __attribute__((always_inline)) - { - return raw[x]; - } - - // default values are UNINITIALIZED - inline CRGB() __attribute__((always_inline)) = default; - - /// allow construction from R, G, B - inline CRGB( uint8_t ir, uint8_t ig, uint8_t ib) __attribute__((always_inline)) - : r(ir), g(ig), b(ib) - { - } - - /// allow construction from 32-bit (really 24-bit) bit 0xRRGGBB color code - inline CRGB( uint32_t colorcode) __attribute__((always_inline)) - : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) - { - } - - /// allow construction from a LEDColorCorrection enum - inline CRGB( LEDColorCorrection colorcode) __attribute__((always_inline)) - : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) - { - - } - - /// allow construction from a ColorTemperature enum - inline CRGB( ColorTemperature colorcode) __attribute__((always_inline)) - : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) - { - - } - - /// allow copy construction - inline CRGB(const CRGB& rhs) __attribute__((always_inline)) = default; - /// allow construction from HSV color - inline CRGB(const CHSV& rhs) __attribute__((always_inline)) - { - hsv2rgb_rainbow( rhs, *this); - } - - /// allow assignment from one RGB struct to another - inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline)) = default; - - /// allow assignment from 32-bit (really 24-bit) 0xRRGGBB color code - inline CRGB& operator= (const uint32_t colorcode) __attribute__((always_inline)) - { - r = (colorcode >> 16) & 0xFF; - g = (colorcode >> 8) & 0xFF; - b = (colorcode >> 0) & 0xFF; - return *this; - } - - /// allow assignment from R, G, and B - inline CRGB& setRGB (uint8_t nr, uint8_t ng, uint8_t nb) __attribute__((always_inline)) - { - r = nr; - g = ng; - b = nb; - return *this; - } - - /// allow assignment from H, S, and V - inline CRGB& setHSV (uint8_t hue, uint8_t sat, uint8_t val) __attribute__((always_inline)) - { - hsv2rgb_rainbow( CHSV(hue, sat, val), *this); - return *this; - } - - /// allow assignment from just a Hue, saturation and value automatically at max. - inline CRGB& setHue (uint8_t hue) __attribute__((always_inline)) - { - hsv2rgb_rainbow( CHSV(hue, 255, 255), *this); - return *this; - } - - /// allow assignment from HSV color - inline CRGB& operator= (const CHSV& rhs) __attribute__((always_inline)) - { - hsv2rgb_rainbow( rhs, *this); - return *this; - } - - /// allow assignment from 32-bit (really 24-bit) 0xRRGGBB color code - inline CRGB& setColorCode (uint32_t colorcode) __attribute__((always_inline)) - { - r = (colorcode >> 16) & 0xFF; - g = (colorcode >> 8) & 0xFF; - b = (colorcode >> 0) & 0xFF; - return *this; - } - - - /// add one RGB to another, saturating at 0xFF for each channel - inline CRGB& operator+= (const CRGB& rhs ) - { - r = qadd8( r, rhs.r); - g = qadd8( g, rhs.g); - b = qadd8( b, rhs.b); - return *this; - } - - /// add a contstant to each channel, saturating at 0xFF - /// this is NOT an operator+= overload because the compiler - /// can't usefully decide when it's being passed a 32-bit - /// constant (e.g. CRGB::Red) and an 8-bit one (CRGB::Blue) - inline CRGB& addToRGB (uint8_t d ) - { - r = qadd8( r, d); - g = qadd8( g, d); - b = qadd8( b, d); - return *this; - } - - /// subtract one RGB from another, saturating at 0x00 for each channel - inline CRGB& operator-= (const CRGB& rhs ) - { - r = qsub8( r, rhs.r); - g = qsub8( g, rhs.g); - b = qsub8( b, rhs.b); - return *this; - } - - /// subtract a constant from each channel, saturating at 0x00 - /// this is NOT an operator+= overload because the compiler - /// can't usefully decide when it's being passed a 32-bit - /// constant (e.g. CRGB::Red) and an 8-bit one (CRGB::Blue) - inline CRGB& subtractFromRGB(uint8_t d ) - { - r = qsub8( r, d); - g = qsub8( g, d); - b = qsub8( b, d); - return *this; - } - - /// subtract a constant of '1' from each channel, saturating at 0x00 - inline CRGB& operator-- () __attribute__((always_inline)) - { - subtractFromRGB(1); - return *this; - } - - /// subtract a constant of '1' from each channel, saturating at 0x00 - inline CRGB operator-- (int ) __attribute__((always_inline)) - { - CRGB retval(*this); - --(*this); - return retval; - } - - /// add a constant of '1' from each channel, saturating at 0xFF - inline CRGB& operator++ () __attribute__((always_inline)) - { - addToRGB(1); - return *this; - } - - /// add a constant of '1' from each channel, saturating at 0xFF - inline CRGB operator++ (int ) __attribute__((always_inline)) - { - CRGB retval(*this); - ++(*this); - return retval; - } - - /// divide each of the channels by a constant - inline CRGB& operator/= (uint8_t d ) - { - r /= d; - g /= d; - b /= d; - return *this; - } - - /// right shift each of the channels by a constant - inline CRGB& operator>>= (uint8_t d) - { - r >>= d; - g >>= d; - b >>= d; - return *this; - } - - /// multiply each of the channels by a constant, - /// saturating each channel at 0xFF - inline CRGB& operator*= (uint8_t d ) - { - r = qmul8( r, d); - g = qmul8( g, d); - b = qmul8( b, d); - return *this; - } - - /// scale down a RGB to N 256ths of it's current brightness, using - /// 'video' dimming rules, which means that unless the scale factor is ZERO - /// each channel is guaranteed NOT to dim down to zero. If it's already - /// nonzero, it'll stay nonzero, even if that means the hue shifts a little - /// at low brightness levels. - inline CRGB& nscale8_video (uint8_t scaledown ) - { - nscale8x3_video( r, g, b, scaledown); - return *this; - } - - /// %= is a synonym for nscale8_video. Think of it is scaling down - /// by "a percentage" - inline CRGB& operator%= (uint8_t scaledown ) - { - nscale8x3_video( r, g, b, scaledown); - return *this; - } - - /// fadeLightBy is a synonym for nscale8_video( ..., 255-fadefactor) - inline CRGB& fadeLightBy (uint8_t fadefactor ) - { - nscale8x3_video( r, g, b, 255 - fadefactor); - return *this; - } - - /// scale down a RGB to N 256ths of it's current brightness, using - /// 'plain math' dimming rules, which means that if the low light levels - /// may dim all the way to 100% black. - inline CRGB& nscale8 (uint8_t scaledown ) - { - nscale8x3( r, g, b, scaledown); - return *this; - } - - /// scale down a RGB to N 256ths of it's current brightness, using - /// 'plain math' dimming rules, which means that if the low light levels - /// may dim all the way to 100% black. - inline CRGB& nscale8 (const CRGB & scaledown ) - { - r = ::scale8(r, scaledown.r); - g = ::scale8(g, scaledown.g); - b = ::scale8(b, scaledown.b); - return *this; - } - - /// return a CRGB object that is a scaled down version of this object - inline CRGB scale8 (const CRGB & scaledown ) const - { - CRGB out; - out.r = ::scale8(r, scaledown.r); - out.g = ::scale8(g, scaledown.g); - out.b = ::scale8(b, scaledown.b); - return out; - } - - /// fadeToBlackBy is a synonym for nscale8( ..., 255-fadefactor) - inline CRGB& fadeToBlackBy (uint8_t fadefactor ) - { - nscale8x3( r, g, b, 255 - fadefactor); - return *this; - } - - /// "or" operator brings each channel up to the higher of the two values - inline CRGB& operator|= (const CRGB& rhs ) - { - if( rhs.r > r) r = rhs.r; - if( rhs.g > g) g = rhs.g; - if( rhs.b > b) b = rhs.b; - return *this; - } - - /// "or" operator brings each channel up to the higher of the two values - inline CRGB& operator|= (uint8_t d ) - { - if( d > r) r = d; - if( d > g) g = d; - if( d > b) b = d; - return *this; - } - - /// "and" operator brings each channel down to the lower of the two values - inline CRGB& operator&= (const CRGB& rhs ) - { - if( rhs.r < r) r = rhs.r; - if( rhs.g < g) g = rhs.g; - if( rhs.b < b) b = rhs.b; - return *this; - } - - /// "and" operator brings each channel down to the lower of the two values - inline CRGB& operator&= (uint8_t d ) - { - if( d < r) r = d; - if( d < g) g = d; - if( d < b) b = d; - return *this; - } - - /// this allows testing a CRGB for zero-ness - inline operator bool() const __attribute__((always_inline)) - { - return r || g || b; - } - - /// invert each channel - inline CRGB operator- () - { - CRGB retval; - retval.r = 255 - r; - retval.g = 255 - g; - retval.b = 255 - b; - return retval; - } - -#if (defined SmartMatrix_h || defined SmartMatrix3_h) - operator rgb24() const { - rgb24 ret; - ret.red = r; - ret.green = g; - ret.blue = b; - return ret; - } -#endif - - /// Get the 'luma' of a CRGB object - aka roughly how much light the - /// CRGB pixel is putting out (from 0 to 255). - inline uint8_t getLuma ( ) const { - //Y' = 0.2126 R' + 0.7152 G' + 0.0722 B' - // 54 183 18 (!) - - uint8_t luma = scale8_LEAVING_R1_DIRTY( r, 54) + \ - scale8_LEAVING_R1_DIRTY( g, 183) + \ - scale8_LEAVING_R1_DIRTY( b, 18); - cleanup_R1(); - return luma; - } - - /// Get the average of the R, G, and B values - inline uint8_t getAverageLight( ) const { -#if FASTLED_SCALE8_FIXED == 1 - const uint8_t eightyfive = 85; -#else - const uint8_t eightyfive = 86; -#endif - uint8_t avg = scale8_LEAVING_R1_DIRTY( r, eightyfive) + \ - scale8_LEAVING_R1_DIRTY( g, eightyfive) + \ - scale8_LEAVING_R1_DIRTY( b, eightyfive); - cleanup_R1(); - return avg; - } - - /// maximize the brightness of this CRGB object - inline void maximizeBrightness( uint8_t limit = 255 ) { - uint8_t max = red; - if( green > max) max = green; - if( blue > max) max = blue; - - // stop div/0 when color is black - if(max > 0) { - uint16_t factor = ((uint16_t)(limit) * 256) / max; - red = (red * factor) / 256; - green = (green * factor) / 256; - blue = (blue * factor) / 256; - } - } - - /// return a new CRGB object after performing a linear interpolation between this object and the passed in object - inline CRGB lerp8( const CRGB& other, fract8 frac) const - { - CRGB ret; - - ret.r = lerp8by8(r,other.r,frac); - ret.g = lerp8by8(g,other.g,frac); - ret.b = lerp8by8(b,other.b,frac); - - return ret; - } - - /// return a new CRGB object after performing a linear interpolation between this object and the passed in object - inline CRGB lerp16( const CRGB& other, fract16 frac) const - { - CRGB ret; - - ret.r = lerp16by16(r<<8,other.r<<8,frac)>>8; - ret.g = lerp16by16(g<<8,other.g<<8,frac)>>8; - ret.b = lerp16by16(b<<8,other.b<<8,frac)>>8; - - return ret; - } - - /// getParity returns 0 or 1, depending on the - /// lowest bit of the sum of the color components. - inline uint8_t getParity() - { - uint8_t sum = r + g + b; - return (sum & 0x01); - } - - /// setParity adjusts the color in the smallest - /// way possible so that the parity of the color - /// is now the desired value. This allows you to - /// 'hide' one bit of information in the color. - /// - /// Ideally, we find one color channel which already - /// has data in it, and modify just that channel by one. - /// We don't want to light up a channel that's black - /// if we can avoid it, and if the pixel is 'grayscale', - /// (meaning that R==G==B), we modify all three channels - /// at once, to preserve the neutral hue. - /// - /// There's no such thing as a free lunch; in many cases - /// this 'hidden bit' may actually be visible, but this - /// code makes reasonable efforts to hide it as much - /// as is reasonably possible. - /// - /// Also, an effort is made to have make it such that - /// repeatedly setting the parity to different values - /// will not cause the color to 'drift'. Toggling - /// the parity twice should generally result in the - /// original color again. - /// - inline void setParity( uint8_t parity) - { - uint8_t curparity = getParity(); - - if( parity == curparity) return; - - if( parity ) { - // going 'up' - if( (b > 0) && (b < 255)) { - if( r == g && g == b) { - ++r; - ++g; - } - ++b; - } else if( (r > 0) && (r < 255)) { - ++r; - } else if( (g > 0) && (g < 255)) { - ++g; - } else { - if( r == g && g == b) { - r ^= 0x01; - g ^= 0x01; - } - b ^= 0x01; - } - } else { - // going 'down' - if( b > 1) { - if( r == g && g == b) { - --r; - --g; - } - --b; - } else if( g > 1) { - --g; - } else if( r > 1) { - --r; - } else { - if( r == g && g == b) { - r ^= 0x01; - g ^= 0x01; - } - b ^= 0x01; - } - } - } - - /// Predefined RGB colors - typedef enum { - AliceBlue=0xF0F8FF, - Amethyst=0x9966CC, - AntiqueWhite=0xFAEBD7, - Aqua=0x00FFFF, - Aquamarine=0x7FFFD4, - Azure=0xF0FFFF, - Beige=0xF5F5DC, - Bisque=0xFFE4C4, - Black=0x000000, - BlanchedAlmond=0xFFEBCD, - Blue=0x0000FF, - BlueViolet=0x8A2BE2, - Brown=0xA52A2A, - BurlyWood=0xDEB887, - CadetBlue=0x5F9EA0, - Chartreuse=0x7FFF00, - Chocolate=0xD2691E, - Coral=0xFF7F50, - CornflowerBlue=0x6495ED, - Cornsilk=0xFFF8DC, - Crimson=0xDC143C, - Cyan=0x00FFFF, - DarkBlue=0x00008B, - DarkCyan=0x008B8B, - DarkGoldenrod=0xB8860B, - DarkGray=0xA9A9A9, - DarkGrey=0xA9A9A9, - DarkGreen=0x006400, - DarkKhaki=0xBDB76B, - DarkMagenta=0x8B008B, - DarkOliveGreen=0x556B2F, - DarkOrange=0xFF8C00, - DarkOrchid=0x9932CC, - DarkRed=0x8B0000, - DarkSalmon=0xE9967A, - DarkSeaGreen=0x8FBC8F, - DarkSlateBlue=0x483D8B, - DarkSlateGray=0x2F4F4F, - DarkSlateGrey=0x2F4F4F, - DarkTurquoise=0x00CED1, - DarkViolet=0x9400D3, - DeepPink=0xFF1493, - DeepSkyBlue=0x00BFFF, - DimGray=0x696969, - DimGrey=0x696969, - DodgerBlue=0x1E90FF, - FireBrick=0xB22222, - FloralWhite=0xFFFAF0, - ForestGreen=0x228B22, - Fuchsia=0xFF00FF, - Gainsboro=0xDCDCDC, - GhostWhite=0xF8F8FF, - Gold=0xFFD700, - Goldenrod=0xDAA520, - Gray=0x808080, - Grey=0x808080, - Green=0x008000, - GreenYellow=0xADFF2F, - Honeydew=0xF0FFF0, - HotPink=0xFF69B4, - IndianRed=0xCD5C5C, - Indigo=0x4B0082, - Ivory=0xFFFFF0, - Khaki=0xF0E68C, - Lavender=0xE6E6FA, - LavenderBlush=0xFFF0F5, - LawnGreen=0x7CFC00, - LemonChiffon=0xFFFACD, - LightBlue=0xADD8E6, - LightCoral=0xF08080, - LightCyan=0xE0FFFF, - LightGoldenrodYellow=0xFAFAD2, - LightGreen=0x90EE90, - LightGrey=0xD3D3D3, - LightPink=0xFFB6C1, - LightSalmon=0xFFA07A, - LightSeaGreen=0x20B2AA, - LightSkyBlue=0x87CEFA, - LightSlateGray=0x778899, - LightSlateGrey=0x778899, - LightSteelBlue=0xB0C4DE, - LightYellow=0xFFFFE0, - Lime=0x00FF00, - LimeGreen=0x32CD32, - Linen=0xFAF0E6, - Magenta=0xFF00FF, - Maroon=0x800000, - MediumAquamarine=0x66CDAA, - MediumBlue=0x0000CD, - MediumOrchid=0xBA55D3, - MediumPurple=0x9370DB, - MediumSeaGreen=0x3CB371, - MediumSlateBlue=0x7B68EE, - MediumSpringGreen=0x00FA9A, - MediumTurquoise=0x48D1CC, - MediumVioletRed=0xC71585, - MidnightBlue=0x191970, - MintCream=0xF5FFFA, - MistyRose=0xFFE4E1, - Moccasin=0xFFE4B5, - NavajoWhite=0xFFDEAD, - Navy=0x000080, - OldLace=0xFDF5E6, - Olive=0x808000, - OliveDrab=0x6B8E23, - Orange=0xFFA500, - OrangeRed=0xFF4500, - Orchid=0xDA70D6, - PaleGoldenrod=0xEEE8AA, - PaleGreen=0x98FB98, - PaleTurquoise=0xAFEEEE, - PaleVioletRed=0xDB7093, - PapayaWhip=0xFFEFD5, - PeachPuff=0xFFDAB9, - Peru=0xCD853F, - Pink=0xFFC0CB, - Plaid=0xCC5533, - Plum=0xDDA0DD, - PowderBlue=0xB0E0E6, - Purple=0x800080, - Red=0xFF0000, - RosyBrown=0xBC8F8F, - RoyalBlue=0x4169E1, - SaddleBrown=0x8B4513, - Salmon=0xFA8072, - SandyBrown=0xF4A460, - SeaGreen=0x2E8B57, - Seashell=0xFFF5EE, - Sienna=0xA0522D, - Silver=0xC0C0C0, - SkyBlue=0x87CEEB, - SlateBlue=0x6A5ACD, - SlateGray=0x708090, - SlateGrey=0x708090, - Snow=0xFFFAFA, - SpringGreen=0x00FF7F, - SteelBlue=0x4682B4, - Tan=0xD2B48C, - Teal=0x008080, - Thistle=0xD8BFD8, - Tomato=0xFF6347, - Turquoise=0x40E0D0, - Violet=0xEE82EE, - Wheat=0xF5DEB3, - White=0xFFFFFF, - WhiteSmoke=0xF5F5F5, - Yellow=0xFFFF00, - YellowGreen=0x9ACD32, - - // LED RGB color that roughly approximates - // the color of incandescent fairy lights, - // assuming that you're using FastLED - // color correction on your LEDs (recommended). - FairyLight=0xFFE42D, - // If you are using no color correction, use this - FairyLightNCC=0xFF9D2A - - } HTMLColorCode; -}; - - -inline __attribute__((always_inline)) bool operator== (const CRGB& lhs, const CRGB& rhs) -{ - return (lhs.r == rhs.r) && (lhs.g == rhs.g) && (lhs.b == rhs.b); -} - -inline __attribute__((always_inline)) bool operator!= (const CRGB& lhs, const CRGB& rhs) -{ - return !(lhs == rhs); -} - -inline __attribute__((always_inline)) bool operator< (const CRGB& lhs, const CRGB& rhs) -{ - uint16_t sl, sr; - sl = lhs.r + lhs.g + lhs.b; - sr = rhs.r + rhs.g + rhs.b; - return sl < sr; -} - -inline __attribute__((always_inline)) bool operator> (const CRGB& lhs, const CRGB& rhs) -{ - uint16_t sl, sr; - sl = lhs.r + lhs.g + lhs.b; - sr = rhs.r + rhs.g + rhs.b; - return sl > sr; -} - -inline __attribute__((always_inline)) bool operator>= (const CRGB& lhs, const CRGB& rhs) -{ - uint16_t sl, sr; - sl = lhs.r + lhs.g + lhs.b; - sr = rhs.r + rhs.g + rhs.b; - return sl >= sr; -} - -inline __attribute__((always_inline)) bool operator<= (const CRGB& lhs, const CRGB& rhs) -{ - uint16_t sl, sr; - sl = lhs.r + lhs.g + lhs.b; - sr = rhs.r + rhs.g + rhs.b; - return sl <= sr; -} - - -__attribute__((always_inline)) -inline CRGB operator+( const CRGB& p1, const CRGB& p2) -{ - return CRGB( qadd8( p1.r, p2.r), - qadd8( p1.g, p2.g), - qadd8( p1.b, p2.b)); -} - -__attribute__((always_inline)) -inline CRGB operator-( const CRGB& p1, const CRGB& p2) -{ - return CRGB( qsub8( p1.r, p2.r), - qsub8( p1.g, p2.g), - qsub8( p1.b, p2.b)); -} - -__attribute__((always_inline)) -inline CRGB operator*( const CRGB& p1, uint8_t d) -{ - return CRGB( qmul8( p1.r, d), - qmul8( p1.g, d), - qmul8( p1.b, d)); -} - -__attribute__((always_inline)) -inline CRGB operator/( const CRGB& p1, uint8_t d) -{ - return CRGB( p1.r/d, p1.g/d, p1.b/d); -} - - -__attribute__((always_inline)) -inline CRGB operator&( const CRGB& p1, const CRGB& p2) -{ - return CRGB( p1.r < p2.r ? p1.r : p2.r, - p1.g < p2.g ? p1.g : p2.g, - p1.b < p2.b ? p1.b : p2.b); -} - -__attribute__((always_inline)) -inline CRGB operator|( const CRGB& p1, const CRGB& p2) -{ - return CRGB( p1.r > p2.r ? p1.r : p2.r, - p1.g > p2.g ? p1.g : p2.g, - p1.b > p2.b ? p1.b : p2.b); -} - -__attribute__((always_inline)) -inline CRGB operator%( const CRGB& p1, uint8_t d) -{ - CRGB retval( p1); - retval.nscale8_video( d); - return retval; -} - - - -/// RGB orderings, used when instantiating controllers to determine what -/// order the controller should send RGB data out in, RGB being the default -/// ordering. -enum EOrder { - RGB=0012, - RBG=0021, - GRB=0102, - GBR=0120, - BRG=0201, - BGR=0210 -}; - -FASTLED_NAMESPACE_END -///@} - -#endif diff --git a/FastLED/src/platforms.cpp b/FastLED/src/platforms.cpp deleted file mode 100644 index 5b6847ad67ce92bdb09572f0c511bfc7951da29a..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#define FASTLED_INTERNAL - - -// Interrupt handlers cannot be defined in the header. -// They must be defined as C functions, or they won't -// be found (due to name mangling), and thus won't -// override any default weak definition. -#if defined(NRF52_SERIES) - - #include "platforms/arm/nrf52/led_sysdefs_arm_nrf52.h" - #include "platforms/arm/nrf52/arbiter_nrf52.h" - - uint32_t isrCount; - - #ifdef __cplusplus - extern "C" { - #endif - // NOTE: Update platforms.cpp in root of FastLED library if this changes - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0) - void PWM0_IRQHandler(void) { ++isrCount; PWM_Arbiter<0>::isr_handler(); } - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1) - void PWM1_IRQHandler(void) { ++isrCount; PWM_Arbiter<1>::isr_handler(); } - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2) - void PWM2_IRQHandler(void) { ++isrCount; PWM_Arbiter<2>::isr_handler(); } - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3) - void PWM3_IRQHandler(void) { ++isrCount; PWM_Arbiter<3>::isr_handler(); } - #endif - #ifdef __cplusplus - } - #endif - -#endif // defined(NRF52_SERIES) - - - -// FASTLED_NAMESPACE_BEGIN -// FASTLED_NAMESPACE_END diff --git a/FastLED/src/platforms.h b/FastLED/src/platforms.h deleted file mode 100644 index 7969c9e4deb25fa9d9536002baada54b97198efb..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __INC_PLATFORMS_H -#define __INC_PLATFORMS_H - -#include "FastLED.h" - -#include "fastled_config.h" - -#if defined(NRF51) -#include "platforms/arm/nrf51/fastled_arm_nrf51.h" -#elif defined(NRF52_SERIES) -#include "platforms/arm/nrf52/fastled_arm_nrf52.h" -#elif defined(__MK20DX128__) || defined(__MK20DX256__) -// Include k20/T3 headers -#include "platforms/arm/k20/fastled_arm_k20.h" -#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) -// Include k66/T3.6 headers -#include "platforms/arm/k66/fastled_arm_k66.h" -#elif defined(__MKL26Z64__) -// Include kl26/T-LC headers -#include "platforms/arm/kl26/fastled_arm_kl26.h" -#elif defined(__IMXRT1062__) -// teensy4 -#include "platforms/arm/mxrt1062/fastled_arm_mxrt1062.h" -#elif defined(__SAM3X8E__) -// Include sam/due headers -#include "platforms/arm/sam/fastled_arm_sam.h" -#elif defined(STM32F10X_MD) || defined(__STM32F1__) -#include "platforms/arm/stm32/fastled_arm_stm32.h" -#elif defined(__SAMD21G18A__) || defined(__SAMD21J18A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__) -#include "platforms/arm/d21/fastled_arm_d21.h" -#elif defined(__SAMD51G19A__) || defined(__SAMD51J19A__) -#include "platforms/arm/d51/fastled_arm_d51.h" -#elif defined(ESP8266) -#include "platforms/esp/8266/fastled_esp8266.h" -#elif defined(ESP32) -#include "platforms/esp/32/fastled_esp32.h" -#elif defined(ARDUINO_ARCH_APOLLO3) -#include "platforms/apollo3/fastled_apollo3.h" -#else -// AVR platforms -#include "platforms/avr/fastled_avr.h" -#endif - -#endif diff --git a/FastLED/src/platforms/apollo3/clockless_apollo3.h b/FastLED/src/platforms/apollo3/clockless_apollo3.h deleted file mode 100644 index fa487c2f7679b079d2a453ccbe19c76d1ad9d91a..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/apollo3/clockless_apollo3.h +++ /dev/null @@ -1,184 +0,0 @@ -#ifndef __INC_CLOCKLESS_APOLLO3_H -#define __INC_CLOCKLESS_APOLLO3_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_APOLLO3) - -// Clockless support for the SparkFun Artemis / Ambiq Micro Apollo3 Blue -// Uses SysTick to govern the pulse timing - -//***************************************************************************** -// -// Code taken from Ambiq Micro's am_hal_systick.c -// and converted to inline static for speed -// -//! @brief Get the current count value in the SYSTICK. -//! -//! This function gets the current count value in the systick timer. -//! -//! @return Current count value. -// -//***************************************************************************** -__attribute__ ((always_inline)) inline static uint32_t __am_hal_systick_count() { - return SysTick->VAL; -} - -#define FASTLED_HAS_CLOCKLESS 1 - -template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<DATA_PIN>::port_t data_t; - - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - // Initialize everything - - // Configure DATA_PIN for FastGPIO (settings are in fastpin_apollo3.h) - FastPin<DATA_PIN>::setOutput(); - FastPin<DATA_PIN>::lo(); - - // Make sure the system clock is running at the full 48MHz - am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0); - - // Make sure interrupts are enabled - //am_hal_interrupt_master_enable(); - - // Enable SysTick Interrupts in the NVIC - //NVIC_EnableIRQ(SysTick_IRQn); - - // SysTick is 24-bit and counts down (not up) - - // Stop the SysTick (just in case it is already running). - // This clears the ENABLE bit in the SysTick Control and Status Register (SYST_CSR). - // In Ambiq naming convention, the control register is SysTick->CTRL - am_hal_systick_stop(); - - // Call SysTick_Config - // This is defined in core_cm4.h - // It loads the specified LOAD value into the SysTick Reload Value Register (SYST_RVR) - // In Ambiq naming convention, the reload register is SysTick->LOAD - // It sets the SysTick interrupt priority - // It clears the SysTick Current Value Register (SYST_CVR) - // In Ambiq naming convention, the current value register is SysTick->VAL - // Finally it sets these bits in the SysTick Control and Status Register (SYST_CSR): - // CLKSOURCE: SysTick uses the processor clock - // TICKINT: When the count reaches zero, the SysTick exception (interrupt) is changed to pending - // ENABLE: Enables the counter - // SysTick_Config returns 0 if successful. 1 indicates a failure (the LOAD value was invalid). - SysTick_Config(0xFFFFFFUL); // The LOAD value needs to be 24-bit - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - mWait.mark(); - } - - template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register uint8_t & b) { - // SysTick counts down (not up) and is 24-bit - for(register uint32_t i = BITS-1; i > 0; i--) { // We could speed this up by using Bit Banding - while(__am_hal_systick_count() > next_mark) { ; } // Wait for the remainder of this cycle to complete - // Calculate next_mark (the time of the next DATA_PIN transition) by subtracting T1+T2+T3 - // SysTick counts down (not up) and is 24-bit - next_mark = (__am_hal_systick_count() - (T1+T2+T3)) & 0xFFFFFFUL; - FastPin<DATA_PIN>::hi(); - if(b&0x80) { - // "1 code" = longer pulse width - while((__am_hal_systick_count() - next_mark) > (T3+(3*(F_CPU/24000000)))) { ; } - FastPin<DATA_PIN>::lo(); - } else { - // "0 code" = shorter pulse width - while((__am_hal_systick_count() - next_mark) > (T2+T3+(4*(F_CPU/24000000)))) { ; } - FastPin<DATA_PIN>::lo(); - } - b <<= 1; - } - - while(__am_hal_systick_count() > next_mark) { ; }// Wait for the remainder of this cycle to complete - // Calculate next_mark (the time of the next DATA_PIN transition) by subtracting T1+T2+T3 - // SysTick counts down (not up) and is 24-bit - next_mark = (__am_hal_systick_count() - (T1+T2+T3)) & 0xFFFFFFUL; - FastPin<DATA_PIN>::hi(); - if(b&0x80) { - // "1 code" = longer pulse width - while((__am_hal_systick_count() - next_mark) > (T3+(2*(F_CPU/24000000)))) { ; } - FastPin<DATA_PIN>::lo(); - } else { - // "0 code" = shorter pulse width - while((__am_hal_systick_count() - next_mark) > (T2+T3+(4*(F_CPU/24000000)))) { ; } - FastPin<DATA_PIN>::lo(); - } - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - - // Setup the pixel controller and load/scale the first byte - pixels.preStepFirstByteDithering(); - register uint8_t b = pixels.loadAndScale0(); - - cli(); - - // Calculate next_mark (the time of the next DATA_PIN transition) by subtracting T1+T2+T3 - // SysTick counts down (not up) and is 24-bit - // The subtraction could underflow (wrap round) so let's mask the result to 24 bits - register uint32_t next_mark = (__am_hal_systick_count() - (T1+T2+T3)) & 0xFFFFFFUL; - - while(pixels.has(1)) { // Keep going for as long as we have pixels - pixels.stepDithering(); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - - // Have we already missed the next_mark? - if(__am_hal_systick_count() < next_mark) { - // If we have exceeded next_mark by an excessive amount, then bail (return 0) - if((next_mark - __am_hal_systick_count()) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; } - } - #endif - - // Write first byte, read next byte - writeBits<8+XTRA0>(next_mark, b); - b = pixels.loadAndScale1(); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0>(next_mark, b); - b = pixels.loadAndScale2(); - - // Write third byte, read 1st byte of next pixel - writeBits<8+XTRA0>(next_mark, b); - b = pixels.advanceAndLoadAndScale0(); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; // end of while(pixels.has(1)) - - // Unfortunately SysTick relies on an interrupt to reload it once it reaches zero - // and having interrupts disabled for most of the above means the interrupt doesn't get serviced. - // So we had better reload it here instead... - am_hal_systick_load(0xFFFFFFUL); - - sei(); - return (1); - } - -}; - - -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/apollo3/fastled_apollo3.h b/FastLED/src/platforms/apollo3/fastled_apollo3.h deleted file mode 100644 index 4c727dd0c53d9ebb18bded62b75773f760c12b7a..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/apollo3/fastled_apollo3.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __INC_FASTLED_APOLLO3_H -#define __INC_FASTLED_APOLLO3_H - -#include "fastpin_apollo3.h" -#include "fastspi_apollo3.h" -#include "clockless_apollo3.h" - -#endif diff --git a/FastLED/src/platforms/apollo3/fastpin_apollo3.h b/FastLED/src/platforms/apollo3/fastpin_apollo3.h deleted file mode 100644 index 6d0f1e60be5fcb19402df76726ab8e9ad234e8c2..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/apollo3/fastpin_apollo3.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef __INC_FASTPIN_APOLLO3_H -#define __INC_FASTPIN_APOLLO3_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be slightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - -template<uint8_t PIN, uint8_t PAD> class _APOLLO3PIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); am_hal_gpio_fastgpio_enable(PAD); } - inline static void setInput() { am_hal_gpio_fastgpio_disable(PAD); pinMode(PIN, INPUT); } - - inline static void hi() __attribute__ ((always_inline)) { am_hal_gpio_fastgpio_set(PAD); } - inline static void lo() __attribute__ ((always_inline)) { am_hal_gpio_fastgpio_clr(PAD); } - inline static void set(register port_t val) __attribute__ ((always_inline)) { if(val) { am_hal_gpio_fastgpio_set(PAD); } else { am_hal_gpio_fastgpio_clr(PAD); } } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { if( am_hal_gpio_fastgpio_read(PAD)) { lo(); } else { hi(); } } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { set(val); } - - inline static port_t hival() __attribute__ ((always_inline)) { return 0; } - inline static port_t loval() __attribute__ ((always_inline)) { return 0; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; } - inline static port_t mask() __attribute__ ((always_inline)) { return 0; } -}; - -// For the Apollo3 we need to define both the pin number and the associated pad -// to avoid having to use ap3_gpio_pin2pad for fastgpio (which would slow things down) -#define _FL_DEFPIN(PIN, PAD) template<> class FastPin<PIN> : public _APOLLO3PIN<PIN, PAD> {}; - -// Actual (pin, pad) definitions -#if defined(ARDUINO_SFE_EDGE) - -#define MAX_PIN 49 -_FL_DEFPIN(0, 0); _FL_DEFPIN(1, 1); _FL_DEFPIN(3, 3); _FL_DEFPIN(4, 4); -_FL_DEFPIN(5, 5); _FL_DEFPIN(6, 6); _FL_DEFPIN(7, 7); _FL_DEFPIN(8, 8); _FL_DEFPIN(9, 9); -_FL_DEFPIN(10, 10); _FL_DEFPIN(11, 11); _FL_DEFPIN(12, 12); _FL_DEFPIN(13, 13); _FL_DEFPIN(14, 14); -_FL_DEFPIN(15, 15); _FL_DEFPIN(17, 17); -_FL_DEFPIN(20, 20); _FL_DEFPIN(21, 21); _FL_DEFPIN(22, 22); _FL_DEFPIN(23, 23); _FL_DEFPIN(24, 24); -_FL_DEFPIN(25, 25); _FL_DEFPIN(26, 26); _FL_DEFPIN(27, 27); _FL_DEFPIN(28, 28); _FL_DEFPIN(29, 29); -_FL_DEFPIN(33, 33); -_FL_DEFPIN(36, 36); _FL_DEFPIN(37, 37); _FL_DEFPIN(38, 38); _FL_DEFPIN(39, 39); -_FL_DEFPIN(40, 40); _FL_DEFPIN(42, 42); _FL_DEFPIN(43, 43); _FL_DEFPIN(44, 44); -_FL_DEFPIN(46, 46); _FL_DEFPIN(47, 47); _FL_DEFPIN(48, 48); _FL_DEFPIN(49, 49); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_SFE_EDGE2) - -#define MAX_PIN 49 -_FL_DEFPIN(0, 0); -_FL_DEFPIN(5, 5); _FL_DEFPIN(6, 6); _FL_DEFPIN(7, 7); _FL_DEFPIN(8, 8); _FL_DEFPIN(9, 9); -_FL_DEFPIN(11, 11); _FL_DEFPIN(12, 12); _FL_DEFPIN(13, 13); _FL_DEFPIN(14, 14); -_FL_DEFPIN(15, 15); _FL_DEFPIN(16, 16); _FL_DEFPIN(17, 17); _FL_DEFPIN(18, 18); _FL_DEFPIN(19, 19); -_FL_DEFPIN(20, 20); _FL_DEFPIN(21, 21); _FL_DEFPIN(23, 23); -_FL_DEFPIN(25, 25); _FL_DEFPIN(26, 26); _FL_DEFPIN(27, 27); _FL_DEFPIN(28, 28); _FL_DEFPIN(29, 29); -_FL_DEFPIN(31, 31); _FL_DEFPIN(32, 32); _FL_DEFPIN(33, 33); _FL_DEFPIN(34, 34); -_FL_DEFPIN(35, 35); _FL_DEFPIN(37, 37); _FL_DEFPIN(39, 39); -_FL_DEFPIN(40, 40); _FL_DEFPIN(41, 41); _FL_DEFPIN(42, 42); _FL_DEFPIN(43, 43); _FL_DEFPIN(44, 44); -_FL_DEFPIN(45, 45); _FL_DEFPIN(48, 48); _FL_DEFPIN(49, 49); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_AM_AP3_SFE_BB_ARTEMIS) - -#define MAX_PIN 31 -_FL_DEFPIN(0, 25); _FL_DEFPIN(1, 24); _FL_DEFPIN(2, 35); _FL_DEFPIN(3, 4); _FL_DEFPIN(4, 22); -_FL_DEFPIN(5, 23); _FL_DEFPIN(6, 27); _FL_DEFPIN(7, 28); _FL_DEFPIN(8, 32); _FL_DEFPIN(9, 12); -_FL_DEFPIN(10, 13); _FL_DEFPIN(11, 7); _FL_DEFPIN(12, 6); _FL_DEFPIN(13, 5); _FL_DEFPIN(14, 40); -_FL_DEFPIN(15, 39); _FL_DEFPIN(16, 29); _FL_DEFPIN(17, 11); _FL_DEFPIN(18, 34); _FL_DEFPIN(19, 33); -_FL_DEFPIN(20, 16); _FL_DEFPIN(21, 31); _FL_DEFPIN(22, 48); _FL_DEFPIN(23, 49); _FL_DEFPIN(24, 8); -_FL_DEFPIN(25, 9); _FL_DEFPIN(26, 10); _FL_DEFPIN(27, 38); _FL_DEFPIN(28, 42); _FL_DEFPIN(29, 43); -_FL_DEFPIN(30, 36); _FL_DEFPIN(31, 37); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_AM_AP3_SFE_BB_ARTEMIS_NANO) - -#define MAX_PIN 23 -_FL_DEFPIN(0, 13); _FL_DEFPIN(1, 33); _FL_DEFPIN(2, 11); _FL_DEFPIN(3, 29); _FL_DEFPIN(4, 18); -_FL_DEFPIN(5, 31); _FL_DEFPIN(6, 43); _FL_DEFPIN(7, 42); _FL_DEFPIN(8, 38); _FL_DEFPIN(9, 39); -_FL_DEFPIN(10, 40); _FL_DEFPIN(11, 5); _FL_DEFPIN(12, 7); _FL_DEFPIN(13, 6); _FL_DEFPIN(14, 35); -_FL_DEFPIN(15, 32); _FL_DEFPIN(16, 12); _FL_DEFPIN(17, 32); _FL_DEFPIN(18, 12); _FL_DEFPIN(19, 19); -_FL_DEFPIN(20, 48); _FL_DEFPIN(21, 49); _FL_DEFPIN(22, 36); _FL_DEFPIN(23, 37); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_AM_AP3_SFE_THING_PLUS) - -#define MAX_PIN 28 -_FL_DEFPIN(0, 25); _FL_DEFPIN(1, 24); _FL_DEFPIN(2, 44); _FL_DEFPIN(3, 35); _FL_DEFPIN(4, 4); -_FL_DEFPIN(5, 22); _FL_DEFPIN(6, 23); _FL_DEFPIN(7, 27); _FL_DEFPIN(8, 28); _FL_DEFPIN(9, 32); -_FL_DEFPIN(10, 14); _FL_DEFPIN(11, 7); _FL_DEFPIN(12, 6); _FL_DEFPIN(13, 5); _FL_DEFPIN(14, 40); -_FL_DEFPIN(15, 39); _FL_DEFPIN(16, 43); _FL_DEFPIN(17, 42); _FL_DEFPIN(18, 26); _FL_DEFPIN(19, 33); -_FL_DEFPIN(20, 13); _FL_DEFPIN(21, 11); _FL_DEFPIN(22, 29); _FL_DEFPIN(23, 12); _FL_DEFPIN(24, 31); -_FL_DEFPIN(25, 48); _FL_DEFPIN(26, 49); _FL_DEFPIN(27, 36); _FL_DEFPIN(28, 37); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_AM_AP3_SFE_BB_ARTEMIS_ATP) || defined(ARDUINO_SFE_ARTEMIS) - -#define MAX_PIN 49 -_FL_DEFPIN(0, 0); _FL_DEFPIN(1, 1); _FL_DEFPIN(2, 2); _FL_DEFPIN(3, 3); _FL_DEFPIN(4, 4); -_FL_DEFPIN(5, 5); _FL_DEFPIN(6, 6); _FL_DEFPIN(7, 7); _FL_DEFPIN(8, 8); _FL_DEFPIN(9, 9); -_FL_DEFPIN(10, 10); _FL_DEFPIN(11, 11); _FL_DEFPIN(12, 12); _FL_DEFPIN(13, 13); _FL_DEFPIN(14, 14); -_FL_DEFPIN(15, 15); _FL_DEFPIN(16, 16); _FL_DEFPIN(17, 17); _FL_DEFPIN(18, 18); _FL_DEFPIN(19, 19); -_FL_DEFPIN(20, 20); _FL_DEFPIN(21, 21); _FL_DEFPIN(22, 22); _FL_DEFPIN(23, 23); _FL_DEFPIN(24, 24); -_FL_DEFPIN(25, 25); _FL_DEFPIN(26, 26); _FL_DEFPIN(27, 27); _FL_DEFPIN(28, 28); _FL_DEFPIN(29, 29); -_FL_DEFPIN(31, 31); _FL_DEFPIN(32, 32); _FL_DEFPIN(33, 33); _FL_DEFPIN(34, 34); -_FL_DEFPIN(35, 35); _FL_DEFPIN(36, 36); _FL_DEFPIN(37, 37); _FL_DEFPIN(38, 38); _FL_DEFPIN(39, 39); -_FL_DEFPIN(40, 40); _FL_DEFPIN(41, 41); _FL_DEFPIN(42, 42); _FL_DEFPIN(43, 43); _FL_DEFPIN(44, 44); -_FL_DEFPIN(45, 45); _FL_DEFPIN(47, 47); _FL_DEFPIN(48, 48); _FL_DEFPIN(49, 49); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_AM_AP3_SFE_ARTEMIS_DK) - -#define MAX_PIN 49 -_FL_DEFPIN(0, 0); _FL_DEFPIN(1, 1); _FL_DEFPIN(2, 2); _FL_DEFPIN(3, 3); _FL_DEFPIN(4, 4); -_FL_DEFPIN(5, 5); _FL_DEFPIN(6, 6); _FL_DEFPIN(7, 7); _FL_DEFPIN(8, 8); _FL_DEFPIN(9, 9); -_FL_DEFPIN(10, 10); _FL_DEFPIN(11, 11); _FL_DEFPIN(12, 12); _FL_DEFPIN(13, 13); _FL_DEFPIN(14, 14); -_FL_DEFPIN(15, 15); _FL_DEFPIN(16, 16); _FL_DEFPIN(17, 17); _FL_DEFPIN(18, 18); _FL_DEFPIN(19, 19); -_FL_DEFPIN(20, 20); _FL_DEFPIN(21, 21); _FL_DEFPIN(22, 22); _FL_DEFPIN(23, 23); _FL_DEFPIN(24, 24); -_FL_DEFPIN(25, 25); _FL_DEFPIN(26, 26); _FL_DEFPIN(27, 27); _FL_DEFPIN(28, 28); _FL_DEFPIN(29, 29); -_FL_DEFPIN(31, 31); _FL_DEFPIN(32, 32); _FL_DEFPIN(33, 33); _FL_DEFPIN(34, 34); -_FL_DEFPIN(35, 35); _FL_DEFPIN(36, 36); _FL_DEFPIN(37, 37); _FL_DEFPIN(38, 38); _FL_DEFPIN(39, 39); -_FL_DEFPIN(40, 40); _FL_DEFPIN(41, 41); _FL_DEFPIN(42, 42); _FL_DEFPIN(43, 43); _FL_DEFPIN(44, 44); -_FL_DEFPIN(45, 45); _FL_DEFPIN(47, 47); _FL_DEFPIN(48, 48); _FL_DEFPIN(49, 49); -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#else - -#error "Unrecognised APOLLO3 board!" - -#endif - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - -#endif // __INC_FASTPIN_AVR_H diff --git a/FastLED/src/platforms/apollo3/fastspi_apollo3.h b/FastLED/src/platforms/apollo3/fastspi_apollo3.h deleted file mode 100644 index 0c77d319786861d9435ea6986cb3d6ea9c6a97d8..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/apollo3/fastspi_apollo3.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef __INC_FASTSPI_APOLLO3_H -#define __INC_FASTSPI_APOLLO3_H - -// This is the implementation of fastspi for the Apollo3. -// It uses fastgpio instead of actual SPI, which means you can use it on all pins. -// It can run slightly faster than the default fastpin (bit banging). - -#include "FastLED.h" - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_APOLLO3) - -#define FASTLED_ALL_PINS_HARDWARE_SPI - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class APOLLO3HardwareSPIOutput { - Selectable *m_pSelect; - -public: - APOLLO3HardwareSPIOutput() { m_pSelect = NULL; } - APOLLO3HardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - - // set the object representing the selectable - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - // initialize the pins for fastgpio - void init() { - FastPin<_CLOCK_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::lo(); - FastPin<_DATA_PIN>::setOutput(); - FastPin<_DATA_PIN>::lo(); - } - - // latch the CS select - void inline select() { /* TODO */ } - - // release the CS select - void inline release() { /* TODO */ } - - // wait until all queued up data has been written - static void waitFully() { /* TODO */ } - - // write a byte as bits - static void writeByte(uint8_t b) { - writeBit<7>(b); - writeBit<6>(b); - writeBit<5>(b); - writeBit<4>(b); - writeBit<3>(b); - writeBit<2>(b); - writeBit<1>(b); - writeBit<0>(b); - } - - // write a word out via SPI (returns immediately on writing register) - static void writeWord(uint16_t w) { - writeByte((uint8_t)((w >> 8) & 0xff)); - writeByte((uint8_t)(w & 0xff)); - } - - // A raw set of writing byte values, assumes setup/init/waiting done elsewhere - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { writeByte(value); } - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytesValue(uint8_t value, int len) { - select(); - writeBytesValueRaw(value, len); - release(); - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - template <class D> void writeBytes(register uint8_t *data, int len) { - uint8_t *end = data + len; - select(); - // could be optimized to write 16bit words out instead of 8bit bytes - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a single bit out, which bit from the passed in byte is determined by template parameter - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - //waitFully(); - if(b & (1 << BIT)) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - - FastPin<_CLOCK_PIN>::hi(); - for (uint32_t d = (_SPI_CLOCK_DIVIDER >> 1); d > 0; d--) { __NOP(); } - FastPin<_CLOCK_PIN>::lo(); - for (uint32_t d = (_SPI_CLOCK_DIVIDER >> 1); d > 0; d--) { __NOP(); } - } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - - int len = pixels.mLen; - - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - } - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - //waitFully(); - release(); - } - -}; - -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/apollo3/led_sysdefs_apollo3.h b/FastLED/src/platforms/apollo3/led_sysdefs_apollo3.h deleted file mode 100644 index be74e24de868947f4efcf24412cc724feb4d38eb..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/apollo3/led_sysdefs_apollo3.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_APOLLO3_H -#define __INC_LED_SYSDEFS_APOLLO3_H - -#define FASTLED_APOLLO3 - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -#ifndef F_CPU -#define F_CPU 48000000 -#endif - -// Default to NOT using PROGMEM -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 0 -#endif - -// data type defs -typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ -typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ - -#define FASTLED_NO_PINMAP - -// reusing/abusing cli/sei defs for due -// These should be fine for the Apollo3. It has its own defines in cmsis_gcc.h -#define cli() __disable_irq(); //__disable_fault_irq(); -#define sei() __enable_irq(); //__enable_fault_irq(); - -#endif diff --git a/FastLED/src/platforms/arm/common/m0clockless.h b/FastLED/src/platforms/arm/common/m0clockless.h deleted file mode 100644 index 6fd865954de2c4f957099d1b169446cebff8fdaf..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/common/m0clockless.h +++ /dev/null @@ -1,389 +0,0 @@ -#ifndef __INC_M0_CLOCKLESS_H -#define __INC_M0_CLOCKLESS_H - -struct M0ClocklessData { - uint8_t d[3]; - uint8_t e[3]; - uint8_t adj; - uint8_t pad; - uint32_t s[3]; -}; - - -template<int HI_OFFSET, int LO_OFFSET, int T1, int T2, int T3, EOrder RGB_ORDER, int WAIT_TIME>int -showLedData(volatile uint32_t *_port, uint32_t _bitmask, const uint8_t *_leds, uint32_t num_leds, struct M0ClocklessData *pData) { - // Lo register variables - register uint32_t scratch=0; - register struct M0ClocklessData *base = pData; - register volatile uint32_t *port = _port; - register uint32_t d=0; - register uint32_t counter=num_leds; - register uint32_t bn=0; - register uint32_t b=0; - register uint32_t bitmask = _bitmask; - - // high register variable - register const uint8_t *leds = _leds; -#if (FASTLED_SCALE8_FIXED == 1) - ++pData->s[0]; - ++pData->s[1]; - ++pData->s[2]; -#endif - asm __volatile__ ( - /////////////////////////////////////////////////////////////////////////// - // - // asm macro definitions - used to assemble the clockless output - // - ".ifnotdef fl_delay_def;" -#ifdef FASTLED_ARM_M0_PLUS - " .set fl_is_m0p, 1;" - " .macro m0pad;" - " nop;" - " .endm;" -#else - " .set fl_is_m0p, 0;" - " .macro m0pad;" - " .endm;" -#endif - " .set fl_delay_def, 1;" - " .set fl_delay_mod, 4;" - " .if fl_is_m0p == 1;" - " .set fl_delay_mod, 3;" - " .endif;" - " .macro fl_delay dtime, reg=r0;" - " .if (\\dtime > 0);" - " .set dcycle, (\\dtime / fl_delay_mod);" - " .set dwork, (dcycle * fl_delay_mod);" - " .set drem, (\\dtime - dwork);" - " .rept (drem);" - " nop;" - " .endr;" - " .if dcycle > 0;" - " mov \\reg, #dcycle;" - " delayloop_\\@:;" - " sub \\reg, #1;" - " bne delayloop_\\@;" - " .if fl_is_m0p == 0;" - " nop;" - " .endif;" - " .endif;" - " .endif;" - " .endm;" - - " .macro mod_delay dtime,b1,b2,reg;" - " .set adj, (\\b1 + \\b2);" - " .if adj < \\dtime;" - " .set dtime2, (\\dtime - adj);" - " fl_delay dtime2, \\reg;" - " .endif;" - " .endm;" - - // check the bit and drop the line low if it isn't set - " .macro qlo4 b,bitmask,port,loff ;" - " lsl \\b, #1 ;" - " bcs skip_\\@ ;" - " str \\bitmask, [\\port, \\loff] ;" - " skip_\\@: ;" - " m0pad;" - " .endm ;" - - // set the pin hi or low (determined by the offset passed in ) - " .macro qset2 bitmask,port,loff;" - " str \\bitmask, [\\port, \\loff];" - " m0pad;" - " .endm;" - - // Load up the next led byte to work with, put it in bn - " .macro loadleds3 leds, bn, rled, scratch;" - " mov \\scratch, \\leds;" - " ldrb \\bn, [\\scratch, \\rled];" - " .endm;" - - // check whether or not we should dither - " .macro loaddither7 bn,d,base,rdither;" - " ldrb \\d, [\\base, \\rdither];" - " lsl \\d, #24;" //; shift high for the qadd w/bn - " lsl \\bn, #24;" //; shift high for the qadd w/d - " bne chkskip_\\@;" //; if bn==0, clear d;" - " eor \\d, \\d;" //; clear d;" - " m0pad;" - " chkskip_\\@:;" - " .endm;" - - // Do the qadd8 for dithering -- there's two versions of this. The m0 version - // takes advantage of the 3 cycle branch to do two things after the branch, - // while keeping timing constant. The m0+, however, branches in 2 cycles, so - // we have to work around that a bit more. This is one of the few times - // where the m0 will actually be _more_ efficient than the m0+ - " .macro dither5 bn,d;" - " .syntax unified;" - " .if fl_is_m0p == 0;" - " adds \\bn, \\d;" // do the add - " bcc dither5_1_\\@;" - " mvns \\bn, \\bn;" // set the low 24bits ot 1's - " lsls \\bn, \\bn, #24;" // move low 8 bits to the high bits - " dither5_1_\\@:;" - " nop;" // nop to keep timing in line - " .else;" - " adds \\bn, \\d;" // do the add" - " bcc dither5_2_\\@;" - " mvns \\bn, \\bn;" // set the low 24bits ot 1's - " dither5_2_\\@:;" - " bcc dither5_3_\\@;" - " lsls \\bn, \\bn, #24;" // move low 8 bits to the high bits - " dither5_3_\\@:;" - " .endif;" - " .syntax divided;" - " .endm;" - - // Do our scaling - " .macro scale4 bn, base, scale, scratch;" - " ldr \\scratch, [\\base, \\scale];" - " lsr \\bn, \\bn, #24;" // bring bn back down to its low 8 bits - " mul \\bn, \\scratch;" // do the multiply - " .endm;" - - // swap bn into b - " .macro swapbbn1 b,bn;" - " lsl \\b, \\bn, #16;" // put the 8 bits we want for output high - " .endm;" - - // adjust the dithering value for the next time around (load e from memory - // to do the math) - " .macro adjdither7 base,d,rled,eoffset,scratch;" - " ldrb \\d, [\\base, \\rled];" - " ldrb \\scratch,[\\base,\\eoffset];" // load e - " .syntax unified;" - " subs \\d, \\scratch, \\d;" // d=e-d - " .syntax divided;" - " strb \\d, [\\base, \\rled];" // save d - " .endm;" - - // increment the led pointer (base+6 has what we're incrementing by) - " .macro incleds3 leds, base, scratch;" - " ldrb \\scratch, [\\base, #6];" // load incremen - " add \\leds, \\leds, \\scratch;" // update leds pointer - " .endm;" - - // compare and loop - " .macro cmploop5 counter,label;" - " .syntax unified;" - " subs \\counter, #1;" - " .syntax divided;" - " beq done_\\@;" - " m0pad;" - " b \\label;" - " done_\\@:;" - " .endm;" - - " .endif;" - ); - -#define M0_ASM_ARGS : \ - [leds] "+h" (leds), \ - [counter] "+l" (counter), \ - [scratch] "+l" (scratch), \ - [d] "+l" (d), \ - [bn] "+l" (bn), \ - [b] "+l" (b) \ - : \ - [port] "l" (port), \ - [base] "l" (base), \ - [bitmask] "l" (bitmask), \ - [hi_off] "I" (HI_OFFSET), \ - [lo_off] "I" (LO_OFFSET), \ - [led0] "I" (RO(0)), \ - [led1] "I" (RO(1)), \ - [led2] "I" (RO(2)), \ - [e0] "I" (3+RO(0)), \ - [e1] "I" (3+RO(1)), \ - [e2] "I" (3+RO(2)), \ - [scale0] "I" (4*(2+RO(0))), \ - [scale1] "I" (4*(2+RO(1))), \ - [scale2] "I" (4*(2+RO(2))), \ - [T1] "I" (T1), \ - [T2] "I" (T2), \ - [T3] "I" (T3) \ - : - - ///////////////////////////////////////////////////////////////////////// - // now for some convinience macros to make building our lines a bit cleaner -#define LOOP " loop_%=:" -#define HI2 " qset2 %[bitmask], %[port], %[hi_off];" -#define _D1 " mod_delay %c[T1],2,0,%[scratch];" -#define QLO4 " qlo4 %[b],%[bitmask],%[port], %[lo_off];" -#define LOADLEDS3(X) " loadleds3 %[leds], %[bn], %[led" #X "] ,%[scratch];" -#define _D2(ADJ) " mod_delay %c[T2],4," #ADJ ",%[scratch];" -#define LO2 " qset2 %[bitmask], %[port], %[lo_off];" -#define _D3(ADJ) " mod_delay %c[T3],2," #ADJ ",%[scratch];" -#define LOADDITHER7(X) " loaddither7 %[bn], %[d], %[base], %[led" #X "];" -#define DITHER5 " dither5 %[bn], %[d];" -#define SCALE4(X) " scale4 %[bn], %[base], %[scale" #X "], %[scratch];" -#define SWAPBBN1 " swapbbn1 %[b], %[bn];" -#define ADJDITHER7(X) " adjdither7 %[base],%[d],%[led" #X "],%[e" #X "],%[scratch];" -#define INCLEDS3 " incleds3 %[leds],%[base],%[scratch];" -#define CMPLOOP5 " cmploop5 %[counter], loop_%=;" -#define NOTHING "" - -#if (defined(SEI_CHK) && (FASTLED_ALLOW_INTERRUPTS == 1)) - // We're allowing interrupts and have hardware timer support defined - - // track the loop outside the asm code, to allow inserting the interrupt - // overrun checks. - asm __volatile__ ( - // pre-load byte 0 - LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1 - M0_ASM_ARGS); - - do { - asm __volatile__ ( - // Write out byte 0, prepping byte 1 - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0) - - // Write out byte 1, prepping byte 2 - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0) - - // Write out byte 2, prepping byte 0 - HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5) - - M0_ASM_ARGS - ); - SEI_CHK; INNER_SEI; --counter; CLI_CHK; - } while(counter); -#elif (FASTLED_ALLOW_INTERRUPTS == 1) - // We're allowing interrupts - track the loop outside the asm code, and - // re-enable interrupts in between each iteration. - asm __volatile__ ( - // pre-load byte 0 - LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1 - M0_ASM_ARGS); - - do { - asm __volatile__ ( - // Write out byte 0, prepping byte 1 - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0) - - // Write out byte 1, prepping byte 2 - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0) - - // Write out byte 2, prepping byte 0 - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5) - - M0_ASM_ARGS - ); - - uint32_t ticksBeforeInterrupts = SysTick->VAL; - sei(); - --counter; - cli(); - - // If more than 45 uSecs have elapsed, give up on this frame and start over. - // Note: this isn't completely correct. It's possible that more than one - // millisecond will elapse, and so SysTick->VAL will lap - // ticksBeforeInterrupts. - // Note: ticksBeforeInterrupts DECREASES - const uint32_t kTicksPerMs = VARIANT_MCK / 1000; - const uint32_t kTicksPerUs = kTicksPerMs / 1000; - const uint32_t kTicksIn45us = kTicksPerUs * 45; - - const uint32_t currentTicks = SysTick->VAL; - - if (ticksBeforeInterrupts < currentTicks) { - // Timer started over - if ((ticksBeforeInterrupts + (kTicksPerMs - currentTicks)) > kTicksIn45us) { - return 0; - } - } else { - if ((ticksBeforeInterrupts - currentTicks) > kTicksIn45us) { - return 0; - } - } - } while(counter); -#else - // We're not allowing interrupts - run the entire loop in asm to keep things - // as tight as possible. In an ideal world, we should be pushing out ws281x - // leds (or other 3-wire leds) with zero gaps between pixels. - asm __volatile__ ( - // pre-load byte 0 - LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1 - - // loop over writing out the data - LOOP - // Write out byte 0, prepping byte 1 - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0) - - // Write out byte 1, prepping byte 2 - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0) - - // Write out byte 2, prepping byte 0 - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0) - HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0) - HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0) - HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0) - HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0) - HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5) CMPLOOP5 - - M0_ASM_ARGS - ); -#endif - return num_leds; -} - -#endif diff --git a/FastLED/src/platforms/arm/d21/clockless_arm_d21.h b/FastLED/src/platforms/arm/d21/clockless_arm_d21.h deleted file mode 100644 index 16526ed67490a9ee63e194f9d1d9f873f5951592..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d21/clockless_arm_d21.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_D21 -#define __INC_CLOCKLESS_ARM_D21 - -#include "../common/m0clockless.h" -FASTLED_NAMESPACE_BEGIN -#define FASTLED_HAS_CLOCKLESS 1 - -template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPinBB<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - FastPinBB<DATA_PIN>::setOutput(); - mPinMask = FastPinBB<DATA_PIN>::mask(); - mPort = FastPinBB<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - cli(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - sei(); - mWait.mark(); - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - struct M0ClocklessData data; - data.d[0] = pixels.d[0]; - data.d[1] = pixels.d[1]; - data.d[2] = pixels.d[2]; - data.s[0] = pixels.mScale[0]; - data.s[1] = pixels.mScale[1]; - data.s[2] = pixels.mScale[2]; - data.e[0] = pixels.e[0]; - data.e[1] = pixels.e[1]; - data.e[2] = pixels.e[2]; - data.adj = pixels.mAdvance; - - typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port(); - return showLedData<8,4,T1,T2,T3,RGB_ORDER, WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data); - } - -}; - -FASTLED_NAMESPACE_END - - -#endif // __INC_CLOCKLESS_ARM_D21 diff --git a/FastLED/src/platforms/arm/d21/fastled_arm_d21.h b/FastLED/src/platforms/arm/d21/fastled_arm_d21.h deleted file mode 100644 index 98412749a0e823890254d18134edbd3dc0314cd2..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d21/fastled_arm_d21.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __INC_FASTLED_ARM_D21_H -#define __INC_FASTLED_ARM_D21_H - -#include "fastpin_arm_d21.h" -#include "clockless_arm_d21.h" - -#endif diff --git a/FastLED/src/platforms/arm/d21/fastpin_arm_d21.h b/FastLED/src/platforms/arm/d21/fastpin_arm_d21.h deleted file mode 100644 index 93dc43c6579081b0f1b7364b49224fb8d282d0f4..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d21/fastpin_arm_d21.h +++ /dev/null @@ -1,274 +0,0 @@ -#ifndef __INC_FASTPIN_ARM_SAM_H -#define __INC_FASTPIN_ARM_SAM_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be slightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - -/// Template definition for STM32 style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found -/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. -/// The registers are data output, set output, clear output, toggle output, input, and direction - -template<uint8_t PIN, uint8_t _BIT, uint32_t _MASK, int _GRP> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - #if 0 - inline static void setOutput() { - if(_BIT<8) { - _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4)); - } else { - _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4)); - } - } - inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - #endif - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTSET.reg = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTCLR.reg = _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUT.reg = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTTGL.reg = _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return PORT_IOBUS->Group[_GRP].OUT.reg | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return PORT_IOBUS->Group[_GRP].OUT.reg & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUT.reg; } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUTSET.reg; } - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUTCLR.reg; } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile PortGroup * r() { return T; } }; - -#define _FL_IO(L) _RD32(GPIO ## L) - -#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, L> {}; - -// Actual pin definitions -#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) - -#define MAX_PIN 17 -_FL_DEFPIN( 8,23,1); -_FL_DEFPIN( 0, 9,1); _FL_DEFPIN( 1, 8,1); _FL_DEFPIN( 2, 2,1); _FL_DEFPIN( 3, 3,1); -_FL_DEFPIN( 6, 5,0); _FL_DEFPIN( 9, 6,0); _FL_DEFPIN(10, 7,0); _FL_DEFPIN(12, 2,0); -_FL_DEFPIN(A6, 9,1); _FL_DEFPIN(A7, 8,1); _FL_DEFPIN(A5, 2,1); _FL_DEFPIN(A4, 3,1); -_FL_DEFPIN(A1, 5,0); _FL_DEFPIN(A2, 6,0); _FL_DEFPIN(A3, 7,0); _FL_DEFPIN(A0, 2,0); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - - -#elif defined(ADAFRUIT_HALLOWING) - -#define MAX_PIN 20 -// 0 & 1 -_FL_DEFPIN( 0, 9, 0); _FL_DEFPIN( 1, 10, 0); -// 2, 3, 4 -_FL_DEFPIN( 2, 14, 0); _FL_DEFPIN( 3, 11, 0); _FL_DEFPIN( 4, 8, 0); -// 5, 6, 7 -_FL_DEFPIN( 5, 15, 0); _FL_DEFPIN( 6, 18, 0); _FL_DEFPIN( 7, 0, 0); -// 8, 9, 10 -_FL_DEFPIN( 8, 12, 0); _FL_DEFPIN( 9, 19, 0); _FL_DEFPIN(10, 20, 0); -// 11, 12, 13 -_FL_DEFPIN(11, 21, 0); _FL_DEFPIN(12, 22, 0); _FL_DEFPIN(13, 23, 0); -// 14, 15, 16 (A0 - A2) -_FL_DEFPIN(14, 2, 0); _FL_DEFPIN(15, 8, 1); _FL_DEFPIN(16, 9, 1); -// 17, 18, 19 (A3 - A5) -_FL_DEFPIN(17, 4, 0); _FL_DEFPIN(18, 5, 0); _FL_DEFPIN(19, 6, 0); - -#define SPI_DATA PIN_SPI_MOSI -#define SPI_CLOCK PIN_SPI_SCK - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(SEEED_XIAO_M0) - -#define MAX_PIN 10 -_FL_DEFPIN( 0, 2,0); _FL_DEFPIN( 1, 4,0); _FL_DEFPIN( 2,10,0); _FL_DEFPIN( 3,11,0); -_FL_DEFPIN( 4, 8,0); _FL_DEFPIN( 5, 9,0); _FL_DEFPIN( 6, 8,1); _FL_DEFPIN( 7, 9,1); -_FL_DEFPIN( 8, 7,0); _FL_DEFPIN( 9, 5,0); _FL_DEFPIN(10, 6,0); - -#define SPI_DATA 9 -#define SPI_CLOCK 8 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_SEEED_ZERO) - -#define MAX_PIN 24 - -_FL_DEFPIN( 0,11,0); _FL_DEFPIN( 1,10,0); _FL_DEFPIN( 2,14,0); _FL_DEFPIN( 3,9,0); -_FL_DEFPIN( 4,8,0); _FL_DEFPIN( 5,15,0); _FL_DEFPIN( 6,20,0); _FL_DEFPIN( 7,21,0); -_FL_DEFPIN( 8,6,0); _FL_DEFPIN( 9,7,0); _FL_DEFPIN( 10,18,0); _FL_DEFPIN( 11,16,0); -_FL_DEFPIN( 12,19,0); _FL_DEFPIN( 13,17,0); _FL_DEFPIN( 14,2,0); _FL_DEFPIN( 15,8,1); -_FL_DEFPIN( 16,9,1); _FL_DEFPIN( 17,4,0); _FL_DEFPIN( 18,5,0); _FL_DEFPIN( 19,2,1); -_FL_DEFPIN( 20,22,0); _FL_DEFPIN( 21,23,0); _FL_DEFPIN( 22,12,0); -_FL_DEFPIN( 23,10,1);//MOSI -_FL_DEFPIN( 24,11,1);//SCK - -#define SPI_DATA 23 -#define SPI_CLOCK 24 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_SAMD_ZERO) - -#define MAX_PIN 42 -_FL_DEFPIN( 0,10,0); _FL_DEFPIN( 1,11,0); _FL_DEFPIN( 2, 8,0); _FL_DEFPIN( 3, 9,0); -_FL_DEFPIN( 4,14,0); _FL_DEFPIN( 5,15,0); _FL_DEFPIN( 6,20,0); _FL_DEFPIN( 7,21,0); -_FL_DEFPIN( 8, 6,0); _FL_DEFPIN( 9, 7,0); _FL_DEFPIN(10,18,0); _FL_DEFPIN(11,16,0); -_FL_DEFPIN(12,19,0); _FL_DEFPIN(13,17,0); _FL_DEFPIN(14, 2,0); _FL_DEFPIN(15, 8,1); -_FL_DEFPIN(16, 9,1); _FL_DEFPIN(17, 4,0); _FL_DEFPIN(18, 5,0); _FL_DEFPIN(19, 2,1); -_FL_DEFPIN(20,22,0); _FL_DEFPIN(21,23,0); _FL_DEFPIN(22,12,0); _FL_DEFPIN(23,11,1); -_FL_DEFPIN(24,10,1); _FL_DEFPIN(25, 3,1); _FL_DEFPIN(26,27,0); _FL_DEFPIN(27,28,0); -_FL_DEFPIN(28,24,0); _FL_DEFPIN(29,25,0); _FL_DEFPIN(30,22,1); _FL_DEFPIN(31,23,1); -_FL_DEFPIN(32,22,0); _FL_DEFPIN(33,23,0); _FL_DEFPIN(34,19,0); _FL_DEFPIN(35,16,0); -_FL_DEFPIN(36,18,0); _FL_DEFPIN(37,17,0); _FL_DEFPIN(38,13,0); _FL_DEFPIN(39,21,0); -_FL_DEFPIN(40, 6,0); _FL_DEFPIN(41, 7,0); _FL_DEFPIN(42, 3,0); - -#define SPI_DATA 24 -#define SPI_CLOCK 23 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_SODAQ_AUTONOMO) - -#define MAX_PIN 56 -_FL_DEFPIN( 0, 9,0); _FL_DEFPIN( 1,10,0); _FL_DEFPIN( 2,11,0); _FL_DEFPIN( 3,10,1); -_FL_DEFPIN( 4,11,1); _FL_DEFPIN( 5,12,1); _FL_DEFPIN( 6,13,1); _FL_DEFPIN( 7,14,1); -_FL_DEFPIN( 8,15,1); _FL_DEFPIN( 9,14,0); _FL_DEFPIN(10,15,0); _FL_DEFPIN(11,16,0); -_FL_DEFPIN(12,17,0); _FL_DEFPIN(13,18,0); _FL_DEFPIN(14,19,0); _FL_DEFPIN(15,16,1); -_FL_DEFPIN(16, 8,0); _FL_DEFPIN(17,28,0); _FL_DEFPIN(18,17,1); _FL_DEFPIN(19, 2,0); -_FL_DEFPIN(20, 6,0); _FL_DEFPIN(21, 5,0); _FL_DEFPIN(22, 4,0); _FL_DEFPIN(23, 9,1); -_FL_DEFPIN(24, 8,1); _FL_DEFPIN(25, 7,1); _FL_DEFPIN(26, 6,1); _FL_DEFPIN(27, 5,1); -_FL_DEFPIN(28, 4,1); _FL_DEFPIN(29, 7,0); _FL_DEFPIN(30, 3,1); _FL_DEFPIN(31, 2,1); -_FL_DEFPIN(32, 1,1); _FL_DEFPIN(33, 0,1); _FL_DEFPIN(34, 3,0); _FL_DEFPIN(35, 3,0); -_FL_DEFPIN(36,30,1); _FL_DEFPIN(37,31,1); _FL_DEFPIN(38,22,1); _FL_DEFPIN(39,23,1); -_FL_DEFPIN(40,12,0); _FL_DEFPIN(41,13,0); _FL_DEFPIN(42,22,0); _FL_DEFPIN(43,23,0); -_FL_DEFPIN(44,20,0); _FL_DEFPIN(45,21,0); _FL_DEFPIN(46,27,0); _FL_DEFPIN(47,24,0); -_FL_DEFPIN(48,25,0); _FL_DEFPIN(49,13,1); _FL_DEFPIN(50,14,1); _FL_DEFPIN(51,17,0); -_FL_DEFPIN(52,18,0); _FL_DEFPIN(53,12,1); _FL_DEFPIN(54,13,1); _FL_DEFPIN(55,14,1); -_FL_DEFPIN(56,15,1); - -#define SPI_DATA 44 -#define SPI_CLOCK 45 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_SAMD_WINO) - -#define MAX_PIN 22 -_FL_DEFPIN( 0, 23, 0); _FL_DEFPIN( 1, 22, 0); _FL_DEFPIN( 2, 16, 0); _FL_DEFPIN( 3, 17, 0); -_FL_DEFPIN( 4, 18, 0); _FL_DEFPIN( 5, 19, 0); _FL_DEFPIN( 6, 24, 0); _FL_DEFPIN( 7, 25, 0); -_FL_DEFPIN( 8, 27, 0); _FL_DEFPIN( 9, 28, 0); _FL_DEFPIN( 10, 30, 0); _FL_DEFPIN( 11, 31, 0); -_FL_DEFPIN( 12, 15, 0); _FL_DEFPIN( 13, 14, 0); _FL_DEFPIN( 14, 2, 0); _FL_DEFPIN( 15, 3, 0); -_FL_DEFPIN( 16, 4, 0); _FL_DEFPIN( 17, 5, 0); _FL_DEFPIN( 18, 6, 0); _FL_DEFPIN( 19, 7, 0); -_FL_DEFPIN( 20, 8, 0); _FL_DEFPIN( 21, 9, 0); _FL_DEFPIN( 22, 10, 0); _FL_DEFPIN( 23, 11, 0); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) - -#define MAX_PIN 22 -_FL_DEFPIN( 0, 22, 0); _FL_DEFPIN( 1, 23, 0); _FL_DEFPIN( 2, 10, 0); _FL_DEFPIN( 3, 11, 0); -_FL_DEFPIN( 4, 10, 1); _FL_DEFPIN( 5, 11, 1); _FL_DEFPIN( 6, 20, 0); _FL_DEFPIN( 7, 21, 0); -_FL_DEFPIN( 8, 16, 0); _FL_DEFPIN( 9, 17, 0); _FL_DEFPIN( 10, 19, 0); _FL_DEFPIN( 11, 8, 0); -_FL_DEFPIN( 12, 9, 0); _FL_DEFPIN( 13, 23, 1); _FL_DEFPIN( 14, 22, 1); _FL_DEFPIN( 15, 2, 0); -_FL_DEFPIN( 16, 2, 1); _FL_DEFPIN( 17, 3, 1); _FL_DEFPIN( 18, 4, 0); _FL_DEFPIN( 19, 5, 0); -_FL_DEFPIN( 20, 6, 0); _FL_DEFPIN( 21, 7, 0); - -#define SPI_DATA 8 -#define SPI_CLOCK 9 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_SAMD_NANO_33_IOT) - -#define MAX_PIN 26 -_FL_DEFPIN( 0, 23, 1); _FL_DEFPIN( 1, 22, 1); _FL_DEFPIN( 2, 10, 1); _FL_DEFPIN( 3, 11, 1); -_FL_DEFPIN( 4, 7, 0); _FL_DEFPIN( 5, 5, 0); _FL_DEFPIN( 6, 4, 0); _FL_DEFPIN( 7, 6, 0); -_FL_DEFPIN( 8, 18, 0); _FL_DEFPIN( 9, 20, 0); _FL_DEFPIN( 10, 21, 0); _FL_DEFPIN( 11, 16, 0); -_FL_DEFPIN( 12, 19, 0); _FL_DEFPIN( 13, 17, 0); _FL_DEFPIN( 14, 2, 0); _FL_DEFPIN( 15, 2, 1); -_FL_DEFPIN( 16, 11, 1); _FL_DEFPIN( 17, 10, 0); _FL_DEFPIN( 18, 8, 1); _FL_DEFPIN( 19, 9, 1); -_FL_DEFPIN( 20, 9, 0); _FL_DEFPIN( 21, 3, 1); _FL_DEFPIN( 22, 12, 0); _FL_DEFPIN( 23, 13, 0); -_FL_DEFPIN( 24, 14, 0); _FL_DEFPIN( 25, 15, 0); - -#define SPI_DATA 22 -#define SPI_CLOCK 25 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_GEMMA_M0) - -#define MAX_PIN 4 -_FL_DEFPIN( 0, 4, 0); _FL_DEFPIN( 1, 2, 0); _FL_DEFPIN( 2, 5, 0); -_FL_DEFPIN( 3, 0, 0); _FL_DEFPIN( 4, 1, 0); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ADAFRUIT_TRINKET_M0) - -#define MAX_PIN 7 -_FL_DEFPIN( 0, 8, 0); _FL_DEFPIN( 1, 2, 0); _FL_DEFPIN( 2, 9, 0); -_FL_DEFPIN( 3, 7, 0); _FL_DEFPIN( 4, 6, 0); _FL_DEFPIN( 7, 0, 0); _FL_DEFPIN( 8, 1, 0); - -#define SPI_DATA 4 -#define SPI_CLOCK 3 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ADAFRUIT_QTPY_M0) - -#define MAX_PIN 10 -_FL_DEFPIN( 0, 2, 0); _FL_DEFPIN( 1, 3, 0); _FL_DEFPIN( 2, 4, 0); _FL_DEFPIN( 3, 5, 0); -_FL_DEFPIN( 4, 16, 0); _FL_DEFPIN( 5, 17, 0); _FL_DEFPIN( 6, 6, 0); _FL_DEFPIN( 7, 7, 0); -_FL_DEFPIN( 8, 11, 0); _FL_DEFPIN( 9, 9, 0); _FL_DEFPIN( 10, 10, 0); - -#define SPI_DATA 10 -#define SPI_CLOCK 8 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - - -#elif defined(ADAFRUIT_ITSYBITSY_M0) - -#define MAX_PIN 16 -_FL_DEFPIN( 2, 14, 0); _FL_DEFPIN( 3, 9, 0); _FL_DEFPIN( 4, 8, 0); -_FL_DEFPIN( 5, 15, 0); _FL_DEFPIN( 6, 20, 0); _FL_DEFPIN( 7, 21, 0); -_FL_DEFPIN( 8, 6, 0); _FL_DEFPIN( 9, 7, 0); _FL_DEFPIN( 10, 18, 0); -_FL_DEFPIN( 11, 16, 0); _FL_DEFPIN( 12, 19, 0); _FL_DEFPIN( 13, 17, 0); -_FL_DEFPIN( 29, 10, 0); // MOSI -_FL_DEFPIN( 30, 11, 0); // SCK -_FL_DEFPIN( 40, 0, 0); //APA102 Clock -_FL_DEFPIN( 41, 0, 1) //APA102 Data - -#define SPI_DATA 29 -#define SPI_CLOCK 30 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#endif - - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - - -#endif // __INC_FASTPIN_ARM_SAM_H diff --git a/FastLED/src/platforms/arm/d21/led_sysdefs_arm_d21.h b/FastLED/src/platforms/arm/d21/led_sysdefs_arm_d21.h deleted file mode 100644 index a48db10abf48badd9c2299a6dc978549e16ccec0..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d21/led_sysdefs_arm_d21.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_ARM_D21_H -#define __INC_LED_SYSDEFS_ARM_D21_H - - -#define FASTLED_ARM -#define FASTLED_ARM_M0_PLUS - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -// reusing/abusing cli/sei defs for due -#define cli() __disable_irq(); -#define sei() __enable_irq(); - - -#endif diff --git a/FastLED/src/platforms/arm/d51/README.txt b/FastLED/src/platforms/arm/d51/README.txt deleted file mode 100644 index b00fb670af212adc72e07b51b41c65b1d16ee2de..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d51/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -FastLED updates for adafruit FEATHER M4 and fixes to ITSBITSY M4 compiles - SAMD51 - -only tested on FEATHER M4 with DOTSTAR and neopixel strips diff --git a/FastLED/src/platforms/arm/d51/clockless_arm_d51.h b/FastLED/src/platforms/arm/d51/clockless_arm_d51.h deleted file mode 100644 index 2bf00d27283fc5006e6bde64868afa20ed9e6618..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d51/clockless_arm_d51.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_D51 -#define __INC_CLOCKLESS_ARM_D51 - -FASTLED_NAMESPACE_BEGIN - -// Definition for a single channel clockless controller for SAMD51 -// See clockless.h for detailed info on how the template parameters are used. -#define ARM_DEMCR (*(volatile uint32_t *)0xE000EDFC) // Debug Exception and Monitor Control -#define ARM_DEMCR_TRCENA (1 << 24) // Enable debugging & monitoring blocks -#define ARM_DWT_CTRL (*(volatile uint32_t *)0xE0001000) // DWT control register -#define ARM_DWT_CTRL_CYCCNTENA (1 << 0) // Enable cycle count -#define ARM_DWT_CYCCNT (*(volatile uint32_t *)0xE0001004) // Cycle count register - - -#define FASTLED_HAS_CLOCKLESS 1 - -template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - FastPin<DATA_PIN>::setOutput(); - mPinMask = FastPin<DATA_PIN>::mask(); - mPort = FastPin<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - mWait.mark(); - } - - template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) { - for(register uint32_t i = BITS-1; i > 0; --i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - FastPin<DATA_PIN>::fastset(port, hi); - if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } else { - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } - b <<= 1; - } - - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - FastPin<DATA_PIN>::fastset(port, hi); - - if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } else { - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - // Get access to the clock - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - ARM_DWT_CYCCNT = 0; - - register data_ptr_t port = FastPin<DATA_PIN>::port(); - register data_t hi = *port | FastPin<DATA_PIN>::mask(); - register data_t lo = *port & ~FastPin<DATA_PIN>::mask(); - *port = lo; - - // Setup the pixel controller and load/scale the first byte - pixels.preStepFirstByteDithering(); - register uint8_t b = pixels.loadAndScale0(); - - cli(); - uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - - while(pixels.has(1)) { - pixels.stepDithering(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; } - } - - hi = *port | FastPin<DATA_PIN>::mask(); - lo = *port & ~FastPin<DATA_PIN>::mask(); - #endif - // Write first byte, read next byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale1(); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale2(); - - // Write third byte, read 1st byte of next pixel - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.advanceAndLoadAndScale0(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - - sei(); - return ARM_DWT_CYCCNT; - } -}; - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/d51/fastled_arm_d51.h b/FastLED/src/platforms/arm/d51/fastled_arm_d51.h deleted file mode 100644 index 0c14bf2f9daa17a319e9f2168de49c47533a5d43..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d51/fastled_arm_d51.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __INC_FASTLED_ARM_D51_H -#define __INC_FASTLED_ARM_D51_H - -#include "fastpin_arm_d51.h" -#include "clockless_arm_d51.h" - -#endif diff --git a/FastLED/src/platforms/arm/d51/fastpin_arm_d51.h b/FastLED/src/platforms/arm/d51/fastpin_arm_d51.h deleted file mode 100644 index 9d31cedb4b876c233c8250c1ac183e7daca6edce..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d51/fastpin_arm_d51.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef __INC_FASTPIN_ARM_D51_H -#define __INC_FASTPIN_ARM_D51_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be slightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - -/// Template definition for STM32 style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found -/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. -/// The registers are data output, set output, clear output, toggle output, input, and direction - -template<uint8_t PIN, uint8_t _BIT, uint32_t _MASK, int _GRP> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - #if 0 - inline static void setOutput() { - if(_BIT<8) { - _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4)); - } else { - _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4)); - } - } - inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - #endif - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTSET.reg = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTCLR.reg = _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { PORT->Group[_GRP].OUT.reg = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTTGL.reg = _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUT.reg; } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTSET.reg; } - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTCLR.reg; } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile PortGroup * r() { return T; } }; - -#define _FL_IO(L) _RD32(GPIO ## L) - -#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, L> {}; - -// Actual pin definitions -#if defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS) - -#define MAX_PIN 19 -// D0-D13, including D6+D8 (DotStar CLK + DATA) -_FL_DEFPIN( 0, 16, 0); _FL_DEFPIN( 1, 17, 0); _FL_DEFPIN( 2, 7, 0); _FL_DEFPIN( 3, 22, 1); -_FL_DEFPIN( 4, 14, 0); _FL_DEFPIN( 5, 15, 0); _FL_DEFPIN( 6, 2, 1); _FL_DEFPIN( 7, 18, 0); -_FL_DEFPIN( 8, 3, 1); _FL_DEFPIN( 9, 19, 0); _FL_DEFPIN(10, 20, 0); _FL_DEFPIN(11, 21, 0); -_FL_DEFPIN(12, 23, 0); _FL_DEFPIN(13, 22, 0); -// A0-A5 -_FL_DEFPIN(14, 2, 0); _FL_DEFPIN(15, 5, 0); _FL_DEFPIN(16, 8, 1); _FL_DEFPIN(17, 9, 1); -_FL_DEFPIN(18, 4, 0); _FL_DEFPIN(19, 6, 0); /* A6 is present in variant.h but couldn't find it on the schematic */ -// SDA/SCL -_FL_DEFPIN(21, 12, 0); _FL_DEFPIN(22, 13, 0); - -// 23..25 MISO/SCK/MOSI -_FL_DEFPIN(23, 23, 1); _FL_DEFPIN(24, 1, 0); _FL_DEFPIN(25, 0, 0); - -#define SPI_DATA 25 -#define SPI_CLOCK 24 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -// Actual pin definitions -#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) - -#define MAX_PIN 20 -// D0-D13, including D6+D8 (DotStar CLK + DATA) -_FL_DEFPIN( 0, 23, 0); _FL_DEFPIN( 1, 22, 0); _FL_DEFPIN( 2, 17, 1); _FL_DEFPIN( 3, 16, 1); -_FL_DEFPIN( 4, 13, 1); _FL_DEFPIN( 5, 14, 1); _FL_DEFPIN( 6, 15, 1); _FL_DEFPIN( 7, 12, 1); -_FL_DEFPIN( 8, 21, 0); _FL_DEFPIN( 9, 20, 0); _FL_DEFPIN(10, 18, 0); _FL_DEFPIN(11, 19, 0); -_FL_DEFPIN(12, 17, 0); _FL_DEFPIN(13, 16, 0); -// A0-A5 -_FL_DEFPIN(14, 2, 0); _FL_DEFPIN(15, 5, 0); _FL_DEFPIN(16, 6, 0); _FL_DEFPIN(17, 0, 1); -_FL_DEFPIN(18, 8, 1); _FL_DEFPIN(19, 9, 1); -// SDA/SCL -_FL_DEFPIN(22, 2, 1); _FL_DEFPIN(23, 3, 1); - -// 23..25 MISO/SCK/MOSI -_FL_DEFPIN(24, 14, 0); _FL_DEFPIN(25, 13, 0); _FL_DEFPIN(26, 12, 0); - -#define SPI_DATA 26 -#define SPI_CLOCK 25 - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ADAFRUIT_FEATHER_M4_EXPRESS) - -#define MAX_PIN 19 -// D0-D13, including D8 (neopixel) no pins 2 3 -_FL_DEFPIN( 0, 17, 1); _FL_DEFPIN( 1, 16, 1); -_FL_DEFPIN( 4, 14, 0); _FL_DEFPIN( 5, 16, 0); _FL_DEFPIN( 6, 18, 0); -_FL_DEFPIN( 8, 3, 1); _FL_DEFPIN( 9, 19, 0); _FL_DEFPIN(10, 20, 0); _FL_DEFPIN(11, 21, 0); -_FL_DEFPIN(12, 22, 0); _FL_DEFPIN(13, 23, 0); -// A0-A5 -_FL_DEFPIN(14, 2, 0); _FL_DEFPIN(15, 5, 0); _FL_DEFPIN(16, 8, 1); _FL_DEFPIN(17, 9, 1); -_FL_DEFPIN(18, 4, 0); _FL_DEFPIN(19, 6, 0); /* A6 is present in variant.h but couldn't find it on the schematic */ -// SDA/SCL -_FL_DEFPIN(21, 12, 0); _FL_DEFPIN(22, 13, 0); -// 23..25 MISO/MOSI/SCK -_FL_DEFPIN(23, 22, 1); _FL_DEFPIN(24, 23, 1); _FL_DEFPIN(25, 17, 0); - -#define SPI_DATA 24 -#define SPI_CLOCK 25 - -#define HAS_HARDWARE_PIN_SUPPORT 1 -#endif - - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - - -#endif // __INC_FASTPIN_ARM_D51_H diff --git a/FastLED/src/platforms/arm/d51/led_sysdefs_arm_d51.h b/FastLED/src/platforms/arm/d51/led_sysdefs_arm_d51.h deleted file mode 100644 index fd6a25e2f980b19896dfa5e9d42db9d516f9c641..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/d51/led_sysdefs_arm_d51.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_ARM_D51_H -#define __INC_LED_SYSDEFS_ARM_D51_H - - -#define FASTLED_ARM -// Note this is an M4, not an M0+, but this enables the shared m0clockless.h -#define FASTLED_ARM_M0_PLUS - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 0 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -// reusing/abusing cli/sei defs for due -#define cli() __disable_irq(); -#define sei() __enable_irq(); - - -#endif diff --git a/FastLED/src/platforms/arm/k20/clockless_arm_k20.h b/FastLED/src/platforms/arm/k20/clockless_arm_k20.h deleted file mode 100644 index 0a7f7b94b7d83b5c91efcf14cf2ebfd68a5f3abf..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/clockless_arm_k20.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_K20_H -#define __INC_CLOCKLESS_ARM_K20_H - -FASTLED_NAMESPACE_BEGIN - -// Definition for a single channel clockless controller for the k20 family of chips, like that used in the teensy 3.0/3.1 -// See clockless.h for detailed info on how the template parameters are used. -#if defined(FASTLED_TEENSY3) - -#define FASTLED_HAS_CLOCKLESS 1 - -template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - FastPin<DATA_PIN>::setOutput(); - mPinMask = FastPin<DATA_PIN>::mask(); - mPort = FastPin<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - mWait.mark(); - } - - template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) { - for(register uint32_t i = BITS-1; i > 0; --i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - FastPin<DATA_PIN>::fastset(port, hi); - if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } else { - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } - b <<= 1; - } - - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - FastPin<DATA_PIN>::fastset(port, hi); - - if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } else { - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - // Get access to the clock - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - ARM_DWT_CYCCNT = 0; - - register data_ptr_t port = FastPin<DATA_PIN>::port(); - register data_t hi = *port | FastPin<DATA_PIN>::mask(); - register data_t lo = *port & ~FastPin<DATA_PIN>::mask(); - *port = lo; - - // Setup the pixel controller and load/scale the first byte - pixels.preStepFirstByteDithering(); - register uint8_t b = pixels.loadAndScale0(); - - cli(); - uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - - while(pixels.has(1)) { - pixels.stepDithering(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; } - } - - hi = *port | FastPin<DATA_PIN>::mask(); - lo = *port & ~FastPin<DATA_PIN>::mask(); - #endif - // Write first byte, read next byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale1(); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale2(); - - // Write third byte, read 1st byte of next pixel - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.advanceAndLoadAndScale0(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - - sei(); - return ARM_DWT_CYCCNT; - } -}; -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/k20/clockless_block_arm_k20.h b/FastLED/src/platforms/arm/k20/clockless_block_arm_k20.h deleted file mode 100644 index 9beeb9fa9f3e9f163270c613bdcf4a934ecec00c..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/clockless_block_arm_k20.h +++ /dev/null @@ -1,332 +0,0 @@ -#ifndef __INC_BLOCK_CLOCKLESS_ARM_K20_H -#define __INC_BLOCK_CLOCKLESS_ARM_K20_H - -// Definition for a single channel clockless controller for the k20 family of chips, like that used in the teensy 3.0/3.1 -// See clockless.h for detailed info on how the template parameters are used. -#if defined(FASTLED_TEENSY3) -#define FASTLED_HAS_BLOCKLESS 1 - -#define PORTC_FIRST_PIN 15 -#define PORTD_FIRST_PIN 2 -#define HAS_PORTDC 1 - -#define PORT_MASK (((1<<LANES)-1) & ((FIRST_PIN==2) ? 0xFF : 0xFFF)) - -#define MIN(X,Y) (((X)<(Y)) ? (X):(Y)) -#define USED_LANES ((FIRST_PIN==2) ? MIN(LANES,8) : MIN(LANES,12)) - -#include <kinetis.h> - -FASTLED_NAMESPACE_BEGIN - -template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 40> -class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PORT_MASK> { - typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<FIRST_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual int size() { return CLEDController::size() * LANES; } - - virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) { - mWait.wait(); - uint32_t clocks = showRGBInternal(pixels); - #if FASTLED_ALLOW_INTERRUPTS == 0 - // Adjust the timer - long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (1 + (microsTaken / 1000)); - #endif - - mWait.mark(); - } - - virtual void init() { - if(FIRST_PIN == PORTC_FIRST_PIN) { // PORTC - switch(USED_LANES) { - case 12: FastPin<30>::setOutput(); - case 11: FastPin<29>::setOutput(); - case 10: FastPin<27>::setOutput(); - case 9: FastPin<28>::setOutput(); - case 8: FastPin<12>::setOutput(); - case 7: FastPin<11>::setOutput(); - case 6: FastPin<13>::setOutput(); - case 5: FastPin<10>::setOutput(); - case 4: FastPin<9>::setOutput(); - case 3: FastPin<23>::setOutput(); - case 2: FastPin<22>::setOutput(); - case 1: FastPin<15>::setOutput(); - } - } else if(FIRST_PIN == PORTD_FIRST_PIN) { // PORTD - switch(USED_LANES) { - case 8: FastPin<5>::setOutput(); - case 7: FastPin<21>::setOutput(); - case 6: FastPin<20>::setOutput(); - case 5: FastPin<6>::setOutput(); - case 4: FastPin<8>::setOutput(); - case 3: FastPin<7>::setOutput(); - case 2: FastPin<14>::setOutput(); - case 1: FastPin<2>::setOutput(); - } - } - mPinMask = FastPin<FIRST_PIN>::mask(); - mPort = FastPin<FIRST_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - typedef union { - uint8_t bytes[12]; - uint16_t shorts[6]; - uint32_t raw[3]; - } Lines; - - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER, LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) { - register Lines b2; - if(USED_LANES>8) { - transpose8<1,2>(b.bytes,b2.bytes); - transpose8<1,2>(b.bytes+8,b2.bytes+1); - } else { - transpose8x1(b.bytes,b2.bytes); - } - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - for(register uint32_t i = 0; i < (USED_LANES/2); ++i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3; - *FastPin<FIRST_PIN>::sport() = PORT_MASK; - - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - if(USED_LANES>8) { - *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK); - } else { - *FastPin<FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PORT_MASK); - } - - while((next_mark - ARM_DWT_CYCCNT) > (T3)); - *FastPin<FIRST_PIN>::cport() = PORT_MASK; - - b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); - b.bytes[i+(USED_LANES/2)] = pixels.template loadAndScale<PX>(pixels,i+(USED_LANES/2),d,scale); - } - - // if folks use an odd numnber of lanes, get the last byte's value here - if(USED_LANES & 0x01) { - b.bytes[USED_LANES-1] = pixels.template loadAndScale<PX>(pixels,USED_LANES-1,d,scale); - } - - for(register uint32_t i = USED_LANES/2; i < 8; ++i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3; - *FastPin<FIRST_PIN>::sport() = PORT_MASK; - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - if(USED_LANES>8) { - *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK); - } else { - // b2.bytes[0] = 0; - *FastPin<FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PORT_MASK); - } - - while((next_mark - ARM_DWT_CYCCNT) > (T3)); - *FastPin<FIRST_PIN>::cport() = PORT_MASK; - - } - } - - - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) { - // Get access to the clock - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - ARM_DWT_CYCCNT = 0; - - // Setup the pixel controller and load/scale the first byte - allpixels.preStepFirstByteDithering(); - register Lines b0; - - allpixels.preStepFirstByteDithering(); - for(int i = 0; i < USED_LANES; ++i) { - b0.bytes[i] = allpixels.loadAndScale0(i); - } - - cli(); - uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - - while(allpixels.has(1)) { - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-5)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; } - } - #endif - allpixels.stepDithering(); - - // Write first byte, read next byte - writeBits<8+XTRA0,1>(next_mark, b0, allpixels); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(next_mark, b0, allpixels); - allpixels.advanceData(); - - // Write third byte - writeBits<8+XTRA0,0>(next_mark, b0, allpixels); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - - return ARM_DWT_CYCCNT; - } -}; - -#define PMASK ((1<<(LANES))-1) -#define PMASK_HI (PMASK>>8 & 0xFF) -#define PMASK_LO (PMASK & 0xFF) - -template <uint8_t LANES, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class SixteenWayInlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PMASK> { - typedef typename FastPin<PORTC_FIRST_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<PORTC_FIRST_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - static_assert(LANES <= 16, "Maximum of 16 lanes for Teensy parallel controllers!"); - // FastPin<30>::setOutput(); - // FastPin<29>::setOutput(); - // FastPin<27>::setOutput(); - // FastPin<28>::setOutput(); - switch(LANES) { - case 16: FastPin<12>::setOutput(); - case 15: FastPin<11>::setOutput(); - case 14: FastPin<13>::setOutput(); - case 13: FastPin<10>::setOutput(); - case 12: FastPin<9>::setOutput(); - case 11: FastPin<23>::setOutput(); - case 10: FastPin<22>::setOutput(); - case 9: FastPin<15>::setOutput(); - - case 8: FastPin<5>::setOutput(); - case 7: FastPin<21>::setOutput(); - case 6: FastPin<20>::setOutput(); - case 5: FastPin<6>::setOutput(); - case 4: FastPin<8>::setOutput(); - case 3: FastPin<7>::setOutput(); - case 2: FastPin<14>::setOutput(); - case 1: FastPin<2>::setOutput(); - } - } - - virtual void showPixels(PixelController<RGB_ORDER, LANES, PMASK> & pixels) { - mWait.wait(); - uint32_t clocks = showRGBInternal(pixels); - #if FASTLED_ALLOW_INTERRUPTS == 0 - // Adjust the timer - long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (1 + (microsTaken / 1000)); - #endif - - mWait.mark(); - } - - typedef union { - uint8_t bytes[16]; - uint16_t shorts[8]; - uint32_t raw[4]; - } Lines; - - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER,LANES, PMASK> &pixels) { // , register uint32_t & b2) { - register Lines b2; - transpose8x1(b.bytes,b2.bytes); - transpose8x1(b.bytes+8,b2.bytes+8); - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - for(register uint32_t i = 0; (i < LANES) && (i < 8); ++i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3; - *FastPin<PORTD_FIRST_PIN>::sport() = PMASK_LO; - *FastPin<PORTC_FIRST_PIN>::sport() = PMASK_HI; - - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+6)); - *FastPin<PORTD_FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PMASK_LO); - *FastPin<PORTC_FIRST_PIN>::cport() = ((~b2.bytes[15-i]) & PMASK_HI); - - while((next_mark - ARM_DWT_CYCCNT) > (T3)); - *FastPin<PORTD_FIRST_PIN>::cport() = PMASK_LO; - *FastPin<PORTC_FIRST_PIN>::cport() = PMASK_HI; - - b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); - if(LANES==16 || (LANES>8 && ((i+8) < LANES))) { - b.bytes[i+8] = pixels.template loadAndScale<PX>(pixels,i+8,d,scale); - } - } - } - - - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER,LANES, PMASK> &allpixels) { - // Get access to the clock - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - ARM_DWT_CYCCNT = 0; - - // Setup the pixel controller and load/scale the first byte - allpixels.preStepFirstByteDithering(); - register Lines b0; - - allpixels.preStepFirstByteDithering(); - for(int i = 0; i < LANES; ++i) { - b0.bytes[i] = allpixels.loadAndScale0(i); - } - - cli(); - uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - - while(allpixels.has(1)) { - allpixels.stepDithering(); - #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; } - } - #endif - - // Write first byte, read next byte - writeBits<8+XTRA0,1>(next_mark, b0, allpixels); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(next_mark, b0, allpixels); - allpixels.advanceData(); - - // Write third byte - writeBits<8+XTRA0,0>(next_mark, b0, allpixels); - - #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - sei(); - - return ARM_DWT_CYCCNT; - } -}; - -FASTLED_NAMESPACE_END - -#endif - -#endif diff --git a/FastLED/src/platforms/arm/k20/fastled_arm_k20.h b/FastLED/src/platforms/arm/k20/fastled_arm_k20.h deleted file mode 100644 index 06c5c8e8fe6f74dc0274ab74842f7c97fe0dc750..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/fastled_arm_k20.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __INC_FASTLED_ARM_K20_H -#define __INC_FASTLED_ARM_K20_H - -// Include the k20 headers -#include "fastpin_arm_k20.h" -#include "fastspi_arm_k20.h" -#include "octows2811_controller.h" -#include "ws2812serial_controller.h" -#include "smartmatrix_t3.h" -#include "clockless_arm_k20.h" -#include "clockless_block_arm_k20.h" - -#endif diff --git a/FastLED/src/platforms/arm/k20/fastpin_arm_k20.h b/FastLED/src/platforms/arm/k20/fastpin_arm_k20.h deleted file mode 100644 index 736bd461741dc2718b4f1d127d9f4e6e9232477c..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/fastpin_arm_k20.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef __FASTPIN_ARM_K20_H -#define __FASTPIN_ARM_K20_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be sloightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - - -/// Template definition for teensy 3.0 style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found -/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. -/// The registers are data output, set output, clear output, toggle output, input, and direction -template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { _PSOR::r() = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { _PTOR::r() = _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_PSOR::r(); } - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_PCOR::r(); } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - -/// Template definition for teensy 3.0 style ARM pins using bit banding, providing direct access to the various GPIO registers. GCC -/// does a poor job of optimizing around these accesses so they are not being used just yet. -template<uint8_t PIN, int _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN_BITBAND { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 1; } - inline static void lo() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 0; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { *_PTOR::template rx<_BIT>() = 1; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return 1; } - inline static port_t loval() __attribute__ ((always_inline)) { return 0; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return _PDOR::template rx<_BIT>(); } - inline static port_t mask() __attribute__ ((always_inline)) { return 1; } -}; - -// Macros for k20 pin access/definition -#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) -#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) - -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \ - template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } }; -#define _FL_IO(L,C) _RD32(GPIO ## L ## _PDOR); _RD32(GPIO ## L ## _PSOR); _RD32(GPIO ## L ## _PCOR); _RD32(GPIO ## L ## _PTOR); _RD32(GPIO ## L ## _PDIR); _RD32(GPIO ## L ## _PDDR); _FL_DEFINE_PORT3(L,C,_R(GPIO ## L ## _PDOR)); - -#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \ - _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; \ - template<> class FastPinBB<PIN> : public _ARMPIN_BITBAND<PIN, BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \ - _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; - -// Actual pin definitions -_FL_IO(A,0); _FL_IO(B,1); _FL_IO(C,2); _FL_IO(D,3); _FL_IO(E,4); - -#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) - -#define MAX_PIN 33 -_FL_DEFPIN(0, 16, B); _FL_DEFPIN(1, 17, B); _FL_DEFPIN(2, 0, D); _FL_DEFPIN(3, 12, A); -_FL_DEFPIN(4, 13, A); _FL_DEFPIN(5, 7, D); _FL_DEFPIN(6, 4, D); _FL_DEFPIN(7, 2, D); -_FL_DEFPIN(8, 3, D); _FL_DEFPIN(9, 3, C); _FL_DEFPIN(10, 4, C); _FL_DEFPIN(11, 6, C); -_FL_DEFPIN(12, 7, C); _FL_DEFPIN(13, 5, C); _FL_DEFPIN(14, 1, D); _FL_DEFPIN(15, 0, C); -_FL_DEFPIN(16, 0, B); _FL_DEFPIN(17, 1, B); _FL_DEFPIN(18, 3, B); _FL_DEFPIN(19, 2, B); -_FL_DEFPIN(20, 5, D); _FL_DEFPIN(21, 6, D); _FL_DEFPIN(22, 1, C); _FL_DEFPIN(23, 2, C); -_FL_DEFPIN(24, 5, A); _FL_DEFPIN(25, 19, B); _FL_DEFPIN(26, 1, E); _FL_DEFPIN(27, 9, C); -_FL_DEFPIN(28, 8, C); _FL_DEFPIN(29, 10, C); _FL_DEFPIN(30, 11, C); _FL_DEFPIN(31, 0, E); -_FL_DEFPIN(32, 18, B); _FL_DEFPIN(33, 4, A); - -#define SPI_DATA 11 -#define SPI_CLOCK 13 -#define SPI1 (*(SPI_t *)0x4002D000) - -#define SPI2_DATA 7 -#define SPI2_CLOCK 14 - -#define FASTLED_TEENSY3 -#define ARM_HARDWARE_SPI -#define HAS_HARDWARE_PIN_SUPPORT -#endif - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - -#endif // __INC_FASTPIN_ARM_K20 diff --git a/FastLED/src/platforms/arm/k20/fastspi_arm_k20.h b/FastLED/src/platforms/arm/k20/fastspi_arm_k20.h deleted file mode 100644 index 3d492558dcc25a7b11ec8164a6c57a5a7c352732..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/fastspi_arm_k20.h +++ /dev/null @@ -1,466 +0,0 @@ -#ifndef __INC_FASTSPI_ARM_H -#define __INC_FASTSPI_ARM_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) - -// Version 1.20 renamed SPI_t to KINETISK_SPI_t -#if TEENSYDUINO >= 120 -#define SPI_t KINETISK_SPI_t -#endif - -#ifndef KINETISK_SPI0 -#define KINETISK_SPI0 SPI0 -#endif - -#ifndef SPI_PUSHR_CONT -#define SPI_PUSHR_CONT SPIX.PUSHR_CONT -#define SPI_PUSHR_CTAS(X) SPIX.PUSHR_CTAS(X) -#define SPI_PUSHR_EOQ SPIX.PUSHR_EOQ -#define SPI_PUSHR_CTCNT SPIX.PUSHR_CTCNT -#define SPI_PUSHR_PCS(X) SPIX.PUSHR_PCS(X) -#endif - -// Template function that, on compilation, expands to a constant representing the highest bit set in a byte. Right now, -// if no bits are set (value is 0), it returns 0, which is also the value returned if the lowest bit is the only bit -// set (the zero-th bit). Unclear if I will want this to change at some point. -template<int VAL, int BIT> class BitWork { -public: - static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork<VAL, BIT-1>::highestBit(); } -}; - -template<int VAL> class BitWork<VAL, 0> { -public: - static int highestBit() __attribute__((always_inline)) { return 0; } -}; - -#define MAX(A, B) (( (A) > (B) ) ? (A) : (B)) - -#define USE_CONT 0 -// intra-frame backup data -struct SPIState { - uint32_t _ctar0,_ctar1; - uint32_t pins[4]; -}; - -// extern SPIState gState; - - -// Templated function to translate a clock divider value into the prescalar, scalar, and clock doubling setting for the world. -template <int VAL> void getScalars(uint32_t & preScalar, uint32_t & scalar, uint32_t & dbl) { - switch(VAL) { - // Handle the dbl clock cases - case 0: case 1: - case 2: preScalar = 0; scalar = 0; dbl = 1; break; - case 3: preScalar = 1; scalar = 0; dbl = 1; break; - case 5: preScalar = 2; scalar = 0; dbl = 1; break; - case 7: preScalar = 3; scalar = 0; dbl = 1; break; - - // Handle the scalar value 6 cases (since it's not a power of two, it won't get caught - // below) - case 9: preScalar = 1; scalar = 2; dbl = 1; break; - case 18: case 19: preScalar = 1; scalar = 2; dbl = 0; break; - - case 15: preScalar = 2; scalar = 2; dbl = 1; break; - case 30: case 31: preScalar = 2; scalar = 2; dbl = 0; break; - - case 21: case 22: case 23: preScalar = 3; scalar = 2; dbl = 1; break; - case 42: case 43: case 44: case 45: case 46: case 47: preScalar = 3; scalar = 2; dbl = 0; break; - default: { - int p2 = BitWork<VAL/2, 15>::highestBit(); - int p3 = BitWork<VAL/3, 15>::highestBit(); - int p5 = BitWork<VAL/5, 15>::highestBit(); - int p7 = BitWork<VAL/7, 15>::highestBit(); - - int w2 = 2 * (1 << p2); - int w3 = (VAL/3) > 0 ? 3 * (1 << p3) : 0; - int w5 = (VAL/5) > 0 ? 5 * (1 << p5) : 0; - int w7 = (VAL/7) > 0 ? 7 * (1 << p7) : 0; - - int maxval = MAX(MAX(w2, w3), MAX(w5, w7)); - - if(w2 == maxval) { preScalar = 0; scalar = p2; } - else if(w3 == maxval) { preScalar = 1; scalar = p3; } - else if(w5 == maxval) { preScalar = 2; scalar = p5; } - else if(w7 == maxval) { preScalar = 3; scalar = p7; } - - dbl = 0; - if(scalar == 0) { dbl = 1; } - else if(scalar < 3) { --scalar; } - } - } - return; -} - -#define SPIX (*(SPI_t*)pSPIX) - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER, uint32_t pSPIX> -class ARMHardwareSPIOutput { - Selectable *m_pSelect; - SPIState gState; - - // Borrowed from the teensy3 SPSR emulation code -- note, enabling pin 7 disables pin 11 (and vice versa), - // and likewise enabling pin 14 disables pin 13 (and vice versa) - inline void enable_pins(void) __attribute__((always_inline)) { - //serial_print("enable_pins\n"); - switch(_DATA_PIN) { - case 7: - CORE_PIN7_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - break; - case 11: - CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - break; - } - - switch(_CLOCK_PIN) { - case 13: - CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - break; - case 14: - CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - break; - } - } - - // Borrowed from the teensy3 SPSR emulation code. We disable the pins that we're using, and restore the state on the pins that we aren't using - inline void disable_pins(void) __attribute__((always_inline)) { - switch(_DATA_PIN) { - case 7: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN11_CONFIG = gState.pins[1]; break; - case 11: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN7_CONFIG = gState.pins[0]; break; - } - - switch(_CLOCK_PIN) { - case 13: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN14_CONFIG = gState.pins[3]; break; - case 14: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN13_CONFIG = gState.pins[2]; break; - } - } - - static inline void update_ctars(uint32_t ctar0, uint32_t ctar1) __attribute__((always_inline)) { - if(SPIX.CTAR0 == ctar0 && SPIX.CTAR1 == ctar1) return; - uint32_t mcr = SPIX.MCR; - if(mcr & SPI_MCR_MDIS) { - SPIX.CTAR0 = ctar0; - SPIX.CTAR1 = ctar1; - } else { - SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPIX.CTAR0 = ctar0; - SPIX.CTAR1 = ctar1; - SPIX.MCR = mcr; - } - } - - static inline void update_ctar0(uint32_t ctar) __attribute__((always_inline)) { - if (SPIX.CTAR0 == ctar) return; - uint32_t mcr = SPIX.MCR; - if (mcr & SPI_MCR_MDIS) { - SPIX.CTAR0 = ctar; - } else { - SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPIX.CTAR0 = ctar; - - SPIX.MCR = mcr; - } - } - - static inline void update_ctar1(uint32_t ctar) __attribute__((always_inline)) { - if (SPIX.CTAR1 == ctar) return; - uint32_t mcr = SPIX.MCR; - if (mcr & SPI_MCR_MDIS) { - SPIX.CTAR1 = ctar; - } else { - SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPIX.CTAR1 = ctar; - SPIX.MCR = mcr; - - } - } - - void setSPIRate() { - // Configure CTAR0, defaulting to 8 bits and CTAR1, defaulting to 16 bits - uint32_t _PBR = 0; - uint32_t _BR = 0; - uint32_t _CSSCK = 0; - uint32_t _DBR = 0; - - // if(_SPI_CLOCK_DIVIDER >= 256) { _PBR = 0; _BR = _CSSCK = 7; _DBR = 0; } // osc/256 - // else if(_SPI_CLOCK_DIVIDER >= 128) { _PBR = 0; _BR = _CSSCK = 6; _DBR = 0; } // osc/128 - // else if(_SPI_CLOCK_DIVIDER >= 64) { _PBR = 0; _BR = _CSSCK = 5; _DBR = 0; } // osc/64 - // else if(_SPI_CLOCK_DIVIDER >= 32) { _PBR = 0; _BR = _CSSCK = 4; _DBR = 0; } // osc/32 - // else if(_SPI_CLOCK_DIVIDER >= 16) { _PBR = 0; _BR = _CSSCK = 3; _DBR = 0; } // osc/16 - // else if(_SPI_CLOCK_DIVIDER >= 8) { _PBR = 0; _BR = _CSSCK = 1; _DBR = 0; } // osc/8 - // else if(_SPI_CLOCK_DIVIDER >= 7) { _PBR = 3; _BR = _CSSCK = 0; _DBR = 1; } // osc/7 - // else if(_SPI_CLOCK_DIVIDER >= 5) { _PBR = 2; _BR = _CSSCK = 0; _DBR = 1; } // osc/5 - // else if(_SPI_CLOCK_DIVIDER >= 4) { _PBR = 0; _BR = _CSSCK = 0; _DBR = 0; } // osc/4 - // else if(_SPI_CLOCK_DIVIDER >= 3) { _PBR = 1; _BR = _CSSCK = 0; _DBR = 1; } // osc/3 - // else { _PBR = 0; _BR = _CSSCK = 0; _DBR = 1; } // osc/2 - - getScalars<_SPI_CLOCK_DIVIDER>(_PBR, _BR, _DBR); - _CSSCK = _BR; - - uint32_t ctar0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(_PBR) | SPI_CTAR_BR(_BR) | SPI_CTAR_CSSCK(_CSSCK); - uint32_t ctar1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(_PBR) | SPI_CTAR_BR(_BR) | SPI_CTAR_CSSCK(_CSSCK); - - #if USE_CONT == 1 - ctar0 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL; - ctar1 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL; - #endif - - if(_DBR) { - ctar0 |= SPI_CTAR_DBR; - ctar1 |= SPI_CTAR_DBR; - } - - update_ctars(ctar0,ctar1); - } - - void inline save_spi_state() __attribute__ ((always_inline)) { - // save ctar data - gState._ctar0 = SPIX.CTAR0; - gState._ctar1 = SPIX.CTAR1; - - // save data for the not-us pins - gState.pins[0] = CORE_PIN7_CONFIG; - gState.pins[1] = CORE_PIN11_CONFIG; - gState.pins[2] = CORE_PIN13_CONFIG; - gState.pins[3] = CORE_PIN14_CONFIG; - } - - void inline restore_spi_state() __attribute__ ((always_inline)) { - // restore ctar data - update_ctars(gState._ctar0,gState._ctar1); - - // restore data for the not-us pins (not necessary because disable_pins will do this) - // CORE_PIN7_CONFIG = gState.pins[0]; - // CORE_PIN11_CONFIG = gState.pins[1]; - // CORE_PIN13_CONFIG = gState.pins[2]; - // CORE_PIN14_CONFIG = gState.pins[3]; - } - - -public: - ARMHardwareSPIOutput() { m_pSelect = NULL; } - ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - void init() { - // set the pins to output - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); - - // Enable SPI0 clock - uint32_t sim6 = SIM_SCGC6; - if((SPI_t*)pSPIX == &KINETISK_SPI0) { - if (!(sim6 & SIM_SCGC6_SPI0)) { - //serial_print("init1\n"); - SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0; - SPIX.CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1); - } - } else if((SPI_t*)pSPIX == &SPI1) { - if (!(sim6 & SIM_SCGC6_SPI1)) { - //serial_print("init1\n"); - SIM_SCGC6 = sim6 | SIM_SCGC6_SPI1; - SPIX.CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1); - } - } - - // Configure SPI as the master and enable - SPIX.MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE); - SPIX.MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); - - // pin/spi configuration happens on select - } - - static void waitFully() __attribute__((always_inline)) { - // Wait for the last byte to get shifted into the register - bool empty = false; - - do { - cli(); - if ((SPIX.SR & 0xF000) > 0) { - // reset the TCF flag - SPIX.SR |= SPI_SR_TCF; - } else { - empty = true; - } - sei(); - } while (!empty); - - // wait for the TCF flag to get set - while (!(SPIX.SR & SPI_SR_TCF)); - SPIX.SR |= (SPI_SR_TCF | SPI_SR_EOQF); - } - - static bool needwait() __attribute__((always_inline)) { return (SPIX.SR & 0x4000); } - static void wait() __attribute__((always_inline)) { while( (SPIX.SR & 0x4000) ); } - static void wait1() __attribute__((always_inline)) { while( (SPIX.SR & 0xF000) >= 0x2000); } - - enum ECont { CONT, NOCONT }; - enum EWait { PRE, POST, NONE }; - enum ELast { NOTLAST, LAST }; - - #if USE_CONT == 1 - #define CM CONT - #else - #define CM NOCONT - #endif - #define WM PRE - - template<ECont CONT_STATE, EWait WAIT_STATE, ELast LAST_STATE> class Write { - public: - static void writeWord(uint16_t w) __attribute__((always_inline)) { - if(WAIT_STATE == PRE) { wait(); } - cli(); - SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | - ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | - SPI_PUSHR_CTAS(1) | (w & 0xFFFF); - SPIX.SR |= SPI_SR_TCF; - sei(); - if(WAIT_STATE == POST) { wait(); } - } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { - if(WAIT_STATE == PRE) { wait(); } - cli(); - SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | - ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | - SPI_PUSHR_CTAS(0) | (b & 0xFF); - SPIX.SR |= SPI_SR_TCF; - sei(); - if(WAIT_STATE == POST) { wait(); } - } - }; - - static void writeWord(uint16_t w) __attribute__((always_inline)) { wait(); cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF; sei(); } - static void writeWordNoWait(uint16_t w) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF; sei(); } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); } - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF);SPIX.SR |= SPI_SR_TCF; sei(); wait(); } - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); } - - static void writeWordCont(uint16_t w) __attribute__((always_inline)) { wait(); cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF; sei(); } - static void writeWordContNoWait(uint16_t w) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF; sei();} - - static void writeByteCont(uint8_t b) __attribute__((always_inline)) { wait(); cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); } - static void writeByteContPostWait(uint8_t b) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); wait(); } - static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); } - - // not the most efficient mechanism in the world - but should be enough for sm16716 and friends - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - uint32_t ctar1_save = SPIX.CTAR1; - - // Clear out the FMSZ bits, reset them for 1 bit transferd for the start bit - uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(0); - update_ctar1(ctar1); - - writeWord( (b & (1 << BIT)) != 0); - - update_ctar1(ctar1_save); - } - - void inline select() __attribute__((always_inline)) { - save_spi_state(); - if(m_pSelect != NULL) { m_pSelect->select(); } - setSPIRate(); - enable_pins(); - } - - void inline release() __attribute__((always_inline)) { - disable_pins(); - if(m_pSelect != NULL) { m_pSelect->release(); } - restore_spi_state(); - } - - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { Write<CM, WM, NOTLAST>::writeByte(value); } - } - - void writeBytesValue(uint8_t value, int len) { - select(); - while(len--) { - writeByte(value); - } - waitFully(); - release(); - } - - // Write a block of n uint8_ts out - template <class D> void writeBytes(register uint8_t *data, int len) { - uint8_t *end = data + len; - select(); - // could be optimized to write 16bit words out instead of 8bit bytes - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - int len = pixels.mLen; - - // Setup the pixel controller - if((FLAGS & FLAG_START_BIT) == 0) { - //If no start bit stupiditiy, write out as many 16-bit blocks as we can - while(pixels.has(2)) { - // Load and write out the first two bytes - if(WM == NONE) { wait1(); } - Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1())); - - // Load and write out the next two bytes (step dithering, advance data in between since we - // cross pixels here) - Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale2()) << 8 | D::adjust(pixels.stepAdvanceAndLoadAndScale0())); - - // Load and write out the next two bytes - Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale1()) << 8 | D::adjust(pixels.loadAndScale2())); - pixels.stepDithering(); - pixels.advanceData(); - } - - if(pixels.has(1)) { - if(WM == NONE) { wait1(); } - // write out the rest as alternating 16/8-bit blocks (likely to be just one) - Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1())); - Write<CM, WM, NOTLAST>::writeByte(D::adjust(pixels.loadAndScale2())); - } - - D::postBlock(len); - waitFully(); - } else if(FLAGS & FLAG_START_BIT) { - uint32_t ctar1_save = SPIX.CTAR1; - - // Clear out the FMSZ bits, reset them for 9 bits transferd for the start bit - uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(8); - update_ctar1(ctar1); - - while(pixels.has(1)) { - writeWord( 0x100 | D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - waitFully(); - - // restore ctar1 - update_ctar1(ctar1_save); - } - release(); - } -}; -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/k20/led_sysdefs_arm_k20.h b/FastLED/src/platforms/arm/k20/led_sysdefs_arm_k20.h deleted file mode 100644 index 0dcb626a7c9a9bdb42faee2136b33cad2e490f4e..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/led_sysdefs_arm_k20.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_ARM_K20_H -#define __INC_LED_SYSDEFS_ARM_K20_H - -#define FASTLED_TEENSY3 -#define FASTLED_ARM - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -#if (F_CPU == 96000000) -#define CLK_DBL 1 -#endif - -// Get some system include files -#include <avr/io.h> -#include <avr/interrupt.h> // for cli/se definitions - -// Define the register types -#if defined(ARDUINO) // && ARDUINO < 150 -typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ -typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ -#endif - -extern volatile uint32_t systick_millis_count; -# define MS_COUNTER systick_millis_count - - -// Default to using PROGMEM, since TEENSY3 provides it -// even though all it does is ignore it. Just being -// conservative here in case TEENSY3 changes. -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 1 -#endif - - -#endif diff --git a/FastLED/src/platforms/arm/k20/octows2811_controller.h b/FastLED/src/platforms/arm/k20/octows2811_controller.h deleted file mode 100644 index f365e61f8d77a56cd72d6e82eea0d40756c31d87..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/octows2811_controller.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __INC_OCTOWS2811_CONTROLLER_H -#define __INC_OCTOWS2811_CONTROLLER_H - -#ifdef USE_OCTOWS2811 - -// #include "OctoWS2811.h" - -FASTLED_NAMESPACE_BEGIN - -template<EOrder RGB_ORDER = GRB, uint8_t CHIP = WS2811_800kHz> -class COctoWS2811Controller : public CPixelLEDController<RGB_ORDER, 8, 0xFF> { - OctoWS2811 *pocto; - uint8_t *drawbuffer,*framebuffer; - - void _init(int nLeds) { - if(pocto == NULL) { - drawbuffer = (uint8_t*)malloc(nLeds * 8 * 3); - framebuffer = (uint8_t*)malloc(nLeds * 8 * 3); - - // byte ordering is handled in show by the pixel controller - int config = WS2811_RGB; - config |= CHIP; - - pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, config); - - pocto->begin(); - } - } -public: - COctoWS2811Controller() { pocto = NULL; } - virtual int size() { return CLEDController::size() * 8; } - - virtual void init() { /* do nothing yet */ } - - typedef union { - uint8_t bytes[8]; - uint32_t raw[2]; - } Lines; - - virtual void showPixels(PixelController<RGB_ORDER, 8, 0xFF> & pixels) { - _init(pixels.size()); - - uint8_t *pData = drawbuffer; - while(pixels.has(1)) { - Lines b; - - for(int i = 0; i < 8; ++i) { b.bytes[i] = pixels.loadAndScale0(i); } - transpose8x1_MSB(b.bytes,pData); pData += 8; - for(int i = 0; i < 8; ++i) { b.bytes[i] = pixels.loadAndScale1(i); } - transpose8x1_MSB(b.bytes,pData); pData += 8; - for(int i = 0; i < 8; ++i) { b.bytes[i] = pixels.loadAndScale2(i); } - transpose8x1_MSB(b.bytes,pData); pData += 8; - pixels.stepDithering(); - pixels.advanceData(); - } - - pocto->show(); - } - -}; - -FASTLED_NAMESPACE_END - -#endif - -#endif diff --git a/FastLED/src/platforms/arm/k20/smartmatrix_t3.h b/FastLED/src/platforms/arm/k20/smartmatrix_t3.h deleted file mode 100644 index c9747f0b410fbd6d2231ee238051956780fae247..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/smartmatrix_t3.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __INC_SMARTMATRIX_T3_H -#define __INC_SMARTMATRIX_T3_H - -#ifdef SmartMatrix_h -#include <SmartMatrix.h> - -FASTLED_NAMESPACE_BEGIN - -extern SmartMatrix *pSmartMatrix; - -// note - dmx simple must be included before FastSPI for this code to be enabled -class CSmartMatrixController : public CPixelLEDController<RGB_ORDER> { - SmartMatrix matrix; - -public: - // initialize the LED controller - virtual void init() { - // Initialize 32x32 LED Matrix - matrix.begin(); - matrix.setBrightness(255); - matrix.setColorCorrection(ccNone); - - // Clear screen - clearLeds(0); - matrix.swapBuffers(); - pSmartMatrix = &matrix; - } - - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - if(SMART_MATRIX_CAN_TRIPLE_BUFFER) { - rgb24 *md = matrix.getRealBackBuffer(); - } else { - rgb24 *md = matrix.backBuffer(); - } - while(pixels.has(1)) { - md->red = pixels.loadAndScale0(); - md->green = pixels.loadAndScale1(); - md->blue = pixels.loadAndScale2(); - md++; - pixels.advanceData(); - pixels.stepDithering(); - } - matrix.swapBuffers(); - if(SMART_MATRIX_CAN_TRIPLE_BUFFER && pixels.advanceBy() > 0) { - matrix.setBackBuffer(pixels.mData); - } - } -}; - -FASTLED_NAMESPACE_END - -#endif - -#endif diff --git a/FastLED/src/platforms/arm/k20/ws2812serial_controller.h b/FastLED/src/platforms/arm/k20/ws2812serial_controller.h deleted file mode 100644 index a761dd49eeb28db83bb8f84c79ed4d0c0414f77c..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k20/ws2812serial_controller.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __INC_WS2812SERIAL_CONTROLLER_H -#define __INC_WS2812SERIAL_CONTROLLER_H - -#ifdef USE_WS2812SERIAL - -FASTLED_NAMESPACE_BEGIN - -template<int DATA_PIN, EOrder RGB_ORDER> -class CWS2812SerialController : public CPixelLEDController<RGB_ORDER, 8, 0xFF> { - WS2812Serial *pserial; - uint8_t *drawbuffer,*framebuffer; - - void _init(int nLeds) { - if (pserial == NULL) { - drawbuffer = (uint8_t*)malloc(nLeds * 3); - framebuffer = (uint8_t*)malloc(nLeds * 12); - pserial = new WS2812Serial(nLeds, framebuffer, drawbuffer, DATA_PIN, WS2812_RGB); - pserial->begin(); - } - } - -public: - CWS2812SerialController() { pserial = NULL; } - - virtual void init() { /* do nothing yet */ } - - virtual void showPixels(PixelController<RGB_ORDER, 8, 0xFF> & pixels) { - _init(pixels.size()); - - uint8_t *p = drawbuffer; - - while(pixels.has(1)) { - *p++ = pixels.loadAndScale0(); - *p++ = pixels.loadAndScale1(); - *p++ = pixels.loadAndScale2(); - pixels.stepDithering(); - pixels.advanceData(); - } - pserial->show(); - } - -}; - -FASTLED_NAMESPACE_END - -#endif // USE_WS2812SERIAL -#endif // __INC_WS2812SERIAL_CONTROLLER_H diff --git a/FastLED/src/platforms/arm/k66/clockless_arm_k66.h b/FastLED/src/platforms/arm/k66/clockless_arm_k66.h deleted file mode 100644 index e9dcc0cd39da7ccc0c343bafda160bf85f223477..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k66/clockless_arm_k66.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_K66_H -#define __INC_CLOCKLESS_ARM_K66_H - -FASTLED_NAMESPACE_BEGIN - -// Definition for a single channel clockless controller for the k66 family of chips, like that used in the teensy 3.6 -// See clockless.h for detailed info on how the template parameters are used. -#if defined(FASTLED_TEENSY3) - -#define FASTLED_HAS_CLOCKLESS 1 - -template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - FastPin<DATA_PIN>::setOutput(); - mPinMask = FastPin<DATA_PIN>::mask(); - mPort = FastPin<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - mWait.mark(); - } - - template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) { - for(register uint32_t i = BITS-1; i > 0; --i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - FastPin<DATA_PIN>::fastset(port, hi); - if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } else { - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } - b <<= 1; - } - - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - FastPin<DATA_PIN>::fastset(port, hi); - - if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } else { - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - FastPin<DATA_PIN>::fastset(port, lo); - } - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - // Get access to the clock - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - ARM_DWT_CYCCNT = 0; - - register data_ptr_t port = FastPin<DATA_PIN>::port(); - register data_t hi = *port | FastPin<DATA_PIN>::mask(); - register data_t lo = *port & ~FastPin<DATA_PIN>::mask(); - *port = lo; - - // Setup the pixel controller and load/scale the first byte - pixels.preStepFirstByteDithering(); - register uint8_t b = pixels.loadAndScale0(); - - cli(); - uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - - while(pixels.has(1)) { - pixels.stepDithering(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; } - } - - hi = *port | FastPin<DATA_PIN>::mask(); - lo = *port & ~FastPin<DATA_PIN>::mask(); - #endif - // Write first byte, read next byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale1(); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale2(); - - // Write third byte, read 1st byte of next pixel - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.advanceAndLoadAndScale0(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - - sei(); - return ARM_DWT_CYCCNT; - } -}; -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/k66/clockless_block_arm_k66.h b/FastLED/src/platforms/arm/k66/clockless_block_arm_k66.h deleted file mode 100644 index 70f8c7a590619df7e341a98b236a89a0dec6eb63..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k66/clockless_block_arm_k66.h +++ /dev/null @@ -1,347 +0,0 @@ -#ifndef __INC_BLOCK_CLOCKLESS_ARM_K66_H -#define __INC_BLOCK_CLOCKLESS_ARM_K66_H - -// Definition for a single channel clockless controller for the k66 family of chips, like that used in the teensy 3.6 -// See clockless.h for detailed info on how the template parameters are used. -#if defined(FASTLED_TEENSY3) -#define FASTLED_HAS_BLOCKLESS 1 - -#define PORTB_FIRST_PIN 0 -#define PORTC_FIRST_PIN 15 -#define PORTD_FIRST_PIN 2 -#define HAS_PORTDC 1 - -#define LANE_MASK (((1<<LANES)-1) & ((FIRST_PIN==2) ? 0xFF : 0xFFF)) -#define PORT_SHIFT(P) ((P) << ((FIRST_PIN==0) ? 16 : 0)) -#define PORT_MASK PORT_SHIFT(LANE_MASK) - -#define MIN(X,Y) (((X)<(Y)) ? (X):(Y)) -#define USED_LANES ((FIRST_PIN!=15) ? MIN(LANES,8) : MIN(LANES,12)) - -#include <kinetis.h> - -FASTLED_NAMESPACE_BEGIN - -template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 40> -class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, LANE_MASK> { - typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<FIRST_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual int size() { return CLEDController::size() * LANES; } - - virtual void showPixels(PixelController<RGB_ORDER, LANES, LANE_MASK> & pixels) { - mWait.wait(); - uint32_t clocks = showRGBInternal(pixels); - #if FASTLED_ALLOW_INTERRUPTS == 0 - // Adjust the timer - long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (1 + (microsTaken / 1000)); - #endif - - mWait.mark(); - } - - virtual void init() { - if(FIRST_PIN == PORTC_FIRST_PIN) { // PORTC - switch(USED_LANES) { - case 12: FastPin<30>::setOutput(); - case 11: FastPin<29>::setOutput(); - case 10: FastPin<27>::setOutput(); - case 9: FastPin<28>::setOutput(); - case 8: FastPin<12>::setOutput(); - case 7: FastPin<11>::setOutput(); - case 6: FastPin<13>::setOutput(); - case 5: FastPin<10>::setOutput(); - case 4: FastPin<9>::setOutput(); - case 3: FastPin<23>::setOutput(); - case 2: FastPin<22>::setOutput(); - case 1: FastPin<15>::setOutput(); - } - } else if(FIRST_PIN == PORTD_FIRST_PIN) { // PORTD - switch(USED_LANES) { - case 8: FastPin<5>::setOutput(); - case 7: FastPin<21>::setOutput(); - case 6: FastPin<20>::setOutput(); - case 5: FastPin<6>::setOutput(); - case 4: FastPin<8>::setOutput(); - case 3: FastPin<7>::setOutput(); - case 2: FastPin<14>::setOutput(); - case 1: FastPin<2>::setOutput(); - } - } else if (FIRST_PIN == PORTB_FIRST_PIN) { // PORTB - switch (USED_LANES) { - case 8: FastPin<45>::setOutput(); - case 7: FastPin<44>::setOutput(); - case 6: FastPin<46>::setOutput(); - case 5: FastPin<43>::setOutput(); - case 4: FastPin<30>::setOutput(); - case 3: FastPin<29>::setOutput(); - case 2: FastPin<1>::setOutput(); - case 1: FastPin<0>::setOutput(); - } - } - mPinMask = FastPin<FIRST_PIN>::mask(); - mPort = FastPin<FIRST_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - typedef union { - uint8_t bytes[12]; - uint16_t shorts[6]; - uint32_t raw[3]; - } Lines; - - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER, LANES, LANE_MASK> &pixels) { // , register uint32_t & b2) { - register Lines b2; - if(USED_LANES>8) { - transpose8<1,2>(b.bytes,b2.bytes); - transpose8<1,2>(b.bytes+8,b2.bytes+1); - } else { - transpose8x1(b.bytes,b2.bytes); - } - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - for(register uint32_t i = 0; i < (USED_LANES/2); ++i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3; - *FastPin<FIRST_PIN>::sport() = PORT_MASK; - - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - if(USED_LANES>8) { - *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK); - } else { - *FastPin<FIRST_PIN>::cport() = (PORT_SHIFT(~b2.bytes[7-i]) & PORT_MASK); - } - - while((next_mark - ARM_DWT_CYCCNT) > (T3)); - *FastPin<FIRST_PIN>::cport() = PORT_MASK; - - b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); - b.bytes[i+(USED_LANES/2)] = pixels.template loadAndScale<PX>(pixels,i+(USED_LANES/2),d,scale); - } - - // if folks use an odd numnber of lanes, get the last byte's value here - if(USED_LANES & 0x01) { - b.bytes[USED_LANES-1] = pixels.template loadAndScale<PX>(pixels,USED_LANES-1,d,scale); - } - - for(register uint32_t i = USED_LANES/2; i < 8; ++i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3; - *FastPin<FIRST_PIN>::sport() = PORT_MASK; - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); - if(USED_LANES>8) { - *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK); - } else { - // b2.bytes[0] = 0; - *FastPin<FIRST_PIN>::cport() = (PORT_SHIFT(~b2.bytes[7-i]) & PORT_MASK); - } - - while((next_mark - ARM_DWT_CYCCNT) > (T3)); - *FastPin<FIRST_PIN>::cport() = PORT_MASK; - - } - } - - - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, LANE_MASK> &allpixels) { - // Get access to the clock - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - ARM_DWT_CYCCNT = 0; - - // Setup the pixel controller and load/scale the first byte - allpixels.preStepFirstByteDithering(); - register Lines b0; - - allpixels.preStepFirstByteDithering(); - for(int i = 0; i < USED_LANES; ++i) { - b0.bytes[i] = allpixels.loadAndScale0(i); - } - - cli(); - uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - - while(allpixels.has(1)) { - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-5)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; } - } - #endif - allpixels.stepDithering(); - - // Write first byte, read next byte - writeBits<8+XTRA0,1>(next_mark, b0, allpixels); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(next_mark, b0, allpixels); - allpixels.advanceData(); - - // Write third byte - writeBits<8+XTRA0,0>(next_mark, b0, allpixels); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - - return ARM_DWT_CYCCNT; - } -}; - -#define PMASK ((1<<(LANES))-1) -#define PMASK_HI (PMASK>>8 & 0xFF) -#define PMASK_LO (PMASK & 0xFF) - -template <uint8_t LANES, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class SixteenWayInlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PMASK> { - typedef typename FastPin<PORTC_FIRST_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<PORTC_FIRST_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - static_assert(LANES <= 16, "Maximum of 16 lanes for Teensy parallel controllers!"); - // FastPin<30>::setOutput(); - // FastPin<29>::setOutput(); - // FastPin<27>::setOutput(); - // FastPin<28>::setOutput(); - switch(LANES) { - case 16: FastPin<12>::setOutput(); - case 15: FastPin<11>::setOutput(); - case 14: FastPin<13>::setOutput(); - case 13: FastPin<10>::setOutput(); - case 12: FastPin<9>::setOutput(); - case 11: FastPin<23>::setOutput(); - case 10: FastPin<22>::setOutput(); - case 9: FastPin<15>::setOutput(); - - case 8: FastPin<5>::setOutput(); - case 7: FastPin<21>::setOutput(); - case 6: FastPin<20>::setOutput(); - case 5: FastPin<6>::setOutput(); - case 4: FastPin<8>::setOutput(); - case 3: FastPin<7>::setOutput(); - case 2: FastPin<14>::setOutput(); - case 1: FastPin<2>::setOutput(); - } - } - - virtual void showPixels(PixelController<RGB_ORDER, LANES, PMASK> & pixels) { - mWait.wait(); - uint32_t clocks = showRGBInternal(pixels); - #if FASTLED_ALLOW_INTERRUPTS == 0 - // Adjust the timer - long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (1 + (microsTaken / 1000)); - #endif - - mWait.mark(); - } - - typedef union { - uint8_t bytes[16]; - uint16_t shorts[8]; - uint32_t raw[4]; - } Lines; - - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER,LANES, PMASK> &pixels) { // , register uint32_t & b2) { - register Lines b2; - transpose8x1(b.bytes,b2.bytes); - transpose8x1(b.bytes+8,b2.bytes+8); - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - for(register uint32_t i = 0; (i < LANES) && (i < 8); ++i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3; - *FastPin<PORTD_FIRST_PIN>::sport() = PMASK_LO; - *FastPin<PORTC_FIRST_PIN>::sport() = PMASK_HI; - - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+6)); - *FastPin<PORTD_FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PMASK_LO); - *FastPin<PORTC_FIRST_PIN>::cport() = ((~b2.bytes[15-i]) & PMASK_HI); - - while((next_mark - ARM_DWT_CYCCNT) > (T3)); - *FastPin<PORTD_FIRST_PIN>::cport() = PMASK_LO; - *FastPin<PORTC_FIRST_PIN>::cport() = PMASK_HI; - - b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); - if(LANES==16 || (LANES>8 && ((i+8) < LANES))) { - b.bytes[i+8] = pixels.template loadAndScale<PX>(pixels,i+8,d,scale); - } - } - } - - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER,LANES, PMASK> &allpixels) { - // Get access to the clock - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - ARM_DWT_CYCCNT = 0; - - // Setup the pixel controller and load/scale the first byte - allpixels.preStepFirstByteDithering(); - register Lines b0; - - allpixels.preStepFirstByteDithering(); - for(int i = 0; i < LANES; ++i) { - b0.bytes[i] = allpixels.loadAndScale0(i); - } - - cli(); - uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - - while(allpixels.has(1)) { - allpixels.stepDithering(); - #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { - sei(); - return ARM_DWT_CYCCNT; } - } - #endif - - // Write first byte, read next byte - writeBits<8+XTRA0,1>(next_mark, b0, allpixels); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(next_mark, b0, allpixels); - allpixels.advanceData(); - - // Write third byte - writeBits<8+XTRA0,0>(next_mark, b0, allpixels); - - #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - sei(); - - return ARM_DWT_CYCCNT; - } -}; - -FASTLED_NAMESPACE_END - -#endif - -#endif diff --git a/FastLED/src/platforms/arm/k66/fastled_arm_k66.h b/FastLED/src/platforms/arm/k66/fastled_arm_k66.h deleted file mode 100644 index 2113e10eb7e98decbc958a69a34a3b2d22b30770..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k66/fastled_arm_k66.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __INC_FASTLED_ARM_K66_H -#define __INC_FASTLED_ARM_K66_H - -// Include the k66 headers -#include "fastpin_arm_k66.h" -#include "fastspi_arm_k66.h" -#include "../k20/octows2811_controller.h" -#include "../k20/ws2812serial_controller.h" -#include "../k20/smartmatrix_t3.h" -#include "clockless_arm_k66.h" -#include "clockless_block_arm_k66.h" - -#endif - diff --git a/FastLED/src/platforms/arm/k66/fastpin_arm_k66.h b/FastLED/src/platforms/arm/k66/fastpin_arm_k66.h deleted file mode 100644 index ef48396c455d940a3af588c09cc38d08e31969bc..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k66/fastpin_arm_k66.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef __FASTPIN_ARM_K66_H -#define __FASTPIN_ARM_K66_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be slightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - - -/// Template definition for teensy 3.0 style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found -/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. -/// The registers are data output, set output, clear output, toggle output, input, and direction -template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { _PSOR::r() = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { _PTOR::r() = _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_PSOR::r(); } - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_PCOR::r(); } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - -/// Template definition for teensy 3.0 style ARM pins using bit banding, providing direct access to the various GPIO registers. GCC -/// does a poor job of optimizing around these accesses so they are not being used just yet. -template<uint8_t PIN, int _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN_BITBAND { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 1; } - inline static void lo() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 0; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { *_PTOR::template rx<_BIT>() = 1; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return 1; } - inline static port_t loval() __attribute__ ((always_inline)) { return 0; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return _PDOR::template rx<_BIT>(); } - inline static port_t mask() __attribute__ ((always_inline)) { return 1; } -}; - -// Macros for k20 pin access/definition -#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) -#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) - -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \ - template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } }; -#define _FL_IO(L,C) _RD32(GPIO ## L ## _PDOR); _RD32(GPIO ## L ## _PSOR); _RD32(GPIO ## L ## _PCOR); _RD32(GPIO ## L ## _PTOR); _RD32(GPIO ## L ## _PDIR); _RD32(GPIO ## L ## _PDDR); _FL_DEFINE_PORT3(L,C,_R(GPIO ## L ## _PDOR)); - -#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \ - _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; \ - template<> class FastPinBB<PIN> : public _ARMPIN_BITBAND<PIN, BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \ - _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; - -_FL_IO(A,0); _FL_IO(B,1); _FL_IO(C,2); _FL_IO(D,3); _FL_IO(E,4); - -// Actual pin definitions -#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) - -#define MAX_PIN 63 -_FL_DEFPIN( 0, 16, B); _FL_DEFPIN( 1, 17, B); _FL_DEFPIN( 2, 0, D); _FL_DEFPIN( 3, 12, A); -_FL_DEFPIN( 4, 13, A); _FL_DEFPIN( 5, 7, D); _FL_DEFPIN( 6, 4, D); _FL_DEFPIN( 7, 2, D); -_FL_DEFPIN( 8, 3, D); _FL_DEFPIN( 9, 3, C); _FL_DEFPIN(10, 4, C); _FL_DEFPIN(11, 6, C); -_FL_DEFPIN(12, 7, C); _FL_DEFPIN(13, 5, C); _FL_DEFPIN(14, 1, D); _FL_DEFPIN(15, 0, C); -_FL_DEFPIN(16, 0, B); _FL_DEFPIN(17, 1, B); _FL_DEFPIN(18, 3, B); _FL_DEFPIN(19, 2, B); -_FL_DEFPIN(20, 5, D); _FL_DEFPIN(21, 6, D); _FL_DEFPIN(22, 1, C); _FL_DEFPIN(23, 2, C); -_FL_DEFPIN(24, 26, E); _FL_DEFPIN(25, 5, A); _FL_DEFPIN(26, 14, A); _FL_DEFPIN(27, 15, A); -_FL_DEFPIN(28, 16, A); _FL_DEFPIN(29, 18, B); _FL_DEFPIN(30, 19, B); _FL_DEFPIN(31, 10, B); -_FL_DEFPIN(32, 11, B); _FL_DEFPIN(33, 24, E); _FL_DEFPIN(34, 25, E); _FL_DEFPIN(35, 8, C); -_FL_DEFPIN(36, 9, C); _FL_DEFPIN(37, 10, C); _FL_DEFPIN(38, 11, C); _FL_DEFPIN(39, 17, A); -_FL_DEFPIN(40, 28, A); _FL_DEFPIN(41, 29, A); _FL_DEFPIN(42, 26, A); _FL_DEFPIN(43, 20, B); -_FL_DEFPIN(44, 22, B); _FL_DEFPIN(45, 23, B); _FL_DEFPIN(46, 21, B); _FL_DEFPIN(47, 8, D); -_FL_DEFPIN(48, 9, D); _FL_DEFPIN(49, 4, B); _FL_DEFPIN(50, 5, B); _FL_DEFPIN(51, 14, D); -_FL_DEFPIN(52, 13, D); _FL_DEFPIN(53, 12, D); _FL_DEFPIN(54, 15, D); _FL_DEFPIN(55, 11, D); -_FL_DEFPIN(56, 10, E); _FL_DEFPIN(57, 11, E); _FL_DEFPIN(58, 0, E); _FL_DEFPIN(59, 1, E); -_FL_DEFPIN(60, 2, E); _FL_DEFPIN(61, 3, E); _FL_DEFPIN(62, 4, E); _FL_DEFPIN(63, 5, E); - - - -#define SPI_DATA 11 -#define SPI_CLOCK 13 - -#define SPI2_DATA 7 -#define SPI2_CLOCK 14 - -#define FASTLED_TEENSY3 -#define ARM_HARDWARE_SPI -#define HAS_HARDWARE_PIN_SUPPORT -#endif - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - -#endif // __INC_FASTPIN_ARM_K66 diff --git a/FastLED/src/platforms/arm/k66/fastspi_arm_k66.h b/FastLED/src/platforms/arm/k66/fastspi_arm_k66.h deleted file mode 100644 index f990741b4f4d8685c83ad87ffa865748cfee4d14..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k66/fastspi_arm_k66.h +++ /dev/null @@ -1,470 +0,0 @@ -#ifndef __INC_FASTSPI_ARM_H -#define __INC_FASTSPI_ARM_H - -// -// copied from k20 code -// changed SPI1 define to KINETISK_SPI1 -// TODO: add third alternative MOSI pin (28) and CLOCK pin (27) -// TODO: add alternative pins for SPI1 -// TODO: add SPI2 output -// - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) - -// Version 1.20 renamed SPI_t to KINETISK_SPI_t -#if TEENSYDUINO >= 120 -#define SPI_t KINETISK_SPI_t -#endif - -#ifndef KINETISK_SPI0 -#define KINETISK_SPI0 SPI0 -#endif - -#ifndef SPI_PUSHR_CONT -#define SPI_PUSHR_CONT SPIX.PUSHR_CONT -#define SPI_PUSHR_CTAS(X) SPIX.PUSHR_CTAS(X) -#define SPI_PUSHR_EOQ SPIX.PUSHR_EOQ -#define SPI_PUSHR_CTCNT SPIX.PUSHR_CTCNT -#define SPI_PUSHR_PCS(X) SPIX.PUSHR_PCS(X) -#endif - -// Template function that, on compilation, expands to a constant representing the highest bit set in a byte. Right now, -// if no bits are set (value is 0), it returns 0, which is also the value returned if the lowest bit is the only bit -// set (the zero-th bit). Unclear if I will want this to change at some point. -template<int VAL, int BIT> class BitWork { -public: - static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork<VAL, BIT-1>::highestBit(); } -}; - -template<int VAL> class BitWork<VAL, 0> { -public: - static int highestBit() __attribute__((always_inline)) { return 0; } -}; - -#define MAX(A, B) (( (A) > (B) ) ? (A) : (B)) - -#define USE_CONT 0 -// intra-frame backup data -struct SPIState { - uint32_t _ctar0,_ctar1; - uint32_t pins[4]; -}; - -// extern SPIState gState; - - -// Templated function to translate a clock divider value into the prescalar, scalar, and clock doubling setting for the world. -template <int VAL> void getScalars(uint32_t & preScalar, uint32_t & scalar, uint32_t & dbl) { - switch(VAL) { - // Handle the dbl clock cases - case 0: case 1: - case 2: preScalar = 0; scalar = 0; dbl = 1; break; - case 3: preScalar = 1; scalar = 0; dbl = 1; break; - case 5: preScalar = 2; scalar = 0; dbl = 1; break; - case 7: preScalar = 3; scalar = 0; dbl = 1; break; - - // Handle the scalar value 6 cases (since it's not a power of two, it won't get caught - // below) - case 9: preScalar = 1; scalar = 2; dbl = 1; break; - case 18: case 19: preScalar = 1; scalar = 2; dbl = 0; break; - - case 15: preScalar = 2; scalar = 2; dbl = 1; break; - case 30: case 31: preScalar = 2; scalar = 2; dbl = 0; break; - - case 21: case 22: case 23: preScalar = 3; scalar = 2; dbl = 1; break; - case 42: case 43: case 44: case 45: case 46: case 47: preScalar = 3; scalar = 2; dbl = 0; break; - default: { - int p2 = BitWork<VAL/2, 15>::highestBit(); - int p3 = BitWork<VAL/3, 15>::highestBit(); - int p5 = BitWork<VAL/5, 15>::highestBit(); - int p7 = BitWork<VAL/7, 15>::highestBit(); - - int w2 = 2 * (1 << p2); - int w3 = (VAL/3) > 0 ? 3 * (1 << p3) : 0; - int w5 = (VAL/5) > 0 ? 5 * (1 << p5) : 0; - int w7 = (VAL/7) > 0 ? 7 * (1 << p7) : 0; - - int maxval = MAX(MAX(w2, w3), MAX(w5, w7)); - - if(w2 == maxval) { preScalar = 0; scalar = p2; } - else if(w3 == maxval) { preScalar = 1; scalar = p3; } - else if(w5 == maxval) { preScalar = 2; scalar = p5; } - else if(w7 == maxval) { preScalar = 3; scalar = p7; } - - dbl = 0; - if(scalar == 0) { dbl = 1; } - else if(scalar < 3) { --scalar; } - } - } - return; -} - -#define SPIX (*(SPI_t*)pSPIX) - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER, uint32_t pSPIX> -class ARMHardwareSPIOutput { - Selectable *m_pSelect; - SPIState gState; - - // Borrowed from the teensy3 SPSR emulation code -- note, enabling pin 7 disables pin 11 (and vice versa), - // and likewise enabling pin 14 disables pin 13 (and vice versa) - inline void enable_pins(void) __attribute__((always_inline)) { - //serial_print("enable_pins\n"); - switch(_DATA_PIN) { - case 7: - CORE_PIN7_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - break; - case 11: - CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - break; - } - - switch(_CLOCK_PIN) { - case 13: - CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - break; - case 14: - CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - break; - } - } - - // Borrowed from the teensy3 SPSR emulation code. We disable the pins that we're using, and restore the state on the pins that we aren't using - inline void disable_pins(void) __attribute__((always_inline)) { - switch(_DATA_PIN) { - case 7: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN11_CONFIG = gState.pins[1]; break; - case 11: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN7_CONFIG = gState.pins[0]; break; - } - - switch(_CLOCK_PIN) { - case 13: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN14_CONFIG = gState.pins[3]; break; - case 14: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN13_CONFIG = gState.pins[2]; break; - } - } - - static inline void update_ctars(uint32_t ctar0, uint32_t ctar1) __attribute__((always_inline)) { - if(SPIX.CTAR0 == ctar0 && SPIX.CTAR1 == ctar1) return; - uint32_t mcr = SPIX.MCR; - if(mcr & SPI_MCR_MDIS) { - SPIX.CTAR0 = ctar0; - SPIX.CTAR1 = ctar1; - } else { - SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPIX.CTAR0 = ctar0; - SPIX.CTAR1 = ctar1; - SPIX.MCR = mcr; - } - } - - static inline void update_ctar0(uint32_t ctar) __attribute__((always_inline)) { - if (SPIX.CTAR0 == ctar) return; - uint32_t mcr = SPIX.MCR; - if (mcr & SPI_MCR_MDIS) { - SPIX.CTAR0 = ctar; - } else { - SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPIX.CTAR0 = ctar; - - SPIX.MCR = mcr; - } - } - - static inline void update_ctar1(uint32_t ctar) __attribute__((always_inline)) { - if (SPIX.CTAR1 == ctar) return; - uint32_t mcr = SPIX.MCR; - if (mcr & SPI_MCR_MDIS) { - SPIX.CTAR1 = ctar; - } else { - SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPIX.CTAR1 = ctar; - SPIX.MCR = mcr; - - } - } - - void setSPIRate() { - // Configure CTAR0, defaulting to 8 bits and CTAR1, defaulting to 16 bits - uint32_t _PBR = 0; - uint32_t _BR = 0; - uint32_t _CSSCK = 0; - uint32_t _DBR = 0; - - // if(_SPI_CLOCK_DIVIDER >= 256) { _PBR = 0; _BR = _CSSCK = 7; _DBR = 0; } // osc/256 - // else if(_SPI_CLOCK_DIVIDER >= 128) { _PBR = 0; _BR = _CSSCK = 6; _DBR = 0; } // osc/128 - // else if(_SPI_CLOCK_DIVIDER >= 64) { _PBR = 0; _BR = _CSSCK = 5; _DBR = 0; } // osc/64 - // else if(_SPI_CLOCK_DIVIDER >= 32) { _PBR = 0; _BR = _CSSCK = 4; _DBR = 0; } // osc/32 - // else if(_SPI_CLOCK_DIVIDER >= 16) { _PBR = 0; _BR = _CSSCK = 3; _DBR = 0; } // osc/16 - // else if(_SPI_CLOCK_DIVIDER >= 8) { _PBR = 0; _BR = _CSSCK = 1; _DBR = 0; } // osc/8 - // else if(_SPI_CLOCK_DIVIDER >= 7) { _PBR = 3; _BR = _CSSCK = 0; _DBR = 1; } // osc/7 - // else if(_SPI_CLOCK_DIVIDER >= 5) { _PBR = 2; _BR = _CSSCK = 0; _DBR = 1; } // osc/5 - // else if(_SPI_CLOCK_DIVIDER >= 4) { _PBR = 0; _BR = _CSSCK = 0; _DBR = 0; } // osc/4 - // else if(_SPI_CLOCK_DIVIDER >= 3) { _PBR = 1; _BR = _CSSCK = 0; _DBR = 1; } // osc/3 - // else { _PBR = 0; _BR = _CSSCK = 0; _DBR = 1; } // osc/2 - - getScalars<_SPI_CLOCK_DIVIDER>(_PBR, _BR, _DBR); - _CSSCK = _BR; - - uint32_t ctar0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(_PBR) | SPI_CTAR_BR(_BR) | SPI_CTAR_CSSCK(_CSSCK); - uint32_t ctar1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(_PBR) | SPI_CTAR_BR(_BR) | SPI_CTAR_CSSCK(_CSSCK); - - #if USE_CONT == 1 - ctar0 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL; - ctar1 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL; - #endif - - if(_DBR) { - ctar0 |= SPI_CTAR_DBR; - ctar1 |= SPI_CTAR_DBR; - } - - update_ctars(ctar0,ctar1); - } - - void inline save_spi_state() __attribute__ ((always_inline)) { - // save ctar data - gState._ctar0 = SPIX.CTAR0; - gState._ctar1 = SPIX.CTAR1; - - // save data for the not-us pins - gState.pins[0] = CORE_PIN7_CONFIG; - gState.pins[1] = CORE_PIN11_CONFIG; - gState.pins[2] = CORE_PIN13_CONFIG; - gState.pins[3] = CORE_PIN14_CONFIG; - } - - void inline restore_spi_state() __attribute__ ((always_inline)) { - // restore ctar data - update_ctars(gState._ctar0,gState._ctar1); - - // restore data for the not-us pins (not necessary because disable_pins will do this) - // CORE_PIN7_CONFIG = gState.pins[0]; - // CORE_PIN11_CONFIG = gState.pins[1]; - // CORE_PIN13_CONFIG = gState.pins[2]; - // CORE_PIN14_CONFIG = gState.pins[3]; - } - -public: - ARMHardwareSPIOutput() { m_pSelect = NULL; } - ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - - void init() { - // set the pins to output - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); - - // Enable SPI0 clock - uint32_t sim6 = SIM_SCGC6; - if((SPI_t*)pSPIX == &KINETISK_SPI0) { - if (!(sim6 & SIM_SCGC6_SPI0)) { - //serial_print("init1\n"); - SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0; - SPIX.CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1); - } - } else if((SPI_t*)pSPIX == &KINETISK_SPI1) { - if (!(sim6 & SIM_SCGC6_SPI1)) { - //serial_print("init1\n"); - SIM_SCGC6 = sim6 | SIM_SCGC6_SPI1; - SPIX.CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1); - } - } - - // Configure SPI as the master and enable - SPIX.MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE); - SPIX.MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); - - // pin/spi configuration happens on select - } - - static void waitFully() __attribute__((always_inline)) { - // Wait for the last byte to get shifted into the register - bool empty = false; - - do { - cli(); - if ((SPIX.SR & 0xF000) > 0) { - // reset the TCF flag - SPIX.SR |= SPI_SR_TCF; - } else { - empty = true; - } - sei(); - } while (!empty); - - // wait for the TCF flag to get set - while (!(SPIX.SR & SPI_SR_TCF)); - SPIX.SR |= (SPI_SR_TCF | SPI_SR_EOQF); - } - - static bool needwait() __attribute__((always_inline)) { return (SPIX.SR & 0x4000); } - static void wait() __attribute__((always_inline)) { while( (SPIX.SR & 0x4000) ); } - static void wait1() __attribute__((always_inline)) { while( (SPIX.SR & 0xF000) >= 0x2000); } - - enum ECont { CONT, NOCONT }; - enum EWait { PRE, POST, NONE }; - enum ELast { NOTLAST, LAST }; - - #if USE_CONT == 1 - #define CM CONT - #else - #define CM NOCONT - #endif - #define WM PRE - - template<ECont CONT_STATE, EWait WAIT_STATE, ELast LAST_STATE> class Write { - public: - static void writeWord(uint16_t w) __attribute__((always_inline)) { - if(WAIT_STATE == PRE) { wait(); } - SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | - ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | - SPI_PUSHR_CTAS(1) | (w & 0xFFFF); - SPIX.SR |= SPI_SR_TCF; - if(WAIT_STATE == POST) { wait(); } - } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { - if(WAIT_STATE == PRE) { wait(); } - SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | - ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | - SPI_PUSHR_CTAS(0) | (b & 0xFF); - SPIX.SR |= SPI_SR_TCF; - if(WAIT_STATE == POST) { wait(); } - } - }; - - static void writeWord(uint16_t w) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF;} - static void writeWordNoWait(uint16_t w) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF;} - - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;} - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF);SPIX.SR |= SPI_SR_TCF; wait(); } - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;} - - static void writeWordCont(uint16_t w) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF;} - static void writeWordContNoWait(uint16_t w) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF;} - - static void writeByteCont(uint8_t b) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;} - static void writeByteContPostWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;wait(); } - static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;} - - // not the most efficient mechanism in the world - but should be enough for sm16716 and friends - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - uint32_t ctar1_save = SPIX.CTAR1; - - // Clear out the FMSZ bits, reset them for 1 bit transferd for the start bit - uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(0); - update_ctar1(ctar1); - - writeWord( (b & (1 << BIT)) != 0); - - update_ctar1(ctar1_save); - } - - void inline select() __attribute__((always_inline)) { - save_spi_state(); - if(m_pSelect != NULL) { m_pSelect->select(); } - setSPIRate(); - enable_pins(); - } - - void inline release() __attribute__((always_inline)) { - disable_pins(); - if(m_pSelect != NULL) { m_pSelect->release(); } - restore_spi_state(); - } - - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { Write<CM, WM, NOTLAST>::writeByte(value); } - } - - void writeBytesValue(uint8_t value, int len) { - select(); - while(len--) { - writeByte(value); - } - waitFully(); - release(); - } - - // Write a block of n uint8_ts out - template <class D> void writeBytes(register uint8_t *data, int len) { - uint8_t *end = data + len; - select(); - // could be optimized to write 16bit words out instead of 8bit bytes - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - int len = pixels.mLen; - - // Setup the pixel controller - if((FLAGS & FLAG_START_BIT) == 0) { - //If no start bit stupiditiy, write out as many 16-bit blocks as we can - while(pixels.has(2)) { - // Load and write out the first two bytes - if(WM == NONE) { wait1(); } - Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1())); - - // Load and write out the next two bytes (step dithering, advance data in between since we - // cross pixels here) - Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale2()) << 8 | D::adjust(pixels.stepAdvanceAndLoadAndScale0())); - - // Load and write out the next two bytes - Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale1()) << 8 | D::adjust(pixels.loadAndScale2())); - pixels.stepDithering(); - pixels.advanceData(); - } - - if(pixels.has(1)) { - if(WM == NONE) { wait1(); } - // write out the rest as alternating 16/8-bit blocks (likely to be just one) - Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1())); - Write<CM, WM, NOTLAST>::writeByte(D::adjust(pixels.loadAndScale2())); - } - - D::postBlock(len); - waitFully(); - } else if(FLAGS & FLAG_START_BIT) { - uint32_t ctar1_save = SPIX.CTAR1; - - // Clear out the FMSZ bits, reset them for 9 bits transferd for the start bit - uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(8); - update_ctar1(ctar1); - - while(pixels.has(1)) { - writeWord( 0x100 | D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - waitFully(); - - // restore ctar1 - update_ctar1(ctar1_save); - } - release(); - } -}; -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/k66/led_sysdefs_arm_k66.h b/FastLED/src/platforms/arm/k66/led_sysdefs_arm_k66.h deleted file mode 100644 index 0b0c701c53a103aea05b3036239d1a61856239c0..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/k66/led_sysdefs_arm_k66.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_ARM_K66_H -#define __INC_LED_SYSDEFS_ARM_K66_H - -#define FASTLED_TEENSY3 -#define FASTLED_ARM - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -#if (F_CPU == 192000000) -#define CLK_DBL 1 -#endif - -// Get some system include files -#include <avr/io.h> -#include <avr/interrupt.h> // for cli/se definitions - -// Define the register types -#if defined(ARDUINO) // && ARDUINO < 150 -typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ -typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ -#endif - -extern volatile uint32_t systick_millis_count; -# define MS_COUNTER systick_millis_count - - -// Default to using PROGMEM, since TEENSY3 provides it -// even though all it does is ignore it. Just being -// conservative here in case TEENSY3 changes. -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 1 -#endif - - -#endif diff --git a/FastLED/src/platforms/arm/kl26/clockless_arm_kl26.h b/FastLED/src/platforms/arm/kl26/clockless_arm_kl26.h deleted file mode 100644 index 29a61fbaaecfdc35a1810084f2af8694d7045e55..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/kl26/clockless_arm_kl26.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_KL26 -#define __INC_CLOCKLESS_ARM_KL26 - -#include "../common/m0clockless.h" -FASTLED_NAMESPACE_BEGIN -#define FASTLED_HAS_CLOCKLESS 1 - -template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPinBB<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; -public: - virtual void init() { - FastPinBB<DATA_PIN>::setOutput(); - mPinMask = FastPinBB<DATA_PIN>::mask(); - mPort = FastPinBB<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - cli(); - uint32_t clocks = showRGBInternal(pixels); - if(!clocks) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - clocks = showRGBInternal(pixels); - } - long microsTaken = CLKS_TO_MICROS(clocks * ((T1 + T2 + T3) * 24)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - struct M0ClocklessData data; - data.d[0] = pixels.d[0]; - data.d[1] = pixels.d[1]; - data.d[2] = pixels.d[2]; - data.s[0] = pixels.mScale[0]; - data.s[1] = pixels.mScale[1]; - data.s[2] = pixels.mScale[2]; - data.e[0] = pixels.e[0]; - data.e[1] = pixels.e[1]; - data.e[2] = pixels.e[2]; - data.adj = pixels.mAdvance; - - typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port(); - return showLedData<4,8,T1,T2,T3,RGB_ORDER, WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data); - // return 0; // 0x00FFFFFF - _VAL; - } - - -}; - -FASTLED_NAMESPACE_END - - -#endif // __INC_CLOCKLESS_ARM_KL26 diff --git a/FastLED/src/platforms/arm/kl26/fastled_arm_kl26.h b/FastLED/src/platforms/arm/kl26/fastled_arm_kl26.h deleted file mode 100644 index a0ef0ff752cffe238cd624701a276b717c74f31a..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/kl26/fastled_arm_kl26.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __INC_FASTLED_ARM_KL26_H -#define __INC_FASTLED_ARM_KL26_H - -// Include the k20 headers -#include "fastpin_arm_kl26.h" -#include "fastspi_arm_kl26.h" -#include "clockless_arm_kl26.h" -#include "../k20/ws2812serial_controller.h" - -#endif diff --git a/FastLED/src/platforms/arm/kl26/fastpin_arm_kl26.h b/FastLED/src/platforms/arm/kl26/fastpin_arm_kl26.h deleted file mode 100644 index 8b3cbdfef84554f32a4ce797ed33a6316b4a3408..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/kl26/fastpin_arm_kl26.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef __FASTPIN_ARM_KL26_H -#define __FASTPIN_ARM_KL26_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be sloightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - - -/// Template definition for teensy LC style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found -/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. -/// The registers are data output, set output, clear output, toggle output, input, and direction -template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { _PSOR::r() = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { _PTOR::r() = _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_PSOR::r(); } - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_PCOR::r(); } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - -// Macros for kl26 pin access/definition -#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) -#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) - -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \ -template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } }; -#define _FL_IO(L,C) _RD32(FGPIO ## L ## _PDOR); _RD32(FGPIO ## L ## _PSOR); _RD32(FGPIO ## L ## _PCOR); _RD32(GPIO ## L ## _PTOR); _RD32(FGPIO ## L ## _PDIR); _RD32(FGPIO ## L ## _PDDR); _FL_DEFINE_PORT3(L,C,_R(FGPIO ## L ## _PDOR)); - -#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << BIT, _R(FGPIO ## L ## _PDOR), _R(FGPIO ## L ## _PSOR), _R(FGPIO ## L ## _PCOR), \ -_R(GPIO ## L ## _PTOR), _R(FGPIO ## L ## _PDIR), _R(FGPIO ## L ## _PDDR)> {}; \ -/* template<> class FastPinBB<PIN> : public _ARMPIN_BITBAND<PIN, BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \ -_R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; */ - -_FL_IO(A,0); _FL_IO(B,1); _FL_IO(C,2); _FL_IO(D,3); _FL_IO(E,4); - -// Actual pin definitions -#if defined(FASTLED_TEENSYLC) && defined(CORE_TEENSY) - -#define MAX_PIN 26 -_FL_DEFPIN(0, 16, B); _FL_DEFPIN(1, 17, B); _FL_DEFPIN(2, 0, D); _FL_DEFPIN(3, 1, A); -_FL_DEFPIN(4, 2, A); _FL_DEFPIN(5, 7, D); _FL_DEFPIN(6, 4, D); _FL_DEFPIN(7, 2, D); -_FL_DEFPIN(8, 3, D); _FL_DEFPIN(9, 3, C); _FL_DEFPIN(10, 4, C); _FL_DEFPIN(11, 6, C); -_FL_DEFPIN(12, 7, C); _FL_DEFPIN(13, 5, C); _FL_DEFPIN(14, 1, D); _FL_DEFPIN(15, 0, C); -_FL_DEFPIN(16, 0, B); _FL_DEFPIN(17, 1, B); _FL_DEFPIN(18, 3, B); _FL_DEFPIN(19, 2, B); -_FL_DEFPIN(20, 5, D); _FL_DEFPIN(21, 6, D); _FL_DEFPIN(22, 1, C); _FL_DEFPIN(23, 2, C); -_FL_DEFPIN(24, 20, E); _FL_DEFPIN(25, 21, E); _FL_DEFPIN(26, 30, E); - -#define SPI_DATA 11 -#define SPI_CLOCK 13 -// #define SPI1 (*(SPI_t *)0x4002D000) - -#define SPI2_DATA 0 -#define SPI2_CLOCK 20 - -#define HAS_HARDWARE_PIN_SUPPORT -#endif - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - -#endif // __INC_FASTPIN_ARM_K20 diff --git a/FastLED/src/platforms/arm/kl26/fastspi_arm_kl26.h b/FastLED/src/platforms/arm/kl26/fastspi_arm_kl26.h deleted file mode 100644 index b1e766774d160491241d6eeedf9559ef13f86d5f..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/kl26/fastspi_arm_kl26.h +++ /dev/null @@ -1,252 +0,0 @@ -#ifndef __INC_FASTSPI_ARM_KL26_H -#define __INC_FASTSPI_ARM_KL26_h - -FASTLED_NAMESPACE_BEGIN - -template <int VAL> void getScalars(uint8_t & sppr, uint8_t & spr) { - if(VAL > 4096) { sppr=7; spr=8; } - else if(VAL > 3584) { sppr=6; spr=8; } - else if(VAL > 3072) { sppr=5; spr=8; } - else if(VAL > 2560) { sppr=4; spr=8; } - else if(VAL > 2048) { sppr=7; spr=7; } - else if(VAL > 2048) { sppr=3; spr=8; } - else if(VAL > 1792) { sppr=6; spr=7; } - else if(VAL > 1536) { sppr=5; spr=7; } - else if(VAL > 1536) { sppr=2; spr=8; } - else if(VAL > 1280) { sppr=4; spr=7; } - else if(VAL > 1024) { sppr=7; spr=6; } - else if(VAL > 1024) { sppr=3; spr=7; } - else if(VAL > 1024) { sppr=1; spr=8; } - else if(VAL > 896) { sppr=6; spr=6; } - else if(VAL > 768) { sppr=5; spr=6; } - else if(VAL > 768) { sppr=2; spr=7; } - else if(VAL > 640) { sppr=4; spr=6; } - else if(VAL > 512) { sppr=7; spr=5; } - else if(VAL > 512) { sppr=3; spr=6; } - else if(VAL > 512) { sppr=1; spr=7; } - else if(VAL > 512) { sppr=0; spr=8; } - else if(VAL > 448) { sppr=6; spr=5; } - else if(VAL > 384) { sppr=5; spr=5; } - else if(VAL > 384) { sppr=2; spr=6; } - else if(VAL > 320) { sppr=4; spr=5; } - else if(VAL > 256) { sppr=7; spr=4; } - else if(VAL > 256) { sppr=3; spr=5; } - else if(VAL > 256) { sppr=1; spr=6; } - else if(VAL > 256) { sppr=0; spr=7; } - else if(VAL > 224) { sppr=6; spr=4; } - else if(VAL > 192) { sppr=5; spr=4; } - else if(VAL > 192) { sppr=2; spr=5; } - else if(VAL > 160) { sppr=4; spr=4; } - else if(VAL > 128) { sppr=7; spr=3; } - else if(VAL > 128) { sppr=3; spr=4; } - else if(VAL > 128) { sppr=1; spr=5; } - else if(VAL > 128) { sppr=0; spr=6; } - else if(VAL > 112) { sppr=6; spr=3; } - else if(VAL > 96) { sppr=5; spr=3; } - else if(VAL > 96) { sppr=2; spr=4; } - else if(VAL > 80) { sppr=4; spr=3; } - else if(VAL > 64) { sppr=7; spr=2; } - else if(VAL > 64) { sppr=3; spr=3; } - else if(VAL > 64) { sppr=1; spr=4; } - else if(VAL > 64) { sppr=0; spr=5; } - else if(VAL > 56) { sppr=6; spr=2; } - else if(VAL > 48) { sppr=5; spr=2; } - else if(VAL > 48) { sppr=2; spr=3; } - else if(VAL > 40) { sppr=4; spr=2; } - else if(VAL > 32) { sppr=7; spr=1; } - else if(VAL > 32) { sppr=3; spr=2; } - else if(VAL > 32) { sppr=1; spr=3; } - else if(VAL > 32) { sppr=0; spr=4; } - else if(VAL > 28) { sppr=6; spr=1; } - else if(VAL > 24) { sppr=5; spr=1; } - else if(VAL > 24) { sppr=2; spr=2; } - else if(VAL > 20) { sppr=4; spr=1; } - else if(VAL > 16) { sppr=7; spr=0; } - else if(VAL > 16) { sppr=3; spr=1; } - else if(VAL > 16) { sppr=1; spr=2; } - else if(VAL > 16) { sppr=0; spr=3; } - else if(VAL > 14) { sppr=6; spr=0; } - else if(VAL > 12) { sppr=5; spr=0; } - else if(VAL > 12) { sppr=2; spr=1; } - else if(VAL > 10) { sppr=4; spr=0; } - else if(VAL > 8) { sppr=3; spr=0; } - else if(VAL > 8) { sppr=1; spr=1; } - else if(VAL > 8) { sppr=0; spr=2; } - else if(VAL > 6) { sppr=2; spr=0; } - else if(VAL > 4) { sppr=1; spr=0; } - else if(VAL > 4) { sppr=0; spr=1; } - else /* if(VAL > 2) */ { sppr=0; spr=0; } -} - - -#define SPIX (*(KINETISL_SPI_t*)pSPIX) -#define ARM_HARDWARE_SPI - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER, uint32_t pSPIX> -class ARMHardwareSPIOutput { - Selectable *m_pSelect; - - static inline void enable_pins(void) __attribute__((always_inline)) { - switch(_DATA_PIN) { - case 0: CORE_PIN0_CONFIG = PORT_PCR_MUX(2); break; - case 1: CORE_PIN1_CONFIG = PORT_PCR_MUX(5); break; - case 7: CORE_PIN7_CONFIG = PORT_PCR_MUX(2); break; - case 8: CORE_PIN8_CONFIG = PORT_PCR_MUX(5); break; - case 11: CORE_PIN11_CONFIG = PORT_PCR_MUX(2); break; - case 12: CORE_PIN12_CONFIG = PORT_PCR_MUX(5); break; - case 21: CORE_PIN21_CONFIG = PORT_PCR_MUX(2); break; - } - - switch(_CLOCK_PIN) { - case 13: CORE_PIN13_CONFIG = PORT_PCR_MUX(2); break; - case 14: CORE_PIN14_CONFIG = PORT_PCR_MUX(2); break; - case 20: CORE_PIN20_CONFIG = PORT_PCR_MUX(2); break; - } - } - - static inline void disable_pins(void) __attribute((always_inline)) { - switch(_DATA_PIN) { - case 0: CORE_PIN0_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - case 1: CORE_PIN1_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - case 7: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - case 8: CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - case 11: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - case 12: CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - case 21: CORE_PIN21_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - } - - switch(_CLOCK_PIN) { - case 13: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - case 14: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - case 20: CORE_PIN20_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; - } - } - - void setSPIRate() { - uint8_t sppr, spr; - getScalars<_SPI_CLOCK_DIVIDER>(sppr, spr); - - // Set the speed - SPIX.BR = SPI_BR_SPPR(sppr) | SPI_BR_SPR(spr); - - // Also, force 8 bit transfers (don't want to juggle 8/16 since that flushes the world) - SPIX.C2 = 0; - SPIX.C1 |= SPI_C1_SPE; - } - -public: - ARMHardwareSPIOutput() { m_pSelect = NULL; } - ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - - // set the object representing the selectable - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - // initialize the SPI subssytem - void init() { - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); - - // Enable the SPI clocks - uint32_t sim4 = SIM_SCGC4; - if ((pSPIX == 0x40076000) && !(sim4 & SIM_SCGC4_SPI0)) { - SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0; - } - - if ( (pSPIX == 0x40077000) && !(sim4 & SIM_SCGC4_SPI1)) { - SIM_SCGC4 = sim4 | SIM_SCGC4_SPI1; - } - - SPIX.C1 = SPI_C1_MSTR | SPI_C1_SPE; - SPIX.C2 = 0; - SPIX.BR = SPI_BR_SPPR(1) | SPI_BR_SPR(0); - } - - // latch the CS select - void inline select() __attribute__((always_inline)) { - if(m_pSelect != NULL) { m_pSelect->select(); } - setSPIRate(); - enable_pins(); - } - - - // release the CS select - void inline release() __attribute__((always_inline)) { - disable_pins(); - if(m_pSelect != NULL) { m_pSelect->release(); } - } - - // Wait for the world to be clear - static void wait() __attribute__((always_inline)) { while(!(SPIX.S & SPI_S_SPTEF)); } - - // wait until all queued up data has been written - void waitFully() { wait(); } - - // not the most efficient mechanism in the world - but should be enough for sm16716 and friends - template <uint8_t BIT> inline static void writeBit(uint8_t b) { /* TODO */ } - - // write a byte out via SPI (returns immediately on writing register) - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPIX.DL = b; } - // write a word out via SPI (returns immediately on writing register) - static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w & 0xFF); } - - // A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes) - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { writeByte(value); } - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytesValue(uint8_t value, int len) { - setSPIRate(); - select(); - while(len--) { - writeByte(value); - } - waitFully(); - release(); - } - - // A full cycle of writing a raw block of data out, including select, release, and waiting - template <class D> void writeBytes(register uint8_t *data, int len) { - setSPIRate(); - uint8_t *end = data + len; - select(); - // could be optimized to write 16bit words out instead of 8bit bytes - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - int len = pixels.mLen; - - select(); - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - } else { - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - } - - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - release(); - } - -}; - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/kl26/led_sysdefs_arm_kl26.h b/FastLED/src/platforms/arm/kl26/led_sysdefs_arm_kl26.h deleted file mode 100644 index 575e63999222964481f303cfb3fae518cc786b2a..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/kl26/led_sysdefs_arm_kl26.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_ARM_KL26_H -#define __INC_LED_SYSDEFS_ARM_KL26_H - -#define FASTLED_TEENSYLC -#define FASTLED_ARM -#define FASTLED_ARM_M0_PLUS - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -#define FASTLED_SPI_BYTE_ONLY - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -// #define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -#if (F_CPU == 96000000) -#define CLK_DBL 1 -#endif - -// Get some system include files -#include <avr/io.h> -#include <avr/interrupt.h> // for cli/se definitions - -// Define the register types -#if defined(ARDUINO) // && ARDUINO < 150 -typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ -typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ -#endif - -extern volatile uint32_t systick_millis_count; -# define MS_COUNTER systick_millis_count - -// Default to using PROGMEM since TEENSYLC provides it -// even though all it does is ignore it. Just being -// conservative here in case TEENSYLC changes. -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 1 -#endif - -#endif diff --git a/FastLED/src/platforms/arm/mxrt1062/block_clockless_arm_mxrt1062.h b/FastLED/src/platforms/arm/mxrt1062/block_clockless_arm_mxrt1062.h deleted file mode 100644 index a7bcddf040834de059df1c292a964a9cdac82e4b..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/mxrt1062/block_clockless_arm_mxrt1062.h +++ /dev/null @@ -1,212 +0,0 @@ -#ifndef __INC_BLOCK_CLOCKLESS_ARM_MXRT1062_H -#define __INC_BLOCK_CLOCKLESS_ARM_MXRT1062_H - -FASTLED_NAMESPACE_BEGIN - -// Definition for a single channel clockless controller for the teensy4 -// See clockless.h for detailed info on how the template parameters are used. -#if defined(FASTLED_TEENSY4) - -#define __FL_T4_MASK ((1<<(LANES))-1) -template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class FlexibleInlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, __FL_T4_MASK> { - uint8_t m_bitOffsets[16]; - uint8_t m_nActualLanes; - uint8_t m_nLowBit; - uint8_t m_nHighBit; - uint32_t m_nWriteMask; - uint8_t m_nOutBlocks; - uint32_t m_offsets[3]; - CMinWait<WAIT_TIME> mWait; - -public: - virtual int size() { return CLEDController::size() * m_nActualLanes; } - - // For each pin, if we've hit our lane count, break, otherwise set the pin to output, - // store the bit offset in our offset array, add this pin to the write mask, and if this - // pin ends a block sequence, then break out of the switch as well - #define _BLOCK_PIN(P) case P: { \ - if(m_nActualLanes == LANES) break; \ - FastPin<P>::setOutput(); \ - m_bitOffsets[m_nActualLanes++] = FastPin<P>::pinbit(); \ - m_nWriteMask |= FastPin<P>::mask(); \ - if( P == 27 || P == 7 || P == 30) break; \ - } - - virtual void init() { - // pre-initialize - memset(m_bitOffsets,0,16); - m_nActualLanes = 0; - m_nLowBit = 33; - m_nHighBit = 0; - m_nWriteMask = 0; - - // setup the bits and data tracking for parallel output - switch(FIRST_PIN) { - // GPIO6 block output - _BLOCK_PIN( 1); - _BLOCK_PIN( 0); - _BLOCK_PIN(24); - _BLOCK_PIN(25); - _BLOCK_PIN(19); - _BLOCK_PIN(18); - _BLOCK_PIN(14); - _BLOCK_PIN(15); - _BLOCK_PIN(17); - _BLOCK_PIN(16); - _BLOCK_PIN(22); - _BLOCK_PIN(23); - _BLOCK_PIN(20); - _BLOCK_PIN(21); - _BLOCK_PIN(26); - _BLOCK_PIN(27); - // GPIO7 block output - _BLOCK_PIN(10); - _BLOCK_PIN(12); - _BLOCK_PIN(11); - _BLOCK_PIN(13); - _BLOCK_PIN( 6); - _BLOCK_PIN( 9); - _BLOCK_PIN(32); - _BLOCK_PIN( 8); - _BLOCK_PIN( 7); - // GPIO 37 block output - _BLOCK_PIN(37); - _BLOCK_PIN(36); - _BLOCK_PIN(35); - _BLOCK_PIN(34); - _BLOCK_PIN(39); - _BLOCK_PIN(38); - _BLOCK_PIN(28); - _BLOCK_PIN(31); - _BLOCK_PIN(30); - } - - for(int i = 0; i < m_nActualLanes; ++i) { - if(m_bitOffsets[i] < m_nLowBit) { m_nLowBit = m_bitOffsets[i]; } - if(m_bitOffsets[i] > m_nHighBit) { m_nHighBit = m_bitOffsets[i]; } - } - - m_nOutBlocks = (m_nHighBit + 8)/8; - - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - virtual void showPixels(PixelController<RGB_ORDER, LANES, __FL_T4_MASK> & pixels) { - mWait.wait(); - #if FASTLED_ALLOW_INTERRUPTS == 0 - uint32_t clocks = showRGBInternal(pixels); - // Adjust the timer - long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (1 + (microsTaken / 1000)); - #else - showRGBInternal(pixels); - #endif - mWait.mark(); - } - - typedef union { - uint8_t bytes[32]; - uint8_t bg[4][8]; - uint16_t shorts[16]; - uint32_t raw[8]; - } _outlines; - - - template<int BITS,int PX> __attribute__ ((always_inline)) inline void writeBits(register uint32_t & next_mark, register _outlines & b, PixelController<RGB_ORDER, LANES, __FL_T4_MASK> &pixels) { - _outlines b2; - transpose8x1(b.bg[3], b2.bg[3]); - transpose8x1(b.bg[2], b2.bg[2]); - transpose8x1(b.bg[1], b2.bg[1]); - transpose8x1(b.bg[0], b2.bg[0]); - - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - int x = 0; - for(uint32_t i = 8; i > 0;) { - --i; - while(ARM_DWT_CYCCNT < next_mark); - *FastPin<FIRST_PIN>::sport() = m_nWriteMask; - next_mark = ARM_DWT_CYCCNT + m_offsets[0]; - - uint32_t out = (b2.bg[3][i] << 24) | (b2.bg[2][i] << 16) | (b2.bg[1][i] << 8) | b2.bg[0][i]; - - out = ((~out) & m_nWriteMask); - while((next_mark - ARM_DWT_CYCCNT) > m_offsets[1]); - *FastPin<FIRST_PIN>::cport() = out; - - out = m_nWriteMask; - while((next_mark - ARM_DWT_CYCCNT) > m_offsets[2]); - *FastPin<FIRST_PIN>::cport() = out; - - // Read and store up to two bytes - if (x < m_nActualLanes) { - b.bytes[m_bitOffsets[x]] = pixels.template loadAndScale<PX>(pixels, x, d, scale); - ++x; - if (x < m_nActualLanes) { - b.bytes[m_bitOffsets[x]] = pixels.template loadAndScale<PX>(pixels, x, d, scale); - ++x; - } - } - } - } - - uint32_t showRGBInternal(PixelController<RGB_ORDER,LANES, __FL_T4_MASK> &allpixels) { - allpixels.preStepFirstByteDithering(); - _outlines b0; - uint32_t start = ARM_DWT_CYCCNT; - - for(int i = 0; i < m_nActualLanes; ++i) { - b0.bytes[m_bitOffsets[i]] = allpixels.loadAndScale0(i); - } - - cli(); - - m_offsets[0] = _FASTLED_NS_TO_DWT(T1+T2+T3); - m_offsets[1] = _FASTLED_NS_TO_DWT(T2+T3); - m_offsets[2] = _FASTLED_NS_TO_DWT(T3); - uint32_t wait_off = _FASTLED_NS_TO_DWT((WAIT_TIME-INTERRUPT_THRESHOLD)); - - uint32_t next_mark = ARM_DWT_CYCCNT + m_offsets[0]; - - while(allpixels.has(1)) { - allpixels.stepDithering(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > wait_off) { sei(); return ARM_DWT_CYCCNT - start; } - } - #endif - // Write first byte, read next byte - writeBits<8+XTRA0,1>(next_mark, b0, allpixels); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(next_mark, b0, allpixels); - allpixels.advanceData(); - - // Write third byte - writeBits<8+XTRA0,0>(next_mark, b0, allpixels); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - } - - sei(); - - return ARM_DWT_CYCCNT - start; - } -}; - -template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, int NUM_LANES, EOrder RGB_ORDER=GRB> -class __FIBCC : public FlexibleInlineBlockClocklessController<NUM_LANES,DATA_PIN,CHIPSET<DATA_PIN,RGB_ORDER>::__T1(),CHIPSET<DATA_PIN,RGB_ORDER>::__T2(),CHIPSET<DATA_PIN,RGB_ORDER>::__T3(),RGB_ORDER,CHIPSET<DATA_PIN,RGB_ORDER>::__XTRA0(),CHIPSET<DATA_PIN,RGB_ORDER>::__FLIP(),CHIPSET<DATA_PIN,RGB_ORDER>::__WAIT_TIME()> {}; - -#define __FASTLED_HAS_FIBCC 1 - -#endif //defined(FASTLED_TEENSY4) - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/mxrt1062/clockless_arm_mxrt1062.h b/FastLED/src/platforms/arm/mxrt1062/clockless_arm_mxrt1062.h deleted file mode 100644 index ed3be816c99dca85a9ab26ddd660d4c3e93c57d7..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/mxrt1062/clockless_arm_mxrt1062.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_MXRT1062_H -#define __INC_CLOCKLESS_ARM_MXRT1062_H - -FASTLED_NAMESPACE_BEGIN - -// Definition for a single channel clockless controller for the teensy4 -// See clockless.h for detailed info on how the template parameters are used. -#if defined(FASTLED_TEENSY4) - -#define FASTLED_HAS_CLOCKLESS 1 - -#define _FASTLED_NS_TO_DWT(_NS) (((F_CPU_ACTUAL>>16)*(_NS)) / (1000000000UL>>16)) - -template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - uint32_t off[3]; - -public: - static constexpr int __DATA_PIN() { return DATA_PIN; } - static constexpr int __T1() { return T1; } - static constexpr int __T2() { return T2; } - static constexpr int __T3() { return T3; } - static constexpr EOrder __RGB_ORDER() { return RGB_ORDER; } - static constexpr int __XTRA0() { return XTRA0; } - static constexpr bool __FLIP() { return FLIP; } - static constexpr int __WAIT_TIME() { return WAIT_TIME; } - - virtual void init() { - FastPin<DATA_PIN>::setOutput(); - mPinMask = FastPin<DATA_PIN>::mask(); - mPort = FastPin<DATA_PIN>::port(); - FastPin<DATA_PIN>::lo(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - mWait.mark(); - } - - template<int BITS> __attribute__ ((always_inline)) inline void writeBits(register uint32_t & next_mark, register uint32_t & b) { - for(register uint32_t i = BITS-1; i > 0; --i) { - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + off[0]; - FastPin<DATA_PIN>::hi(); - if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > off[1]); - FastPin<DATA_PIN>::lo(); - } else { - while((next_mark - ARM_DWT_CYCCNT) > off[2]); - FastPin<DATA_PIN>::lo(); - } - b <<= 1; - } - - while(ARM_DWT_CYCCNT < next_mark); - next_mark = ARM_DWT_CYCCNT + off[1]; - FastPin<DATA_PIN>::hi(); - - if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > off[2]); - FastPin<DATA_PIN>::lo(); - } else { - while((next_mark - ARM_DWT_CYCCNT) > off[2]); - FastPin<DATA_PIN>::lo(); - } - } - - uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - uint32_t start = ARM_DWT_CYCCNT; - - // Setup the pixel controller and load/scale the first byte - pixels.preStepFirstByteDithering(); - register uint32_t b = pixels.loadAndScale0(); - - cli(); - - off[0] = _FASTLED_NS_TO_DWT(T1+T2+T3); - off[1] = _FASTLED_NS_TO_DWT(T2+T3); - off[2] = _FASTLED_NS_TO_DWT(T3); - - uint32_t wait_off = _FASTLED_NS_TO_DWT((WAIT_TIME-INTERRUPT_THRESHOLD)); - - uint32_t next_mark = ARM_DWT_CYCCNT + off[0]; - - while(pixels.has(1)) { - pixels.stepDithering(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(ARM_DWT_CYCCNT > next_mark) { - if((ARM_DWT_CYCCNT-next_mark) > wait_off) { sei(); return ARM_DWT_CYCCNT - start; } - } - #endif - // Write first byte, read next byte - writeBits<8+XTRA0>(next_mark, b); - b = pixels.loadAndScale1(); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0>(next_mark, b); - b = pixels.loadAndScale2(); - - // Write third byte, read 1st byte of next pixel - writeBits<8+XTRA0>(next_mark, b); - b = pixels.advanceAndLoadAndScale0(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - - sei(); - return ARM_DWT_CYCCNT - start; - } -}; -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/mxrt1062/fastled_arm_mxrt1062.h b/FastLED/src/platforms/arm/mxrt1062/fastled_arm_mxrt1062.h deleted file mode 100644 index 5098af335ac632afd8a452b455ee7397b6bc4fb2..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/mxrt1062/fastled_arm_mxrt1062.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __INC_FASTLED_ARM_MXRT1062_H -#define __INC_FASTLED_ARM_MXRT1062_H - -#include "fastpin_arm_mxrt1062.h" -#include "fastspi_arm_mxrt1062.h" -#include "../k20/octows2811_controller.h" -#include "../k20/ws2812serial_controller.h" -#include "../k20/smartmatrix_t3.h" -#include "clockless_arm_mxrt1062.h" -#include "block_clockless_arm_mxrt1062.h" - -#endif diff --git a/FastLED/src/platforms/arm/mxrt1062/fastpin_arm_mxrt1062.h b/FastLED/src/platforms/arm/mxrt1062/fastpin_arm_mxrt1062.h deleted file mode 100644 index 8960a8c9c6e229eaf2dcb34e4f9b3f26ab74ecc3..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/mxrt1062/fastpin_arm_mxrt1062.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef __FASTPIN_ARM_MXRT1062_H -#define __FASTPIN_ARM_MXRT1062_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be slightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - -/// Template definition for teensy 4.0 style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. It calls through to pinMode for setting input/output on pins -/// The registers are data output, set output, clear output, toggle output, input, and direction -template<uint8_t PIN, uint32_t _BIT, uint32_t _MASK, typename _GPIO_DR, typename _GPIO_DR_SET, typename _GPIO_DR_CLEAR, typename _GPIO_DR_TOGGLE> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { _GPIO_DR_SET::r() = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { _GPIO_DR_CLEAR::r() = _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { _GPIO_DR::r() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { _GPIO_DR_TOGGLE::r() = _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return _GPIO_DR::r() | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return _GPIO_DR::r() & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_GPIO_DR::r(); } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPIO_DR_SET::r(); } - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPIO_DR_CLEAR::r(); } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } - inline static uint32_t pinbit() __attribute__ ((always_inline)) { return _BIT; } -}; - - -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } }; -#define _FL_IO(L) _RD32(GPIO ## L ## _DR); _RD32(GPIO ## L ## _DR_SET); _RD32(GPIO ## L ## _DR_CLEAR); _RD32(GPIO ## L ## _DR_TOGGLE); _FL_DEFINE_PORT(L, _R(GPIO ## L ## _DR)); - -// From the teensy core - it looks like there's the "default set" of port registers at GPIO1-5 - but then there -// are a mirrored set for GPIO1-4 at GPIO6-9, which in the teensy core is referred to as "fast" - while the pin definitiosn -// at https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=193716&viewfull=1#post193716 -// refer to GPIO1-4, we're going to use GPIO6-9 in the definitions below because the fast registers are what -// the teensy core is using internally -#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, _R(GPIO ## L ## _DR), _R(GPIO ## L ## _DR_SET), _R(GPIO ## L ## _DR_CLEAR), _R(GPIO ## L ## _DR_TOGGLE)> {}; - -#if defined(FASTLED_TEENSY4) && defined(CORE_TEENSY) -_FL_IO(1); _FL_IO(2); _FL_IO(3); _FL_IO(4); _FL_IO(5); -_FL_IO(6); _FL_IO(7); _FL_IO(8); _FL_IO(9); - -#define MAX_PIN 39 -_FL_DEFPIN( 0, 3,6); _FL_DEFPIN( 1, 2,6); _FL_DEFPIN( 2, 4,9); _FL_DEFPIN( 3, 5,9); -_FL_DEFPIN( 4, 6,9); _FL_DEFPIN( 5, 8,9); _FL_DEFPIN( 6,10,7); _FL_DEFPIN( 7,17,7); -_FL_DEFPIN( 8,16,7); _FL_DEFPIN( 9,11,7); _FL_DEFPIN(10, 0,7); _FL_DEFPIN(11, 2,7); -_FL_DEFPIN(12, 1,7); _FL_DEFPIN(13, 3,7); _FL_DEFPIN(14,18,6); _FL_DEFPIN(15,19,6); -_FL_DEFPIN(16,23,6); _FL_DEFPIN(17,22,6); _FL_DEFPIN(18,17,6); _FL_DEFPIN(19,16,6); -_FL_DEFPIN(20,26,6); _FL_DEFPIN(21,27,6); _FL_DEFPIN(22,24,6); _FL_DEFPIN(23,25,6); -_FL_DEFPIN(24,12,6); _FL_DEFPIN(25,13,6); _FL_DEFPIN(26,30,6); _FL_DEFPIN(27,31,6); -_FL_DEFPIN(28,18,8); _FL_DEFPIN(29,31,9); _FL_DEFPIN(30,23,8); _FL_DEFPIN(31,22,8); -_FL_DEFPIN(32,12,7); _FL_DEFPIN(33, 7,9); _FL_DEFPIN(34,15,8); _FL_DEFPIN(35,14,8); -_FL_DEFPIN(36,13,8); _FL_DEFPIN(37,12,8); _FL_DEFPIN(38,17,8); _FL_DEFPIN(39,16,8); - -#define HAS_HARDWARE_PIN_SUPPORT - -#define ARM_HARDWARE_SPI -#define SPI_DATA 11 -#define SPI_CLOCK 13 - -#define SPI1_DATA 26 -#define SPI1_CLOCK 27 - -#define SPI2_DATA 35 -#define SPI2_CLOCK 37 - -#endif // defined FASTLED_TEENSY4 - -#endif // FASTLED_FORCE_SOFTWARE_PINSs - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/mxrt1062/fastspi_arm_mxrt1062.h b/FastLED/src/platforms/arm/mxrt1062/fastspi_arm_mxrt1062.h deleted file mode 100644 index 068c7be1853672af64a161d11095a322fc6c9a85..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/mxrt1062/fastspi_arm_mxrt1062.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef __INC_FASTSPI_ARM_MXRT1062_H -#define __INC_FASTSPI_ARM_MXRT1062_H - -FASTLED_NAMESPACE_BEGIN - -#if defined (FASTLED_TEENSY4) && defined(ARM_HARDWARE_SPI) -#include <SPI.h> - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_RATE, SPIClass & _SPIObject, int _SPI_INDEX> -class Teesy4HardwareSPIOutput { - Selectable *m_pSelect; - uint32_t m_bitCount; - uint32_t m_bitData; - inline IMXRT_LPSPI_t & port() __attribute__((always_inline)) { - switch(_SPI_INDEX) { - case 0: - return IMXRT_LPSPI4_S; - case 1: - return IMXRT_LPSPI3_S; - case 2: - return IMXRT_LPSPI1_S; - } - } - -public: - Teesy4HardwareSPIOutput() { m_pSelect = NULL; m_bitCount = 0;} - Teesy4HardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; m_bitCount = 0;} - - // set the object representing the selectable -- ignore for now - void setSelect(Selectable *pSelect) { /* TODO */ } - - // initialize the SPI subssytem - void init() { _SPIObject.begin(); } - - // latch the CS select - void inline select() __attribute__((always_inline)) { - // begin the SPI transaction - _SPIObject.beginTransaction(SPISettings(_SPI_CLOCK_RATE, MSBFIRST, SPI_MODE0)); - if(m_pSelect != NULL) { m_pSelect->select(); } - } - - // release the CS select - void inline release() __attribute__((always_inline)) { - if(m_pSelect != NULL) { m_pSelect->release(); } - _SPIObject.endTransaction(); - } - - // wait until all queued up data has been written - static void waitFully() { /* TODO */ } - - // write a byte out via SPI (returns immediately on writing register) - - void inline writeByte(uint8_t b) __attribute__((always_inline)) { - if(m_bitCount == 0) { - _SPIObject.transfer(b); - } else { - // There's been a bit of data written, add that to the output as well - uint32_t outData = (m_bitData << 8) | b; - uint32_t tcr = port().TCR; - port().TCR = (tcr & 0xfffff000) | LPSPI_TCR_FRAMESZ((8+m_bitCount) - 1); // turn on 9 bit mode - port().TDR = outData; // output 9 bit data. - while ((port().RSR & LPSPI_RSR_RXEMPTY)) ; // wait while the RSR fifo is empty... - port().TCR = (tcr & 0xfffff000) | LPSPI_TCR_FRAMESZ((8) - 1); // turn back on 8 bit mode - port().RDR; - m_bitCount = 0; - } - } - - // write a word out via SPI (returns immediately on writing register) - void inline writeWord(uint16_t w) __attribute__((always_inline)) { - writeByte(((w>>8) & 0xFF)); - _SPIObject.transfer(w & 0xFF); - } - - // A raw set of writing byte values, assumes setup/init/waiting done elsewhere - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { _SPIObject.transfer(value); } - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytesValue(uint8_t value, int len) { - select(); writeBytesValueRaw(value, len); release(); - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - template <class D> void writeBytes(register uint8_t *data, int len) { - uint8_t *end = data + len; - select(); - // could be optimized to write 16bit words out instead of 8bit bytes - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a single bit out, which bit from the passed in byte is determined by template parameter - template <uint8_t BIT> inline void writeBit(uint8_t b) { - m_bitData = (m_bitData<<1) | ((b&(1<<BIT)) != 0); - // If this is the 8th bit we've collected, just write it out raw - register uint32_t bc = m_bitCount; - bc = (bc + 1) & 0x07; - if (!bc) { - m_bitCount = 0; - _SPIObject.transfer(m_bitData); - } - m_bitCount = bc; - } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - int len = pixels.mLen; - - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - } - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - release(); - } - -}; - - -#endif - -FASTLED_NAMESPACE_END -#endif diff --git a/FastLED/src/platforms/arm/mxrt1062/led_sysdefs_arm_mxrt1062.h b/FastLED/src/platforms/arm/mxrt1062/led_sysdefs_arm_mxrt1062.h deleted file mode 100644 index ac4908254c097b6e567cbd147f5a75e00afff6e9..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/mxrt1062/led_sysdefs_arm_mxrt1062.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_ARM_MXRT1062_H -#define __INC_LED_SYSDEFS_ARM_MXRT1062_H - -#define FASTLED_TEENSY4 -#define FASTLED_ARM - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -#if (F_CPU == 96000000) -#define CLK_DBL 1 -#endif - -// Get some system include files -#include <avr/io.h> -#include <avr/interrupt.h> // for cli/se definitions - -// Define the register types -#if defined(ARDUINO) // && ARDUINO < 150 -typedef volatile uint32_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ -typedef volatile uint32_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ -#endif - -// extern volatile uint32_t systick_millis_count; -// # define MS_COUNTER systick_millis_count - -// Teensy4 provides progmem -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 1 -#endif - - -#endif diff --git a/FastLED/src/platforms/arm/nrf51/clockless_arm_nrf51.h b/FastLED/src/platforms/arm/nrf51/clockless_arm_nrf51.h deleted file mode 100644 index c607e61e5f34e319e73bd78569f07248e9626bbe..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf51/clockless_arm_nrf51.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_NRF51 -#define __INC_CLOCKLESS_ARM_NRF51 - -#if defined(NRF51) - -#include <nrf51_bitfields.h> -#define FASTLED_HAS_CLOCKLESS 1 - -#if (FASTLED_ALLOW_INTERRUPTS==1) -#define SEI_CHK LED_TIMER->CC[0] = (WAIT_TIME * (F_CPU/1000000)); LED_TIMER->TASKS_CLEAR; LED_TIMER->EVENTS_COMPARE[0] = 0; -#define CLI_CHK cli(); if(LED_TIMER->EVENTS_COMPARE[0]) { LED_TIMER->TASKS_STOP = 1; return 0; } -#define INNER_SEI sei(); -#else -#define SEI_CHK -#define CLI_CHK -#define INNER_SEI delaycycles<1>(); -#endif - - -#include "../common/m0clockless.h" -template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 75> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPinBB<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - FastPinBB<DATA_PIN>::setOutput(); - mPinMask = FastPinBB<DATA_PIN>::mask(); - mPort = FastPinBB<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - cli(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - sei(); - mWait.mark(); - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - struct M0ClocklessData data; - data.d[0] = pixels.d[0]; - data.d[1] = pixels.d[1]; - data.d[2] = pixels.d[2]; - data.s[0] = pixels.mScale[0]; - data.s[1] = pixels.mScale[1]; - data.s[2] = pixels.mScale[2]; - data.e[0] = pixels.e[0]; - data.e[1] = pixels.e[1]; - data.e[2] = pixels.e[2]; - data.adj = pixels.mAdvance; - - typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port(); - - // timer mode w/prescaler of 0 - LED_TIMER->MODE = TIMER_MODE_MODE_Timer; - LED_TIMER->PRESCALER = 0; - LED_TIMER->EVENTS_COMPARE[0] = 0; - LED_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit; - LED_TIMER->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk; - LED_TIMER->TASKS_START = 1; - - int ret = showLedData<4,8,T1,T2,T3,RGB_ORDER,WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data); - - LED_TIMER->TASKS_STOP = 1; - return ret; // 0x00FFFFFF - _VAL; - } -}; - - -#endif // NRF51 -#endif // __INC_CLOCKLESS_ARM_NRF51 diff --git a/FastLED/src/platforms/arm/nrf51/fastled_arm_nrf51.h b/FastLED/src/platforms/arm/nrf51/fastled_arm_nrf51.h deleted file mode 100644 index 88344a35a67b59242bb64719ee1f9f80db9680fb..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf51/fastled_arm_nrf51.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __INC_FASTLED_ARM_NRF51_H -#define __INC_FASTLED_ARM_NRF51_H - -// Include the k20 headers -#include "fastpin_arm_nrf51.h" -#include "fastspi_arm_nrf51.h" -#include "clockless_arm_nrf51.h" - -#endif diff --git a/FastLED/src/platforms/arm/nrf51/fastpin_arm_nrf51.h b/FastLED/src/platforms/arm/nrf51/fastpin_arm_nrf51.h deleted file mode 100644 index 6005c44830561870853b5f657ddc129c306bf8c5..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf51/fastpin_arm_nrf51.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef __FASTPIN_ARM_NRF51_H -#define __FASTPIN_ARM_NRF51_H - -#if defined(NRF51) -/// Template definition for teensy 3.0 style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found -/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. -/// The registers are data output, set output, clear output, toggle output, input, and direction -#if 0 -template<uint8_t PIN, uint32_t _MASK, typename _DIRSET, typename _DIRCLR, typename _OUTSET, typename _OUTCLR, typename _OUT> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { _DIRSET::r() = _MASK; } - inline static void setInput() { _DIRCLR::r() = _MASK; } - - inline static void hi() __attribute__ ((always_inline)) { _OUTSET::r() = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { _OUTCLR::r() = _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { _OUT::r() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { _OUT::r() ^= _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return _OUT::r() | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return _OUT::r() & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_OUT::r(); } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - -#define ADDR(X) *(volatile uint32_t*)X -#define NR_GPIO_ADDR(base,offset) (*(volatile uint32_t *))((uint32_t)(base + offset)) -#define NR_DIRSET ADDR(0x50000518UL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x518) -#define NR_DIRCLR ADDR(0x5000051CUL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x51C) -#define NR_OUTSET ADDR(0x50000508UL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x508) -#define NR_OUTCLR ADDR(0x5000050CUL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x50C) -#define NR_OUT ADDR(0x50000504UL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x504) - -#define _RD32_NRF(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; }}; - -_RD32_NRF(NR_DIRSET); -_RD32_NRF(NR_DIRCLR); -_RD32_NRF(NR_OUTSET); -_RD32_NRF(NR_OUTCLR); -_RD32_NRF(NR_OUT); - -#define _FL_DEFPIN(PIN) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << PIN, \ - _R(NR_DIRSET), _R(NR_DIRCLR), _R(NR_OUTSET), _R(NR_OUTCLR), _R(NR_OUT)> {}; -#else - -typedef struct { /*!< GPIO Structure */ - // __I uint32_t RESERVED0[321]; - __IO uint32_t OUT; /*!< Write GPIO port. */ - __IO uint32_t OUTSET; /*!< Set individual bits in GPIO port. */ - __IO uint32_t OUTCLR; /*!< Clear individual bits in GPIO port. */ - __I uint32_t IN; /*!< Read GPIO port. */ - __IO uint32_t DIR; /*!< Direction of GPIO pins. */ - __IO uint32_t DIRSET; /*!< DIR set register. */ - __IO uint32_t DIRCLR; /*!< DIR clear register. */ - __I uint32_t RESERVED1[120]; - __IO uint32_t PIN_CNF[32]; /*!< Configuration of GPIO pins. */ -} FL_NRF_GPIO_Type; - -#define FL_NRF_GPIO_BASE 0x50000504UL -#define FL_NRF_GPIO ((FL_NRF_GPIO_Type *) FL_NRF_GPIO_BASE) - -template<uint8_t PIN, uint32_t _MASK> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { FL_NRF_GPIO->DIRSET = _MASK; } - inline static void setInput() { FL_NRF_GPIO->DIRCLR = _MASK; } - - inline static void hi() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUTSET = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUTCLR= _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { FL_NRF_GPIO->OUT = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUT ^= _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return FL_NRF_GPIO->OUT | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return FL_NRF_GPIO->OUT & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &FL_NRF_GPIO->OUT; } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } - - inline static bool isset() __attribute__ ((always_inline)) { return (FL_NRF_GPIO->IN & _MASK) != 0; } -}; - - -#define _FL_DEFPIN(PIN) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << PIN> {}; -#endif - -// Actual pin definitions -#define MAX_PIN 31 -_FL_DEFPIN(0); _FL_DEFPIN(1); _FL_DEFPIN(2); _FL_DEFPIN(3); -_FL_DEFPIN(4); _FL_DEFPIN(5); _FL_DEFPIN(6); _FL_DEFPIN(7); -_FL_DEFPIN(8); _FL_DEFPIN(9); _FL_DEFPIN(10); _FL_DEFPIN(11); -_FL_DEFPIN(12); _FL_DEFPIN(13); _FL_DEFPIN(14); _FL_DEFPIN(15); -_FL_DEFPIN(16); _FL_DEFPIN(17); _FL_DEFPIN(18); _FL_DEFPIN(19); -_FL_DEFPIN(20); _FL_DEFPIN(21); _FL_DEFPIN(22); _FL_DEFPIN(23); -_FL_DEFPIN(24); _FL_DEFPIN(25); _FL_DEFPIN(26); _FL_DEFPIN(27); -_FL_DEFPIN(28); _FL_DEFPIN(29); _FL_DEFPIN(30); _FL_DEFPIN(31); - -#define HAS_HARDWARE_PIN_SUPPORT - -#endif - -#endif diff --git a/FastLED/src/platforms/arm/nrf51/fastspi_arm_nrf51.h b/FastLED/src/platforms/arm/nrf51/fastspi_arm_nrf51.h deleted file mode 100644 index 6826ebcba3c0fedc19ce3a80cf1c63d43eb51246..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf51/fastspi_arm_nrf51.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef __INC_FASTSPI_NRF_H -#define __INC_FASTSPI_NRF_H - -#ifdef NRF51 - -#ifndef FASTLED_FORCE_SOFTWARE_SPI -#define FASTLED_ALL_PINS_HARDWARE_SPI - -// A nop/stub class, mostly to show the SPI methods that are needed/used by the various SPI chipset implementations. Should -// be used as a definition for the set of methods that the spi implementation classes should use (since C++ doesn't support the -// idea of interfaces - it's possible this could be done with virtual classes, need to decide if i want that overhead) -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class NRF51SPIOutput { - - struct saveData { - uint32_t sck; - uint32_t mosi; - uint32_t miso; - uint32_t freq; - uint32_t enable; - } mSavedData; - - void saveSPIData() { - mSavedData.sck = NRF_SPI0->PSELSCK; - mSavedData.mosi = NRF_SPI0->PSELMOSI; - mSavedData.miso = NRF_SPI0->PSELMISO; - mSavedData.freq = NRF_SPI0->FREQUENCY; - mSavedData.enable = NRF_SPI0->ENABLE; - } - - void restoreSPIData() { - NRF_SPI0->PSELSCK = mSavedData.sck; - NRF_SPI0->PSELMOSI = mSavedData.mosi; - NRF_SPI0->PSELMISO = mSavedData.miso; - NRF_SPI0->FREQUENCY = mSavedData.freq; - mSavedData.enable = NRF_SPI0->ENABLE; - } - -public: - NRF51SPIOutput() { FastPin<_DATA_PIN>::setOutput(); FastPin<_CLOCK_PIN>::setOutput(); } - NRF51SPIOutput(Selectable *pSelect) { FastPin<_DATA_PIN>::setOutput(); FastPin<_CLOCK_PIN>::setOutput(); } - - // set the object representing the selectable - void setSelect(Selectable *pSelect) { /* TODO */ } - - // initialize the SPI subssytem - void init() { - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); - NRF_SPI0->PSELSCK = _CLOCK_PIN; - NRF_SPI0->PSELMOSI = _DATA_PIN; - NRF_SPI0->PSELMISO = 0xFFFFFFFF; - NRF_SPI0->FREQUENCY = 0x80000000; - NRF_SPI0->ENABLE = 1; - NRF_SPI0->EVENTS_READY = 0; - } - - // latch the CS select - void select() { saveSPIData(); init(); } - - // release the CS select - void release() { shouldWait(); restoreSPIData(); } - - static bool shouldWait(bool wait = false) __attribute__((always_inline)) __attribute__((always_inline)) { - // static bool sWait=false; - // bool oldWait = sWait; - // sWait = wait; - // never going to bother with waiting since we're always running the spi clock at max speed on the rfduino - // TODO: When we set clock rate, implement/fix waiting properly, otherwise the world hangs up - return false; - } - - // wait until all queued up data has been written - static void waitFully() __attribute__((always_inline)){ if(shouldWait()) { while(NRF_SPI0->EVENTS_READY==0); } NRF_SPI0->INTENCLR; } - static void wait() __attribute__((always_inline)){ if(shouldWait()) { while(NRF_SPI0->EVENTS_READY==0); } NRF_SPI0->INTENCLR; } - - // write a byte out via SPI (returns immediately on writing register) - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); NRF_SPI0->TXD = b; NRF_SPI0->INTENCLR; shouldWait(true); } - - // write a word out via SPI (returns immediately on writing register) - static void writeWord(uint16_t w) __attribute__((always_inline)){ writeByte(w>>8); writeByte(w & 0xFF); } - - // A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes) - static void writeBytesValueRaw(uint8_t value, int len) { while(len--) { writeByte(value); } } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytesValue(uint8_t value, int len) { - select(); - while(len--) { - writeByte(value); - } - waitFully(); - release(); - } - - // A full cycle of writing a raw block of data out, including select, release, and waiting - template<class D> void writeBytes(uint8_t *data, int len) { - uint8_t *end = data + len; - select(); - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - void writeBytes(uint8_t *data, int len) { - writeBytes<DATA_NOP>(data, len); - } - - // write a single bit out, which bit from the passed in byte is determined by template parameter - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - waitFully(); - NRF_SPI0->ENABLE = 0; - if(b & 1<<BIT) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - FastPin<_CLOCK_PIN>::toggle(); - FastPin<_CLOCK_PIN>::toggle(); - NRF_SPI0->ENABLE = 1; - } - - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - int len = pixels.mLen; - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - } - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - waitFully(); - release(); - } -}; - -#endif -#endif - -#endif diff --git a/FastLED/src/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h b/FastLED/src/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h deleted file mode 100644 index b63dfd3215dce406b2993996f1c05a51828dcf70..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __LED_SYSDEFS_ARM_NRF51 -#define __LED_SYSDEFS_ARM_NRF51 - -#ifndef NRF51 -#define NRF51 -#endif - -#define LED_TIMER NRF_TIMER1 -#define FASTLED_NO_PINMAP -#define FASTLED_HAS_CLOCKLESS - -#define FASTLED_SPI_BYTE_ONLY - -#define FASTLED_ARM -#define FASTLED_ARM_M0 - -#ifndef F_CPU -#define F_CPU 16000000 -#endif - -#include <stdint.h> -#include <nrf51.h> -#include <core_cm0.h> - -typedef volatile uint32_t RoReg; -typedef volatile uint32_t RwReg; -typedef uint32_t prog_uint32_t; -typedef uint8_t boolean; - -#define PROGMEM -#define NO_PROGMEM -#define NEED_CXX_BITS - -// Default to NOT using PROGMEM here -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 0 -#endif - -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -#define cli() __disable_irq(); -#define sei() __enable_irq(); - -#endif diff --git a/FastLED/src/platforms/arm/nrf52/arbiter_nrf52.h b/FastLED/src/platforms/arm/nrf52/arbiter_nrf52.h deleted file mode 100644 index 8972d2d23347a75a2ffb932b8863eb5858f0f477..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf52/arbiter_nrf52.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef __INC_ARBITER_NRF52 -#define __INC_ARBITER_NRF52 - -#if defined(NRF52_SERIES) - -#include "led_sysdefs_arm_nrf52.h" - -//FASTLED_NAMESPACE_BEGIN - -typedef void (*FASTLED_NRF52_PWM_INTERRUPT_HANDLER)(); - -// a trick learned from other embedded projects .. -// use the enum as an index to a statically-allocated array -// to store unique information for that instance. -// also provides a count of how many instances were enabled. -// -// See led_sysdefs_arm_nrf52.h for selection.... -// -typedef enum _FASTLED_NRF52_ENABLED_PWM_INSTANCE { -#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0) - FASTLED_NRF52_PWM0_INSTANCE_IDX, -#endif -#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1) - FASTLED_NRF52_PWM1_INSTANCE_IDX, -#endif -#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2) - FASTLED_NRF52_PWM2_INSTANCE_IDX, -#endif -#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3) - FASTLED_NRF52_PWM3_INSTANCE_IDX, -#endif - FASTLED_NRF52_PWM_INSTANCE_COUNT -} FASTLED_NRF52_ENABLED_PWM_INSTANCES; - -static_assert(FASTLED_NRF52_PWM_INSTANCE_COUNT > 0, "Instance count must be greater than zero -- define FASTLED_NRF52_ENABLE_PWM_INSTNACE[n] (replace `[n]` with digit)"); - -template <uint32_t _PWM_ID> -class PWM_Arbiter { -private: - static_assert(_PWM_ID < 32, "PWM_ID over 31 breaks current arbitration bitmask"); - //const uint32_t _ACQUIRE_MASK = (1u << _PWM_ID) ; - //const uint32_t _CLEAR_MASK = ~((uint32_t)(1u << _PWM_ID)); - static uint32_t s_PwmInUse; - static NRF_PWM_Type * const s_PWM; - static IRQn_Type const s_PWM_IRQ; - static FASTLED_NRF52_PWM_INTERRUPT_HANDLER volatile s_Isr; - -public: - static void isr_handler() { - return s_Isr(); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static bool isAcquired() { - return (0u != (s_PwmInUse & 1u)); // _ACQUIRE_MASK - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void acquire(FASTLED_NRF52_PWM_INTERRUPT_HANDLER isr) { - while (!tryAcquire(isr)); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static bool tryAcquire(FASTLED_NRF52_PWM_INTERRUPT_HANDLER isr) { - uint32_t oldValue = __sync_fetch_and_or(&s_PwmInUse, 1u); // _ACQUIRE_MASK - if (0u == (oldValue & 1u)) { // _ACQUIRE_MASK - s_Isr = isr; - return true; - } - return false; - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void releaseFromIsr() { - uint32_t oldValue = __sync_fetch_and_and(&s_PwmInUse, ~1u); // _CLEAR_MASK - if (0u == (oldValue & 1u)) { // _ACQUIRE_MASK - // TODO: This should never be true... indicates was not held. - // Assert here? - (void)oldValue; - } - return; - } - FASTLED_NRF52_INLINE_ATTRIBUTE static NRF_PWM_Type * getPWM() { - return s_PWM; - } - FASTLED_NRF52_INLINE_ATTRIBUTE static IRQn_Type getIRQn() { return s_PWM_IRQ; } -}; -template <uint32_t _PWM_ID> NRF_PWM_Type * const PWM_Arbiter<_PWM_ID>::s_PWM = - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0) - (_PWM_ID == 0 ? NRF_PWM0 : - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1) - (_PWM_ID == 1 ? NRF_PWM1 : - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2) - (_PWM_ID == 2 ? NRF_PWM2 : - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3) - (_PWM_ID == 3 ? NRF_PWM3 : - #endif - (NRF_PWM_Type*)-1 - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0) - ) - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1) - ) - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2) - ) - #endif - #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3) - ) - #endif - ; -template <uint32_t _PWM_ID> IRQn_Type const PWM_Arbiter<_PWM_ID>::s_PWM_IRQ = ((IRQn_Type)((uint8_t)((uint32_t)(s_PWM) >> 12))); -template <uint32_t _PWM_ID> uint32_t PWM_Arbiter<_PWM_ID>::s_PwmInUse = 0; -template <uint32_t _PWM_ID> FASTLED_NRF52_PWM_INTERRUPT_HANDLER volatile PWM_Arbiter<_PWM_ID>::s_Isr = NULL; - -//FASTLED_NAMESPACE_END - -#endif // NRF52_SERIES -#endif // __INC_ARBITER_NRF52 \ No newline at end of file diff --git a/FastLED/src/platforms/arm/nrf52/clockless_arm_nrf52.h b/FastLED/src/platforms/arm/nrf52/clockless_arm_nrf52.h deleted file mode 100644 index 1dd3cd94d62a11acc3d6fd5dd9530a9a3fcdac4b..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf52/clockless_arm_nrf52.h +++ /dev/null @@ -1,390 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_NRF52 -#define __INC_CLOCKLESS_ARM_NRF52 - -#if defined(NRF52_SERIES) - - -//FASTLED_NAMESPACE_BEGIN - -#define FASTLED_HAS_CLOCKLESS 1 -#define FASTLED_NRF52_MAXIMUM_PIXELS_PER_STRING 144 // TODO: Figure out how to safely let this be calller-defined.... - -// nRF52810 has a single PWM peripheral (PWM0) -// nRF52832 has three PWM peripherals (PWM0, PWM1, PWM2) -// nRF52840 has four PWM peripherals (PWM0, PWM1, PWM2, PWM3) -// NOTE: Update platforms.cpp in root of FastLED library if this changes -#define FASTLED_NRF52_PWM_ID 0 - -extern uint32_t isrCount; - - -template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER = RGB, int _XTRA0 = 0, bool _FLIP = false, int _WAIT_TIME_MICROSECONDS = 10> -class ClocklessController : public CPixelLEDController<_RGB_ORDER> { - static_assert(FASTLED_NRF52_MAXIMUM_PIXELS_PER_STRING > 0, "Maximum string length must be positive value (FASTLED_NRF52_MAXIMUM_PIXELS_PER_STRING)"); - static_assert(_T1 > 0 , "negative values are not allowed"); - static_assert(_T2 > 0 , "negative values are not allowed"); - static_assert(_T3 > 0 , "negative values are not allowed"); - static_assert(_T1 < (0x8000u-2u), "_T1 must fit in 15 bits"); - static_assert(_T2 < (0x8000u-2u), "_T2 must fit in 15 bits"); - static_assert(_T3 < (0x8000u-2u), "_T3 must fit in 15 bits"); - static_assert(_T1 < (0x8000u-2u), "_T0H must fit in 15 bits"); - static_assert(_T1+_T2 < (0x8000u-2u), "_T1H must fit in 15 bits"); - static_assert(_T1+_T2+_T3 < (0x8000u-2u), "_TOP must fit in 15 bits"); - static_assert(_T1+_T2+_T3 <= PWM_COUNTERTOP_COUNTERTOP_Msk, "_TOP too large for peripheral"); - -private: - static const bool _INITIALIZE_PIN_HIGH = (_FLIP ? 1 : 0); - static const uint16_t _POLARITY_BIT = (_FLIP ? 0 : 0x8000); - - static const uint8_t _BITS_PER_PIXEL = (8 + _XTRA0) * 3; // NOTE: 3 means RGB only... - static const uint16_t _PWM_BUFFER_COUNT = (_BITS_PER_PIXEL * FASTLED_NRF52_MAXIMUM_PIXELS_PER_STRING); - static const uint8_t _T0H = ((uint16_t)(_T1 )); - static const uint8_t _T1H = ((uint16_t)(_T1+_T2 )); - static const uint8_t _TOP = ((uint16_t)(_T1+_T2+_T3)); - - // may as well be static, as can only attach one LED string per _DATA_PIN.... - static uint16_t s_SequenceBuffer[_PWM_BUFFER_COUNT]; - static uint16_t s_SequenceBufferValidElements; - static volatile uint32_t s_SequenceBufferInUse; - static CMinWait<_WAIT_TIME_MICROSECONDS> mWait; // ensure data has time to latch - - FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_InitializePinState() { - FastPin<_DATA_PIN>::setOutput(); - if (_INITIALIZE_PIN_HIGH) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_InitializePwmInstance(NRF_PWM_Type * pwm) { - - // Pins must be set before enabling the peripheral - pwm->PSEL.OUT[0] = FastPin<_DATA_PIN>::nrf_pin(); - pwm->PSEL.OUT[1] = NRF_PWM_PIN_NOT_CONNECTED; - pwm->PSEL.OUT[2] = NRF_PWM_PIN_NOT_CONNECTED; - pwm->PSEL.OUT[3] = NRF_PWM_PIN_NOT_CONNECTED; - nrf_pwm_enable(pwm); - nrf_pwm_configure(pwm, NRF_PWM_CLK_16MHz, NRF_PWM_MODE_UP, _TOP); - nrf_pwm_decoder_set(pwm, NRF_PWM_LOAD_COMMON, NRF_PWM_STEP_AUTO); - - // clear any prior shorts / interrupt enable bits - nrf_pwm_shorts_set(pwm, 0); - nrf_pwm_int_set(pwm, 0); - // clear all prior events - nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_STOPPED); - nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQSTARTED0); - nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQSTARTED1); - nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0); - nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND1); - nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_PWMPERIODEND); - nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_LOOPSDONE); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_ConfigurePwmSequence(NRF_PWM_Type * pwm) { - // config is easy, using SEQ0, no loops... - nrf_pwm_sequence_t sequenceConfig; - sequenceConfig.values.p_common = &(s_SequenceBuffer[0]); - sequenceConfig.length = s_SequenceBufferValidElements; - sequenceConfig.repeats = 0; // send the data once, and only once - sequenceConfig.end_delay = 0; // no extra delay at the end of SEQ[0] / SEQ[1] - nrf_pwm_sequence_set(pwm, 0, &sequenceConfig); - nrf_pwm_sequence_set(pwm, 1, &sequenceConfig); - nrf_pwm_loop_set(pwm, 0); - - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_EnableInterruptsAndShortcuts(NRF_PWM_Type * pwm) { - IRQn_Type irqn = PWM_Arbiter<FASTLED_NRF52_PWM_ID>::getIRQn(); - // TODO: check API results... - uint32_t result; - - result = sd_nvic_SetPriority(irqn, configMAX_SYSCALL_INTERRUPT_PRIORITY); - (void)result; - result = sd_nvic_EnableIRQ(irqn); - (void)result; - - // shortcuts prevent (up to) 4-cycle delay from interrupt handler to next action - uint32_t shortsToEnable = 0; - shortsToEnable |= NRF_PWM_SHORT_SEQEND0_STOP_MASK; ///< SEQEND[0] --> STOP task. - shortsToEnable |= NRF_PWM_SHORT_SEQEND1_STOP_MASK; ///< SEQEND[1] --> STOP task. - //shortsToEnable |= NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; ///< LOOPSDONE --> SEQSTART[0] task. - //shortsToEnable |= NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK; ///< LOOPSDONE --> SEQSTART[1] task. - shortsToEnable |= NRF_PWM_SHORT_LOOPSDONE_STOP_MASK; ///< LOOPSDONE --> STOP task. - nrf_pwm_shorts_set(pwm, shortsToEnable); - - // mark which events should cause interrupts... - uint32_t interruptsToEnable = 0; - interruptsToEnable |= NRF_PWM_INT_SEQEND0_MASK; - interruptsToEnable |= NRF_PWM_INT_SEQEND1_MASK; - interruptsToEnable |= NRF_PWM_INT_LOOPSDONE_MASK; - interruptsToEnable |= NRF_PWM_INT_STOPPED_MASK; - nrf_pwm_int_set(pwm, interruptsToEnable); - - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_StartTask(NRF_PWM_Type * pwm) { - nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void spinAcquireSequenceBuffer() { - while (!tryAcquireSequenceBuffer()); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static bool tryAcquireSequenceBuffer() { - return __sync_bool_compare_and_swap(&s_SequenceBufferInUse, 0, 1); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void releaseSequenceBuffer() { - uint32_t tmp = __sync_val_compare_and_swap(&s_SequenceBufferInUse, 1, 0); - if (tmp != 1) { - // TODO: Error / Assert / log ? - } - } - -public: - static void isr_handler() { - NRF_PWM_Type * pwm = PWM_Arbiter<FASTLED_NRF52_PWM_ID>::getPWM(); - IRQn_Type irqn = PWM_Arbiter<FASTLED_NRF52_PWM_ID>::getIRQn(); - - // Currently, only use SEQUENCE 0, so only event - // of consequence is LOOPSDONE ... - if (nrf_pwm_event_check(pwm,NRF_PWM_EVENT_STOPPED)) { - nrf_pwm_event_clear(pwm,NRF_PWM_EVENT_STOPPED); - - // update the minimum time to next call - mWait.mark(); - // mark the sequence as no longer in use -- pointer, comparator, exchange value - releaseSequenceBuffer(); - // prevent further interrupts from PWM events - nrf_pwm_int_set(pwm, 0); - // disable PWM interrupts - None of the PWM IRQs are shared - // with other peripherals, avoiding complexity of shared IRQs. - sd_nvic_DisableIRQ(irqn); - // disable the PWM instance - nrf_pwm_disable(pwm); - // may take up to 4 cycles for writes to propagate (APB bus @ 16MHz) - asm __volatile__ ( "NOP; NOP; NOP; NOP;" ); - // release the PWM arbiter to be re-used by another LED string - PWM_Arbiter<FASTLED_NRF52_PWM_ID>::releaseFromIsr(); - } - } - - - virtual void init() { - FASTLED_NRF52_DEBUGPRINT("Clockless Timings:\n"); - FASTLED_NRF52_DEBUGPRINT(" T0H == %d", _T0H); - FASTLED_NRF52_DEBUGPRINT(" T1H == %d", _T1H); - FASTLED_NRF52_DEBUGPRINT(" TOP == %d\n", _TOP); - // to avoid pin initialization from causing first LED to have invalid color, - // call mWait.mark() to ensure data latches before color data gets sent. - startPwmPlayback_InitializePinState(); - mWait.mark(); - - } - virtual uint16_t getMaxRefreshRate() const { return 800; } - - virtual void showPixels(PixelController<_RGB_ORDER> & pixels) { - // wait for the only sequence buffer to become available - spinAcquireSequenceBuffer(); - prepareSequenceBuffers(pixels); - // ensure any prior data had time to latch - mWait.wait(); - startPwmPlayback(s_SequenceBufferValidElements); - return; - } - - template<uint8_t _BIT> - FASTLED_NRF52_INLINE_ATTRIBUTE static void WriteBitToSequence(uint8_t byte, uint16_t * e) { - *e = _POLARITY_BIT | (((byte & (1u << _BIT)) == 0) ? _T0H : _T1H); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void prepareSequenceBuffers(PixelController<_RGB_ORDER> & pixels) { - s_SequenceBufferValidElements = 0; - int32_t remainingSequenceElements = _PWM_BUFFER_COUNT; - uint16_t * e = s_SequenceBuffer; - uint32_t size_needed = pixels.size(); // count of pixels - size_needed *= (8 + _XTRA0); // bits per pixel - size_needed *= 2; // each bit takes two bytes - - if (size_needed > _PWM_BUFFER_COUNT) { - // TODO: assert()? - return; - } - - while (pixels.has(1) && (remainingSequenceElements >= _BITS_PER_PIXEL)) { - uint8_t b0 = pixels.loadAndScale0(); - WriteBitToSequence<7>(b0, e); ++e; - WriteBitToSequence<6>(b0, e); ++e; - WriteBitToSequence<5>(b0, e); ++e; - WriteBitToSequence<4>(b0, e); ++e; - WriteBitToSequence<3>(b0, e); ++e; - WriteBitToSequence<2>(b0, e); ++e; - WriteBitToSequence<1>(b0, e); ++e; - WriteBitToSequence<0>(b0, e); ++e; - if (_XTRA0 > 0) { - for (int i = 0; i < _XTRA0; ++i) { - WriteBitToSequence<0>(0,e); ++e; - } - } - uint8_t b1 = pixels.loadAndScale1(); - WriteBitToSequence<7>(b1, e); ++e; - WriteBitToSequence<6>(b1, e); ++e; - WriteBitToSequence<5>(b1, e); ++e; - WriteBitToSequence<4>(b1, e); ++e; - WriteBitToSequence<3>(b1, e); ++e; - WriteBitToSequence<2>(b1, e); ++e; - WriteBitToSequence<1>(b1, e); ++e; - WriteBitToSequence<0>(b1, e); ++e; - if (_XTRA0 > 0) { - for (int i = 0; i < _XTRA0; ++i) { - WriteBitToSequence<0>(0,e); ++e; - } - } - uint8_t b2 = pixels.loadAndScale2(); - WriteBitToSequence<7>(b2, e); ++e; - WriteBitToSequence<6>(b2, e); ++e; - WriteBitToSequence<5>(b2, e); ++e; - WriteBitToSequence<4>(b2, e); ++e; - WriteBitToSequence<3>(b2, e); ++e; - WriteBitToSequence<2>(b2, e); ++e; - WriteBitToSequence<1>(b2, e); ++e; - WriteBitToSequence<0>(b2, e); ++e; - if (_XTRA0 > 0) { - for (int i = 0; i < _XTRA0; ++i) { - WriteBitToSequence<0>(0,e); ++e; - } - } - - // advance pixel and sequence pointers - s_SequenceBufferValidElements += _BITS_PER_PIXEL; - remainingSequenceElements -= _BITS_PER_PIXEL; - pixels.advanceData(); - pixels.stepDithering(); - } - } - - - FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback(uint16_t bytesToSend) { - PWM_Arbiter<FASTLED_NRF52_PWM_ID>::acquire(isr_handler); - NRF_PWM_Type * pwm = PWM_Arbiter<FASTLED_NRF52_PWM_ID>::getPWM(); - - // mark the sequence as being in-use - __sync_fetch_and_or(&s_SequenceBufferInUse, 1); - - startPwmPlayback_InitializePinState(); - startPwmPlayback_InitializePwmInstance(pwm); - startPwmPlayback_ConfigurePwmSequence(pwm); - startPwmPlayback_EnableInterruptsAndShortcuts(pwm); - startPwmPlayback_StartTask(pwm); - return; - } - - -#if 0 - FASTLED_NRF52_INLINE_ATTRIBUTE static uint16_t* getRawSequenceBuffer() { return s_SequenceBuffer; } - FASTLED_NRF52_INLINE_ATTRIBUTE static uint16_t getRawSequenceBufferSize() { return _PWM_BUFFER_COUNT; } - FASTLED_NRF52_INLINE_ATTRIBUTE static uint16_t getSequenceBufferInUse() { return s_SequenceBufferInUse; } - FASTLED_NRF52_INLINE_ATTRIBUTE static void sendRawSequenceBuffer(uint16_t bytesToSend) { - mWait.wait(); // ensure min time between updates - startPwmPlayback(bytesToSend); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void sendRawBytes(uint8_t * arrayOfBytes, uint16_t bytesToSend) { - // wait for sequence buffer to be available - while (s_SequenceBufferInUse != 0); - - s_SequenceBufferValidElements = 0; - int32_t remainingSequenceElements = _PWM_BUFFER_COUNT; - uint16_t * e = s_SequenceBuffer; - uint8_t * nextByte = arrayOfBytes; - for (uint16_t bytesRemain = bytesToSend; - (remainingSequenceElements >= 8) && (bytesRemain > 0); - --bytesRemain, - remainingSequenceElements -= 8, - s_SequenceBufferValidElements += 8 - ) { - uint8_t b = *nextByte; - WriteBitToSequence<7,false>(b, e); ++e; - WriteBitToSequence<6,false>(b, e); ++e; - WriteBitToSequence<5,false>(b, e); ++e; - WriteBitToSequence<4,false>(b, e); ++e; - WriteBitToSequence<3,false>(b, e); ++e; - WriteBitToSequence<2,false>(b, e); ++e; - WriteBitToSequence<1,false>(b, e); ++e; - WriteBitToSequence<0,false>(b, e); ++e; - if (_XTRA0 > 0) { - for (int i = 0; i < _XTRA0; ++i) { - WriteBitToSequence<0,_FLIP>(0,e); ++e; - } - } - } - mWait.wait(); // ensure min time between updates - - startPwmPlayback(s_SequenceBufferValidElements); - } -#endif // 0 - -}; - -template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER, int _XTRA0, bool _FLIP, int _WAIT_TIME_MICROSECONDS> -uint16_t ClocklessController<_DATA_PIN, _T1, _T2, _T3, _RGB_ORDER, _XTRA0, _FLIP, _WAIT_TIME_MICROSECONDS>::s_SequenceBufferValidElements = 0; -template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER, int _XTRA0, bool _FLIP, int _WAIT_TIME_MICROSECONDS> -uint32_t volatile ClocklessController<_DATA_PIN, _T1, _T2, _T3, _RGB_ORDER, _XTRA0, _FLIP, _WAIT_TIME_MICROSECONDS>::s_SequenceBufferInUse = 0; -template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER, int _XTRA0, bool _FLIP, int _WAIT_TIME_MICROSECONDS> -uint16_t ClocklessController<_DATA_PIN, _T1, _T2, _T3, _RGB_ORDER, _XTRA0, _FLIP, _WAIT_TIME_MICROSECONDS>::s_SequenceBuffer[_PWM_BUFFER_COUNT]; -template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER, int _XTRA0, bool _FLIP, int _WAIT_TIME_MICROSECONDS> -CMinWait<_WAIT_TIME_MICROSECONDS> ClocklessController<_DATA_PIN, _T1, _T2, _T3, _RGB_ORDER, _XTRA0, _FLIP, _WAIT_TIME_MICROSECONDS>::mWait; - -/* nrf_pwm solution -// -// When the nRF52 softdevice (e.g., BLE) is enabled, the CPU can be pre-empted -// at any time for radio interrupts. These interrupts cannot be disabled. -// The problem is, even simple BLE advertising interrupts may take **`348μs`** -// (per softdevice 1.40, see http://infocenter.nordicsemi.com/pdf/S140_SDS_v1.3.pdf) -// -// The nRF52 chips have a decent Easy-DMA-enabled PWM peripheral. -// -// The major downside: -// [] The PWM peripheral has a fixed input buffer size at 16 bits per clock cycle. -// (each clockless protocol bit == 2 bytes) -// -// The major upsides include: -// [] Fully asynchronous, freeing CPU for other tasks -// [] Softdevice interrupts do not affect PWM clocked output (reliable clocking) -// -// The initial solution generally does the following for showPixels(): -// [] wait for a sequence buffer to become available -// [] prepare the entire LED string's sequence (see `prepareSequenceBuffers()`) -// [] ensures minimum wait time from prior sequence's end -// -// Options after initial solution working: -// [] - -// TODO: Double-buffers, so one can be doing DMA while the second -// buffer is being prepared. -// TODO: Pool of buffers, so can keep N-1 active in DMA, while -// preparing data in the final buffer? -// Write another class similar to PWM_Arbiter, only for -// tracking use of sequence buffers? -// TODO: Use volatile variable to track buffers that the -// prior DMA operation is finished with, so can fill -// in those buffers with newly-prepared data... -// apis to send the pre-generated buffer. This would be essentially asynchronous, -// and result in efficient run time if the pixels are either (a) static, or -// (b) cycle through a limited number of options whose converted results can -// be cached and re-used. While simple, this method takes lots of extra RAM... -// 16 bits for every full clock (high/low) cycle. -// -// Clockless chips typically send 24 bits (3x 8-bit) per pixel. -// One odd clockless chip sends 36 bits (3x 12-bit) per pixel. -// Each bit requires a 16-bit sequence entry for the PWM peripheral. -// This gives approximately: -// 24 bpp 36 bpp -// ========================================== -// 1 pixel 48 bytes 72 bytes -// 32 pixels 1,536 bytes 2,304 bytes -// 64 pixels 3,072 bytes 4,608 bytes -// -// -// UPDATE: this is the method I'm choosing, to get _SOMETHING_ -// clockless working... 3k RAM for 64 pixels is acceptable -// for a first release, as it allows re-use of FASTLED -// color correction, dithering, etc. .... -*/ - -//FASTLED_NAMESPACE_END - -#endif // NRF52_SERIES -#endif // __INC_CLOCKLESS_ARM_NRF52 \ No newline at end of file diff --git a/FastLED/src/platforms/arm/nrf52/fastled_arm_nrf52.h b/FastLED/src/platforms/arm/nrf52/fastled_arm_nrf52.h deleted file mode 100644 index 453003068ece7e81cf55bcd4fef860add5359756..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf52/fastled_arm_nrf52.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __INC_FASTLED_ARM_NRF52_H -#define __INC_FASTLED_ARM_NRF52_H - -#include "led_sysdefs_arm_nrf52.h" -#include "arbiter_nrf52.h" -#include "fastpin_arm_nrf52.h" -#include "fastspi_arm_nrf52.h" -#include "clockless_arm_nrf52.h" - -#endif // #ifndef __INC_FASTLED_ARM_NRF52_H - diff --git a/FastLED/src/platforms/arm/nrf52/fastpin_arm_nrf52.h b/FastLED/src/platforms/arm/nrf52/fastpin_arm_nrf52.h deleted file mode 100644 index 9d0a8ec9902c5e931f956eef95b90d34c33442b0..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf52/fastpin_arm_nrf52.h +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef __FASTPIN_ARM_NRF52_H -#define __FASTPIN_ARM_NRF52_H - - -/* -// -// Background: -// =========== -// the nRF52 has more than 32 ports, and thus must support -// two distinct GPIO port registers. -// -// For the nRF52 series, the structure to control the port is -// `NRF_GPIO_Type`, with separate addresses mapped for set, clear, etc. -// The two ports are defined as NRF_P0 and NRF_P1. -// An example declaration for the ports is: -// #define NRF_P0_BASE 0x50000000UL -// #define NRF_P1_BASE 0x50000300UL -// #define NRF_P0 ((NRF_GPIO_Type*)NRF_P0_BASE) -// #define NRF_P1 ((NRF_GPIO_Type*)NRF_P1_BASE) -// -// Therefore, ideally, the _FL_DEFPIN() macro would simply -// conditionally pass either NRF_P0 or NRF_P1 to the underlying -// FastPin<> template class class. -// -// The "pin" provided to the FastLED<> template (and which -// the _FL_DEFPIN() macro specializes for valid pins) is NOT -// the microcontroller port.pin, but the Arduino digital pin. -// Some boards have an identity mapping (e.g., nRF52832 Feather) -// but most do not. Therefore, the _FL_DEFPIN() macro -// must translate the Arduino pin to the mcu port.pin. -// -// -// Difficulties: -// ============= -// The goal is to avoid any such lookups, using compile-time -// optimized functions for speed, in line with FastLED's -// overall design goals. This means constexpr, compile-time -// and aggressive inlining of functions.... -// -// Right away, this precludes the use of g_ADigitalPinMap, -// which is not constexpr, and thus not available for -// preprocessor/compile-time optimizations. Therefore, -// we have to specialize FastPin<uint8_t PIN>, given a -// compile-time value for PIN, into at least a PORT and -// a BITMASK for the port. -// -// Arduino compiles using C++11 for at least Feather nRF52840 Express. -// C++11 is very restrictive about template parameters. -// Template parameters can only be: -// 1. a type (as most people expect) -// 2. a template -// 3. a constexpr native integer type -// -// Therefore, attempts to use `NRF_GPIO_Type *` as a -// template parameter will fail.... -// -// Solution: -// ========= -// The solution chosen is to define a unique structure for each port, -// whose SOLE purpose is to have a static inline function that -// returns the `NRF_GPIO_Type *` that is needed. -// -// Thus, while it's illegal to pass `NRF_P0` as a template -// parameter, it's perfectly legal to pass `__generated_struct_NRF_P0`, -// and have the template call a well-known `static inline` function -// that returns `NRF_P0` ... which is itself a compile-time constant. -// -// Note that additional magic can be applied that will automatically -// generate the structures. If you want to add that to this platform, -// check out the KL26 platform files for a starting point. -// -*/ - -// manually define two structures, to avoid fighting with preprocessor macros -struct __generated_struct_NRF_P0 { - FASTLED_NRF52_INLINE_ATTRIBUTE constexpr static uintptr_t r() { - return NRF_P0_BASE; - } -}; -// Not all NRF52 chips have two ports. Only define if P1 is present. -#if defined(NRF_P1_BASE) -struct __generated_struct_NRF_P1 { - FASTLED_NRF52_INLINE_ATTRIBUTE constexpr static uintptr_t r() { - return NRF_P1_BASE; - } -}; -#endif - - -// The actual class template can then use a typename, for what is essentially a constexpr NRF_GPIO_Type* -template <uint32_t _MASK, typename _PORT, uint8_t _PORT_NUMBER, uint8_t _PIN_NUMBER> class _ARMPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - FASTLED_NRF52_INLINE_ATTRIBUTE static void setOutput() { - // OK for this to be more than one instruction, as unusual to quickly switch input/output modes - nrf_gpio_cfg( - nrf_pin(), - NRF_GPIO_PIN_DIR_OUTPUT, // set pin as output - NRF_GPIO_PIN_INPUT_DISCONNECT, // disconnect the input buffering - NRF_GPIO_PIN_NOPULL, // neither pull-up nor pull-down resistors enabled - NRF_GPIO_PIN_H0H1, // high drive mode required for faster speeds - NRF_GPIO_PIN_NOSENSE // pin sense level disabled - ); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void setInput() { - // OK for this to be more than one instruction, as unusual to quickly switch input/output modes - nrf_gpio_cfg( - nrf_pin(), - NRF_GPIO_PIN_DIR_INPUT, // set pin as input - NRF_GPIO_PIN_INPUT_DISCONNECT, // disconnect the input buffering - NRF_GPIO_PIN_NOPULL, // neither pull-up nor pull-down resistors enabled - NRF_GPIO_PIN_H0H1, // high drive mode required for faster speeds - NRF_GPIO_PIN_NOSENSE // pin sense level disabled - ); - } - FASTLED_NRF52_INLINE_ATTRIBUTE static void hi() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTSET = _MASK; } // sets _MASK in the SET OUTPUT register (output set high) - FASTLED_NRF52_INLINE_ATTRIBUTE static void lo() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTCLR = _MASK; } // sets _MASK in the CLEAR OUTPUT register (output set low) - FASTLED_NRF52_INLINE_ATTRIBUTE static void toggle() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT ^= _MASK; } // toggles _MASK bits in the OUTPUT GPIO port directly - FASTLED_NRF52_INLINE_ATTRIBUTE static void strobe() { toggle(); toggle(); } // BUGBUG -- Is this used by FastLED? Without knowing (for example) SPI Speed? - FASTLED_NRF52_INLINE_ATTRIBUTE static port_t hival() { return (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT | _MASK; } // sets all _MASK bit(s) in the OUTPUT GPIO port to 1 - FASTLED_NRF52_INLINE_ATTRIBUTE static port_t loval() { return (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT & ~_MASK; } // sets all _MASK bit(s) in the OUTPUT GPIO port to 0 - FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t port() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT); } // gets raw pointer to OUTPUT GPIO port - FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t cport() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTCLR); } // gets raw pointer to SET DIRECTION GPIO port - FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t sport() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTSET); } // gets raw pointer to CLEAR DIRECTION GPIO port - FASTLED_NRF52_INLINE_ATTRIBUTE static port_t mask() { return _MASK; } // gets the value of _MASK - FASTLED_NRF52_INLINE_ATTRIBUTE static void hi (register port_ptr_t port) { hi(); } // sets _MASK in the SET OUTPUT register (output set high) - FASTLED_NRF52_INLINE_ATTRIBUTE static void lo (register port_ptr_t port) { lo(); } // sets _MASK in the CLEAR OUTPUT register (output set low) - FASTLED_NRF52_INLINE_ATTRIBUTE static void set(register port_t val ) { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT = val; } // sets entire port's value (optimization used by FastLED) - FASTLED_NRF52_INLINE_ATTRIBUTE static void fastset(register port_ptr_t port, register port_t val) { *port = val; } - constexpr static uint32_t nrf_pin2() { return NRF_GPIO_PIN_MAP(_PORT_NUMBER, _PIN_NUMBER); } - constexpr static bool LowSpeedOnlyRecommended() { - // Caller must always determine if high speed use if allowed on a given pin, - // because it depends on more than just the chip packaging ... it depends on entire board (and even system) design. - return false; // choosing default to be FALSE, to allow users to ATTEMPT to use high-speed on pins where support is not known - } - // Expose the nrf pin (port/pin combined), port, and pin as properties (e.g., for setting up SPI) - - FASTLED_NRF52_INLINE_ATTRIBUTE static uint32_t nrf_pin() { return NRF_GPIO_PIN_MAP(_PORT_NUMBER, _PIN_NUMBER); } -}; - -// -// BOARD_PIN can be either the pin portion of a port.pin, or the combined NRF_GPIO_PIN_MAP() number. -// For example both the following two defines refer to P1.15 (pin 47) as Arduino pin 3: -// _FL_DEFPIN(3, 15, 1); -// _FL_DEFPIN(3, 47, 1); -// -// Similarly, the following defines are all equivalent: -// _DEFPIN_ARM_IDENTITY_P1(47); -// _FL_DEFPIN(47, 15, 1); -// _FL_DEFPIN(47, 47, 1); -// - -#define _FL_DEFPIN(ARDUINO_PIN, BOARD_PIN, BOARD_PORT) \ - template<> class FastPin<ARDUINO_PIN> : \ - public _ARMPIN< \ - 1u << (BOARD_PIN & 31u), \ - __generated_struct_NRF_P ## BOARD_PORT, \ - (BOARD_PIN / 32), \ - BOARD_PIN & 31u \ - > \ - {} - -#define _DEFPIN_ARM_IDENTITY_P0(ARDUINO_PIN) \ - template<> class FastPin<ARDUINO_PIN> : \ - public _ARMPIN< \ - 1u << (ARDUINO_PIN & 31u), \ - __generated_struct_NRF_P0, \ - 0, \ - (ARDUINO_PIN & 31u) + 0 \ - > \ - {} - -#define _DEFPIN_ARM_IDENTITY_P1(ARDUINO_PIN) \ - template<> class FastPin<ARDUINO_PIN> : \ - public _ARMPIN< \ - 1u << (ARDUINO_PIN & 31u), \ - __generated_struct_NRF_P1, \ - 1, \ - (ARDUINO_PIN & 31u) + 32 \ - > \ - {} - -// The actual pin definitions are in a separate header file... -#include "fastpin_arm_nrf52_variants.h" - -#define HAS_HARDWARE_PIN_SUPPORT - -#endif // #ifndef __FASTPIN_ARM_NRF52_H diff --git a/FastLED/src/platforms/arm/nrf52/fastpin_arm_nrf52_variants.h b/FastLED/src/platforms/arm/nrf52/fastpin_arm_nrf52_variants.h deleted file mode 100644 index 9020655c8a8bcff2c405366cb8e5b2c8f79a1696..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf52/fastpin_arm_nrf52_variants.h +++ /dev/null @@ -1,723 +0,0 @@ -#ifndef __FASTPIN_ARM_NRF52_VARIANTS_H -#define __FASTPIN_ARM_NRF52_VARIANTS_H - -// use this to determine if found variant or not (avoid multiple boards at once) -#undef __FASTPIN_ARM_NRF52_VARIANT_FOUND - -// Adafruit Bluefruit nRF52832 Feather -// From https://www.adafruit.com/package_adafruit_index.json -#if defined (ARDUINO_NRF52832_FEATHER) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Adafruit Bluefruit nRF52832 Feather is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - _DEFPIN_ARM_IDENTITY_P0( 0); // xtal 1 - _DEFPIN_ARM_IDENTITY_P0( 1); // xtal 2 - _DEFPIN_ARM_IDENTITY_P0( 2); // a0 - _DEFPIN_ARM_IDENTITY_P0( 3); // a1 - _DEFPIN_ARM_IDENTITY_P0( 4); // a2 - _DEFPIN_ARM_IDENTITY_P0( 5); // a3 - _DEFPIN_ARM_IDENTITY_P0( 6); // TXD - _DEFPIN_ARM_IDENTITY_P0( 7); // GPIO #7 - _DEFPIN_ARM_IDENTITY_P0( 8); // RXD - _DEFPIN_ARM_IDENTITY_P0( 9); // NFC1 - _DEFPIN_ARM_IDENTITY_P0(10); // NFC2 - _DEFPIN_ARM_IDENTITY_P0(11); // GPIO #11 - _DEFPIN_ARM_IDENTITY_P0(12); // SCK - _DEFPIN_ARM_IDENTITY_P0(13); // MOSI - _DEFPIN_ARM_IDENTITY_P0(14); // MISO - _DEFPIN_ARM_IDENTITY_P0(15); // GPIO #15 - _DEFPIN_ARM_IDENTITY_P0(16); // GPIO #16 - _DEFPIN_ARM_IDENTITY_P0(17); // LED #1 (red) - _DEFPIN_ARM_IDENTITY_P0(18); // SWO - _DEFPIN_ARM_IDENTITY_P0(19); // LED #2 (blue) - _DEFPIN_ARM_IDENTITY_P0(20); // DFU - // _DEFPIN_ARM_IDENTITY_P0(21); // Reset -- not valid to use for FastLED? - // _DEFPIN_ARM_IDENTITY_P0(22); // Factory Reset -- not vaild to use for FastLED? - // _DEFPIN_ARM_IDENTITY_P0(23); // N/A - // _DEFPIN_ARM_IDENTITY_P0(24); // N/A - _DEFPIN_ARM_IDENTITY_P0(25); // SDA - _DEFPIN_ARM_IDENTITY_P0(26); // SCL - _DEFPIN_ARM_IDENTITY_P0(27); // GPIO #27 - _DEFPIN_ARM_IDENTITY_P0(28); // A4 - _DEFPIN_ARM_IDENTITY_P0(29); // A5 - _DEFPIN_ARM_IDENTITY_P0(30); // A6 - _DEFPIN_ARM_IDENTITY_P0(31); // A7 -#endif // defined (ARDUINO_NRF52832_FEATHER) - -// Adafruit Circuit Playground Bluefruit -// From https://www.adafruit.com/package_adafruit_index.json -#if defined (ARDUINO_NRF52840_CIRCUITPLAY) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - - // This board is a bit of a mess ... as it defines - // multiple arduino pins to map to a single Port/Pin - // combination. - - // Use PIN_NEOPIXEL (D8) for the ten built-in neopixels - _FL_DEFPIN( 8, 13, 0); // P0.13 -- D8 / Neopixels - - // PIN_A0 is connect to an amplifier, and thus *might* - // not be suitable for use with FastLED. - // Do not enable this pin until can confirm - // signal integrity from this pin. - // - // NOTE: it might also be possible if first disable - // the amp using D11 ("speaker shutdown" pin) - // - // _FL_DEFPIN(14, 26, 0); // P0.26 -- A0 / D12 / Audio Out - _FL_DEFPIN(15, 2, 0); // P0.02 -- A1 / D6 - _FL_DEFPIN(16, 29, 0); // P0.29 -- A2 / D9 - _FL_DEFPIN(17, 3, 0); // P0.03 -- A3 / D10 - _FL_DEFPIN(18, 4, 0); // P0.04 -- A4 / D3 / SCL - _FL_DEFPIN(19, 5, 0); // P0.05 -- A5 / D2 / SDA - _FL_DEFPIN(20, 30, 0); // P0.30 -- A6 / D0 / UART RX - _FL_DEFPIN(21, 14, 0); // P0.14 -- AREF / D1 / UART TX - -#endif - -// Adafruit Bluefruit nRF52840 Feather Express -// From https://www.adafruit.com/package_adafruit_index.json -#if defined (ARDUINO_NRF52840_FEATHER) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - - // Arduino pins 0..7 - _FL_DEFPIN( 0, 25, 0); // D0 is P0.25 -- UART TX - //_FL_DEFPIN( 1, 24, 0); // D1 is P0.24 -- UART RX - _FL_DEFPIN( 2, 10, 0); // D2 is P0.10 -- NFC2 - _FL_DEFPIN( 3, 47, 1); // D3 is P1.15 -- PIN_LED1 (red) - _FL_DEFPIN( 4, 42, 1); // D4 is P1.10 -- PIN_LED2 (blue) - _FL_DEFPIN( 5, 40, 1); // D5 is P1.08 -- SPI/SS - _FL_DEFPIN( 6, 7, 0); // D6 is P0.07 - _FL_DEFPIN( 7, 34, 1); // D7 is P1.02 -- PIN_DFU (Button) - - // Arduino pins 8..15 - _FL_DEFPIN( 8, 16, 0); // D8 is P0.16 -- PIN_NEOPIXEL - _FL_DEFPIN( 9, 26, 0); // D9 is P0.26 - _FL_DEFPIN(10, 27, 0); // D10 is P0.27 - _FL_DEFPIN(11, 6, 0); // D11 is P0.06 - _FL_DEFPIN(12, 8, 0); // D12 is P0.08 - _FL_DEFPIN(13, 41, 1); // D13 is P1.09 - _FL_DEFPIN(14, 4, 0); // D14 is P0.04 -- A0 - _FL_DEFPIN(15, 5, 0); // D15 is P0.05 -- A1 - - // Arduino pins 16..23 - _FL_DEFPIN(16, 30, 0); // D16 is P0.30 -- A2 - _FL_DEFPIN(17, 28, 0); // D17 is P0.28 -- A3 - _FL_DEFPIN(18, 2, 0); // D18 is P0.02 -- A4 - _FL_DEFPIN(19, 3, 0); // D19 is P0.03 -- A5 - //_FL_DEFPIN(20, 29, 0); // D20 is P0.29 -- A6 -- Connected to battery! - //_FL_DEFPIN(21, 31, 0); // D21 is P0.31 -- A7 -- AREF - _FL_DEFPIN(22, 12, 0); // D22 is P0.12 -- SDA - _FL_DEFPIN(23, 11, 0); // D23 is P0.11 -- SCL - - // Arduino pins 24..31 - _FL_DEFPIN(24, 15, 0); // D24 is P0.15 -- PIN_SPI_MISO - _FL_DEFPIN(25, 13, 0); // D25 is P0.13 -- PIN_SPI_MOSI - _FL_DEFPIN(26, 14, 0); // D26 is P0.14 -- PIN_SPI_SCK - //_FL_DEFPIN(27, 19, 0); // D27 is P0.19 -- PIN_QSPI_SCK - //_FL_DEFPIN(28, 20, 0); // D28 is P0.20 -- PIN_QSPI_CS - //_FL_DEFPIN(29, 17, 0); // D29 is P0.17 -- PIN_QSPI_DATA0 - //_FL_DEFPIN(30, 22, 0); // D30 is P0.22 -- PIN_QSPI_DATA1 - //_FL_DEFPIN(31, 23, 0); // D31 is P0.23 -- PIN_QSPI_DATA2 - - // Arduino pins 32..34 - //_FL_DEFPIN(32, 21, 0); // D32 is P0.21 -- PIN_QSPI_DATA3 - //_FL_DEFPIN(33, 9, 0); // D33 is NFC1, only accessible via test point -#endif // defined (ARDUINO_NRF52840_FEATHER) - -// Adafruit Bluefruit nRF52840 Metro Express -// From https://www.adafruit.com/package_adafruit_index.json -#if defined (ARDUINO_NRF52840_METRO) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Adafruit Bluefruit nRF52840 Metro Express is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - _FL_DEFPIN( 0, 25, 0); // D0 is P0.25 (UART TX) - _FL_DEFPIN( 1, 24, 0); // D1 is P0.24 (UART RX) - _FL_DEFPIN( 2, 10, 1); // D2 is P1.10 - _FL_DEFPIN( 3, 4, 1); // D3 is P1.04 - _FL_DEFPIN( 4, 11, 1); // D4 is P1.11 - _FL_DEFPIN( 5, 12, 1); // D5 is P1.12 - _FL_DEFPIN( 6, 14, 1); // D6 is P1.14 - _FL_DEFPIN( 7, 26, 0); // D7 is P0.26 - _FL_DEFPIN( 8, 27, 0); // D8 is P0.27 - _FL_DEFPIN( 9, 12, 0); // D9 is P0.12 - _FL_DEFPIN(10, 6, 0); // D10 is P0.06 - _FL_DEFPIN(11, 8, 0); // D11 is P0.08 - _FL_DEFPIN(12, 9, 1); // D12 is P1.09 - _FL_DEFPIN(13, 14, 0); // D13 is P0.14 - _FL_DEFPIN(14, 4, 0); // D14 is P0.04 (A0) - _FL_DEFPIN(15, 5, 0); // D15 is P0.05 (A1) - _FL_DEFPIN(16, 28, 0); // D16 is P0.28 (A2) - _FL_DEFPIN(17, 30, 0); // D17 is P0.30 (A3) - _FL_DEFPIN(18, 2, 0); // D18 is P0.02 (A4) - _FL_DEFPIN(19, 3, 0); // D19 is P0.03 (A5) - _FL_DEFPIN(20, 29, 0); // D20 is P0.29 (A6, battery) - _FL_DEFPIN(21, 31, 0); // D21 is P0.31 (A7, ARef) - _FL_DEFPIN(22, 15, 0); // D22 is P0.15 (SDA) - _FL_DEFPIN(23, 16, 0); // D23 is P0.16 (SCL) - _FL_DEFPIN(24, 11, 0); // D24 is P0.11 (SPI MISO) - _FL_DEFPIN(25, 8, 1); // D25 is P1.08 (SPI MOSI) - _FL_DEFPIN(26, 7, 0); // D26 is P0.07 (SPI SCK ) - //_FL_DEFPIN(27, 19, 0); // D27 is P0.19 (QSPI CLK ) - //_FL_DEFPIN(28, 20, 0); // D28 is P0.20 (QSPI CS ) - //_FL_DEFPIN(29, 17, 0); // D29 is P0.17 (QSPI Data 0) - //_FL_DEFPIN(30, 23, 0); // D30 is P0.23 (QSPI Data 1) - //_FL_DEFPIN(31, 22, 0); // D31 is P0.22 (QSPI Data 2) - //_FL_DEFPIN(32, 21, 0); // D32 is P0.21 (QSPI Data 3) - _FL_DEFPIN(33, 13, 1); // D33 is P1.13 LED1 - _FL_DEFPIN(34, 15, 1); // D34 is P1.15 LED2 - _FL_DEFPIN(35, 13, 0); // D35 is P0.13 NeoPixel - _FL_DEFPIN(36, 0, 1); // D36 is P1.02 Switch - _FL_DEFPIN(37, 0, 1); // D37 is P1.00 SWO/DFU - _FL_DEFPIN(38, 9, 0); // D38 is P0.09 NFC1 - _FL_DEFPIN(39, 10, 0); // D39 is P0.10 NFC2 -#endif // defined (ARDUINO_NRF52840_METRO) - -// Adafruit Bluefruit on nRF52840DK PCA10056 -// From https://www.adafruit.com/package_adafruit_index.json -#if defined (ARDUINO_NRF52840_PCA10056) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - - #if defined(USE_ARDUINO_PIN_NUMBERING) - #error "Define of `USE_ARDUINO_PIN_NUMBERING` has known errors in pin mapping -- select different mapping" - #elif defined(FASTLED_NRF52_USE_ARDUINO_UNO_R3_HEADER_PIN_NUMBERING) - /* The following allows defining and using the FastPin<> templates, - using the Arduino UNO R3 connector pin definitions. - */ - _FL_DEFPIN( 0, 1, 1); // D0 is P1.01 - _FL_DEFPIN( 1, 2, 1); // D1 is P1.02 - _FL_DEFPIN( 2, 3, 1); // D2 is P1.03 - _FL_DEFPIN( 3, 4, 1); // D3 is P1.04 - _FL_DEFPIN( 4, 5, 1); // D4 is P1.05 - _FL_DEFPIN( 5, 6, 1); // D5 is P1.06 - _FL_DEFPIN( 6, 7, 1); // D6 is P1.07 (BUTTON1 option) - _FL_DEFPIN( 7, 8, 1); // D7 is P1.08 (BUTTON2 option) - _FL_DEFPIN( 8, 10, 1); // D8 is P1.10 - _FL_DEFPIN( 9, 11, 1); // D9 is P1.11 - _FL_DEFPIN(10, 12, 1); // D10 is P1.12 - _FL_DEFPIN(11, 13, 1); // D11 is P1.13 - _FL_DEFPIN(12, 14, 1); // D12 is P1.14 - _FL_DEFPIN(13, 15, 1); // D13 is P1.15 - // Arduino UNO uses pins D14..D19 to map to header pins A0..A5 - // AREF has no equivalent digital pin map on Arduino, would be P0.02 - _FL_DEFPIN(14, 3, 0); // D14 / A0 is P0.03 - _FL_DEFPIN(15, 4, 0); // D15 / A1 is P0.04 - _FL_DEFPIN(16, 28, 0); // D16 / A2 is P0.28 - _FL_DEFPIN(17, 29, 0); // D17 / A3 is P0.29 - // Cannot determine which pin on PCA10056 would be intended solely from UNO R3 digital pin number - //_FL_DEFPIN(18, 30, 0); // D18 could be one of two pins: A4 would be P0.30, SDA would be P0.26 - //_FL_DEFPIN(19, 31, 0); // D19 could be one of two pins: A5 would be P0.31, SCL would be P0.27 - #elif defined(FASTLED_NRF52_USE_ARDUINO_MEGA_2560_REV3_HEADER_PIN_NUMBERING) - /* The following allows defining and using the FastPin<> templates, - using the Arduino UNO R3 connector pin definitions. - */ - _FL_DEFPIN( 0, 1, 1); // D0 is P1.01 - _FL_DEFPIN( 1, 2, 1); // D1 is P1.02 - _FL_DEFPIN( 2, 3, 1); // D2 is P1.03 - _FL_DEFPIN( 3, 4, 1); // D3 is P1.04 - _FL_DEFPIN( 4, 5, 1); // D4 is P1.05 - _FL_DEFPIN( 5, 6, 1); // D5 is P1.06 - _FL_DEFPIN( 6, 7, 1); // D6 is P1.07 (BUTTON1 option) - _FL_DEFPIN( 7, 8, 1); // D7 is P1.08 (BUTTON2 option) - _FL_DEFPIN( 8, 10, 1); // D8 is P1.10 - _FL_DEFPIN( 9, 11, 1); // D9 is P1.11 - _FL_DEFPIN(10, 12, 1); // D10 is P1.12 - _FL_DEFPIN(11, 13, 1); // D11 is P1.13 - _FL_DEFPIN(12, 14, 1); // D12 is P1.14 - _FL_DEFPIN(13, 15, 1); // D13 is P1.15 - - // Arduino MEGA 2560 has additional digital pins on lower digital header - _FL_DEFPIN(14, 10, 0); // D14 is P0.10 - _FL_DEFPIN(15, 9, 0); // D15 is P0.09 - _FL_DEFPIN(16, 8, 0); // D16 is P0.08 - _FL_DEFPIN(17, 7, 0); // D17 is P0.07 - _FL_DEFPIN(18, 6, 0); // D14 is P0.06 - _FL_DEFPIN(19, 5, 0); // D15 is P0.05 - // Cannot determine which pin on PCA10056 would be intended solely from UNO MEGA 2560 digital pin number - //_FL_DEFPIN(20, 1, 0); // D20 could be one of two pins: D20 on lower header would be P0.01, SDA would be P0.26 - //_FL_DEFPIN(21, 0, 0); // D21 could be one of two pins: D21 on lower header would be P0.00, SCL would be P0.27 - - // Arduino MEGA 2560 has D22-D53 exposed on perpendicular two-row header - // PCA10056 has support for D22-D38 via a 2x19 header at that location (D39 is GND on PCA10056) - _FL_DEFPIN(22, 11, 0); // D22 is P0.11 - _FL_DEFPIN(23, 12, 0); // D23 is P0.12 - _FL_DEFPIN(24, 13, 0); // D24 is P0.13 - _FL_DEFPIN(25, 14, 0); // D25 is P0.14 - _FL_DEFPIN(26, 15, 0); // D26 is P0.15 - _FL_DEFPIN(27, 16, 0); // D27 is P0.16 - // _FL_DEFPIN(28, 17, 0); // D28 is P0.17 (QSPI !CS ) - // _FL_DEFPIN(29, 18, 0); // D29 is P0.18 (RESET) - // _FL_DEFPIN(30, 19, 0); // D30 is P0.19 (QSPI CLK) - // _FL_DEFPIN(31, 20, 0); // D31 is P0.20 (QSPI DIO0) - // _FL_DEFPIN(32, 21, 0); // D32 is P0.21 (QSPI DIO1) - // _FL_DEFPIN(33, 22, 0); // D33 is P0.22 (QSPI DIO2) - // _FL_DEFPIN(34, 23, 0); // D34 is P0.23 (QSPI DIO3) - _FL_DEFPIN(35, 24, 0); // D35 is P0.24 - _FL_DEFPIN(36, 25, 0); // D36 is P0.25 - _FL_DEFPIN(37, 0, 1); // D37 is P1.00 - _FL_DEFPIN(38, 9, 1); // D38 is P1.09 - // _FL_DEFPIN(39, , 0); // D39 is P0. - - - // Arduino MEGA 2560 uses pins D54..D59 to map to header pins A0..A5 - // (it also has D60..D69 for A6..A15, which have no corresponding header on PCA10056) - // AREF has no equivalent digital pin map on Arduino, would be P0.02 - _FL_DEFPIN(54, 3, 0); // D54 / A0 is P0.03 - _FL_DEFPIN(55, 4, 0); // D55 / A1 is P0.04 - _FL_DEFPIN(56, 28, 0); // D56 / A2 is P0.28 - _FL_DEFPIN(57, 29, 0); // D57 / A3 is P0.29 - _FL_DEFPIN(58, 30, 0); // D58 / A4 is P0.30 - _FL_DEFPIN(59, 31, 0); // D59 / A5 is P0.31 - - #else // identity mapping of arduino pin to port/pin - /* 48 pins, defined using natural mapping in Adafruit's variant.cpp (!) */ - _DEFPIN_ARM_IDENTITY_P0( 0); // P0.00 (XL1 .. ensure SB4 bridged, SB2 cut) - _DEFPIN_ARM_IDENTITY_P0( 1); // P0.01 (XL2 .. ensure SB3 bridged, SB1 cut) - _DEFPIN_ARM_IDENTITY_P0( 2); // P0.02 (AIN0) - _DEFPIN_ARM_IDENTITY_P0( 3); // P0.03 (AIN1) - _DEFPIN_ARM_IDENTITY_P0( 4); // P0.04 (AIN2 / UART CTS option) - _DEFPIN_ARM_IDENTITY_P0( 5); // P0.05 (AIN3 / UART RTS) - _DEFPIN_ARM_IDENTITY_P0( 6); // P0.06 (UART TxD) - _DEFPIN_ARM_IDENTITY_P0( 7); // P0.07 (TRACECLK / UART CTS default) - _DEFPIN_ARM_IDENTITY_P0( 8); // P0.08 (UART RxD) - _DEFPIN_ARM_IDENTITY_P0( 9); // P0.09 (NFC1) - _DEFPIN_ARM_IDENTITY_P0(10); // P0.10 (NFC2) - _DEFPIN_ARM_IDENTITY_P0(11); // P0.11 (TRACEDATA2 / BUTTON1 default) - _DEFPIN_ARM_IDENTITY_P0(12); // P0.12 (TRACEDATA1 / BUTTON2 default) - _DEFPIN_ARM_IDENTITY_P0(13); // P0.13 (LED1) - _DEFPIN_ARM_IDENTITY_P0(14); // P0.14 (LED2) - _DEFPIN_ARM_IDENTITY_P0(15); // P0.15 (LED3) - _DEFPIN_ARM_IDENTITY_P0(16); // P0.16 (LED4) - //_DEFPIN_ARM_IDENTITY_P0(17); // P0.17 (QSPI !CS ) - //_DEFPIN_ARM_IDENTITY_P0(18); // P0.18 (RESET) - //_DEFPIN_ARM_IDENTITY_P0(19); // P0.19 (QSPI CLK ) - //_DEFPIN_ARM_IDENTITY_P0(20); // P0.20 (QSPI DIO0) - //_DEFPIN_ARM_IDENTITY_P0(21); // P0.21 (QSPI DIO1) - //_DEFPIN_ARM_IDENTITY_P0(22); // P0.22 (QSPI DIO2) - //_DEFPIN_ARM_IDENTITY_P0(23); // P0.23 (QSPI DIO3) - _DEFPIN_ARM_IDENTITY_P0(24); // P0.24 (BUTTON3) - _DEFPIN_ARM_IDENTITY_P0(25); // P0.25 (BUTTON4) - _DEFPIN_ARM_IDENTITY_P0(26); // P0.26 - _DEFPIN_ARM_IDENTITY_P0(27); // P0.27 - _DEFPIN_ARM_IDENTITY_P0(28); // P0.28 (AIN4) - _DEFPIN_ARM_IDENTITY_P0(29); // P0.29 (AIN5) - _DEFPIN_ARM_IDENTITY_P0(30); // P0.30 (AIN6) - _DEFPIN_ARM_IDENTITY_P0(31); // P0.31 (AIN7) - _DEFPIN_ARM_IDENTITY_P0(32); // P1.00 (SWO / TRACEDATA0) - _DEFPIN_ARM_IDENTITY_P0(33); // P1.01 - _DEFPIN_ARM_IDENTITY_P0(34); // P1.02 - _DEFPIN_ARM_IDENTITY_P0(35); // P1.03 - _DEFPIN_ARM_IDENTITY_P0(36); // P1.04 - _DEFPIN_ARM_IDENTITY_P0(37); // P1.05 - _DEFPIN_ARM_IDENTITY_P0(38); // P1.06 - _DEFPIN_ARM_IDENTITY_P0(39); // P1.07 (BUTTON1 option) - _DEFPIN_ARM_IDENTITY_P0(40); // P1.08 (BUTTON2 option) - _DEFPIN_ARM_IDENTITY_P0(41); // P1.09 (TRACEDATA3) - _DEFPIN_ARM_IDENTITY_P0(42); // P1.10 - _DEFPIN_ARM_IDENTITY_P0(43); // P1.11 - _DEFPIN_ARM_IDENTITY_P0(44); // P1.12 - _DEFPIN_ARM_IDENTITY_P0(45); // P1.13 - _DEFPIN_ARM_IDENTITY_P0(46); // P1.14 - _DEFPIN_ARM_IDENTITY_P0(47); // P1.15 - #endif -#endif // defined (ARDUINO_NRF52840_PCA10056) - -// Adafruit ItsyBitsy nRF52840 Express -// From https://www.adafruit.com/package_adafruit_index.json -#if defined (ARDUINO_NRF52_ITSYBITSY) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Adafruit ItsyBitsy nRF52840 Express is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - - // [D0 .. D13] (digital) - _FL_DEFPIN( 0, 25, 0); // D0 is P0.25 (UART RX) - _FL_DEFPIN( 1, 24, 0); // D1 is P0.24 (UART TX) - _FL_DEFPIN( 2, 2, 1); // D2 is P1.02 - _FL_DEFPIN( 3, 6, 0); // D3 is P0.06 LED - _FL_DEFPIN( 4, 29, 0); // D4 is P0.29 Button - _FL_DEFPIN( 5, 27, 0); // D5 is P0.27 - _FL_DEFPIN( 6, 9, 1); // D6 is P1.09 (DotStar Clock) - _FL_DEFPIN( 7, 8, 1); // D7 is P1.08 - _FL_DEFPIN( 8, 8, 0); // D8 is P0.08 (DotStar Data) - _FL_DEFPIN( 9, 7, 0); // D9 is P0.07 - _FL_DEFPIN(10, 5, 0); // D10 is P0.05 - _FL_DEFPIN(11, 26, 0); // D11 is P0.26 - _FL_DEFPIN(12, 11, 0); // D12 is P0.11 - _FL_DEFPIN(13, 12, 0); // D13 is P0.12 - - // [D14 .. D20] (analog [A0 .. A6]) - _FL_DEFPIN(14, 4, 0); // D14 is P0.04 (A0) - _FL_DEFPIN(15, 30, 0); // D15 is P0.30 (A1) - _FL_DEFPIN(16, 28, 0); // D16 is P0.28 (A2) - _FL_DEFPIN(17, 31, 0); // D17 is P0.31 (A3) - _FL_DEFPIN(18, 2, 0); // D18 is P0.02 (A4) - _FL_DEFPIN(19, 3, 0); // D19 is P0.03 (A5) - _FL_DEFPIN(20, 5, 0); // D20 is P0.05 (A6/D10) - - // [D21 .. D22] (I2C) - _FL_DEFPIN(21, 16, 0); // D21 is P0.16 (SDA) - _FL_DEFPIN(22, 14, 0); // D22 is P0.14 (SCL) - - // [D23 .. D25] (SPI) - _FL_DEFPIN(23, 20, 0); // D23 is P0.20 (SPI MISO) - _FL_DEFPIN(24, 15, 0); // D24 is P0.15 (SPI MOSI) - _FL_DEFPIN(25, 13, 0); // D25 is P0.13 (SPI SCK ) - - // [D26 .. D31] (QSPI) - _FL_DEFPIN(26, 19, 0); // D26 is P0.19 (QSPI CLK) - _FL_DEFPIN(27, 23, 0); // D27 is P0.23 (QSPI CS) - _FL_DEFPIN(28, 21, 0); // D28 is P0.21 (QSPI Data 0) - _FL_DEFPIN(29, 22, 0); // D29 is P0.22 (QSPI Data 1) - _FL_DEFPIN(30, 0, 1); // D30 is P1.00 (QSPI Data 2) - _FL_DEFPIN(31, 17, 0); // D31 is P0.17 (QSPI Data 3) - -#endif // defined (ARDUINO_NRF52_ITSYBITSY) - -// Electronut labs bluey -// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/bluey/variant.cpp -#if defined(ARDUINO_ELECTRONUT_BLUEY) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Electronut labs bluey is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - _FL_DEFPIN( 0, 26, 0); // D0 is P0.26 - _FL_DEFPIN( 1, 27, 0); // D1 is P0.27 - _FL_DEFPIN( 2, 22, 0); // D2 is P0.22 (SPI SS ) - _FL_DEFPIN( 3, 23, 0); // D3 is P0.23 (SPI MOSI) - _FL_DEFPIN( 4, 24, 0); // D4 is P0.24 (SPI MISO, also A3) - _FL_DEFPIN( 5, 25, 0); // D5 is P0.25 (SPI SCK ) - _FL_DEFPIN( 6, 16, 0); // D6 is P0.16 (Button) - _FL_DEFPIN( 7, 19, 0); // D7 is P0.19 (R) - _FL_DEFPIN( 8, 18, 0); // D8 is P0.18 (G) - _FL_DEFPIN( 9, 17, 0); // D9 is P0.17 (B) - _FL_DEFPIN(10, 11, 0); // D10 is P0.11 (SCL) - _FL_DEFPIN(11, 12, 0); // D11 is P0.12 (DRDYn) - _FL_DEFPIN(12, 13, 0); // D12 is P0.13 (SDA) - _FL_DEFPIN(13, 14, 0); // D13 is P0.17 (INT) - _FL_DEFPIN(14, 15, 0); // D14 is P0.15 (INT1) - _FL_DEFPIN(15, 20, 0); // D15 is P0.20 (INT2) - _FL_DEFPIN(16, 2, 0); // D16 is P0.02 (A0) - _FL_DEFPIN(17, 3, 0); // D17 is P0.03 (A1) - _FL_DEFPIN(18, 4, 0); // D18 is P0.04 (A2) - _FL_DEFPIN(19, 24, 0); // D19 is P0.24 (A3, also D4/SPI MISO) -- is this right? - _FL_DEFPIN(20, 29, 0); // D20 is P0.29 (A4) - _FL_DEFPIN(21, 30, 0); // D21 is P0.30 (A5) - _FL_DEFPIN(22, 31, 0); // D22 is P0.31 (A6) - _FL_DEFPIN(23, 8, 0); // D23 is P0.08 (RX) - _FL_DEFPIN(24, 6, 0); // D24 is P0.06 (TX) - _FL_DEFPIN(25, 5, 0); // D25 is P0.05 (RTS) - _FL_DEFPIN(26, 7, 0); // D26 is P0.07 (CTS) -#endif // defined(ARDUINO_ELECTRONUT_BLUEY) - -// Electronut labs hackaBLE -// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/hackaBLE/variant.cpp -#if defined(ARDUINO_ELECTRONUT_HACKABLE) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Electronut labs hackaBLE is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - _FL_DEFPIN( 0, 14, 0); // D0 is P0.14 (RX) - _FL_DEFPIN( 1, 13, 0); // D1 is P0.13 (TX) - _FL_DEFPIN( 2, 12, 0); // D2 is P0.12 - _FL_DEFPIN( 3, 11, 0); // D3 is P0.11 (SPI MOSI) - _FL_DEFPIN( 4, 8, 0); // D4 is P0.08 (SPI MISO) - _FL_DEFPIN( 5, 7, 0); // D5 is P0.07 (SPI SCK ) - _FL_DEFPIN( 6, 6, 0); // D6 is P0.06 - _FL_DEFPIN( 7, 27, 0); // D7 is P0.27 - _FL_DEFPIN( 8, 26, 0); // D8 is P0.26 - _FL_DEFPIN( 9, 25, 0); // D9 is P0.25 - _FL_DEFPIN(10, 5, 0); // D10 is P0.05 (A3) - _FL_DEFPIN(11, 4, 0); // D11 is P0.04 (A2) - _FL_DEFPIN(12, 3, 0); // D12 is P0.03 (A1) - _FL_DEFPIN(13, 2, 0); // D13 is P0.02 (A0 / AREF) - _FL_DEFPIN(14, 23, 0); // D14 is P0.23 - _FL_DEFPIN(15, 22, 0); // D15 is P0.22 - _FL_DEFPIN(16, 18, 0); // D16 is P0.18 - _FL_DEFPIN(17, 16, 0); // D17 is P0.16 - _FL_DEFPIN(18, 15, 0); // D18 is P0.15 - _FL_DEFPIN(19, 24, 0); // D19 is P0.24 - _FL_DEFPIN(20, 28, 0); // D20 is P0.28 (A4) - _FL_DEFPIN(21, 29, 0); // D21 is P0.29 (A5) - _FL_DEFPIN(22, 30, 0); // D22 is P0.30 (A6) - _FL_DEFPIN(23, 31, 0); // D23 is P0.31 (A7) - _FL_DEFPIN(24, 19, 0); // D24 is P0.19 (RED LED) - _FL_DEFPIN(25, 20, 0); // D25 is P0.20 (GREEN LED) - _FL_DEFPIN(26, 17, 0); // D26 is P0.17 (BLUE LED) -#endif // defined(ARDUINO_ELECTRONUT_HACKABLE) - -// Electronut labs hackaBLE_v2 -// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/hackaBLE_v2/variant.cpp -// (32 pins, natural mapping) -#if defined(ARDUINO_ELECTRONUT_hackaBLE_v2) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Electronut labs hackaBLE_v2 is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - _DEFPIN_ARM_IDENTITY_P0( 0); // P0.00 - _DEFPIN_ARM_IDENTITY_P0( 1); // P0.01 - _DEFPIN_ARM_IDENTITY_P0( 2); // P0.02 (A0 / SDA / AREF) - _DEFPIN_ARM_IDENTITY_P0( 3); // P0.03 (A1 / SCL ) - _DEFPIN_ARM_IDENTITY_P0( 4); // P0.04 (A2) - _DEFPIN_ARM_IDENTITY_P0( 5); // P0.05 (A3) - _DEFPIN_ARM_IDENTITY_P0( 6); // P0.06 - _DEFPIN_ARM_IDENTITY_P0( 7); // P0.07 (RX) - _DEFPIN_ARM_IDENTITY_P0( 8); // P0.08 (TX) - _DEFPIN_ARM_IDENTITY_P0( 9); // P0.09 - _DEFPIN_ARM_IDENTITY_P0(10); // P0.10 - _DEFPIN_ARM_IDENTITY_P0(11); // P0.11 (SPI MISO) - _DEFPIN_ARM_IDENTITY_P0(12); // P0.12 (SPI MOSI) - _DEFPIN_ARM_IDENTITY_P0(13); // P0.13 (SPI SCK ) - _DEFPIN_ARM_IDENTITY_P0(14); // P0.14 (SPI SS ) - _DEFPIN_ARM_IDENTITY_P0(15); // P0.15 - _DEFPIN_ARM_IDENTITY_P0(16); // P0.16 - _DEFPIN_ARM_IDENTITY_P0(17); // P0.17 (BLUE LED) - _DEFPIN_ARM_IDENTITY_P0(18); // P0.18 - _DEFPIN_ARM_IDENTITY_P0(19); // P0.19 (RED LED) - _DEFPIN_ARM_IDENTITY_P0(20); // P0.20 (GREEN LED) - // _DEFPIN_ARM_IDENTITY_P0(21); // P0.21 (RESET) - _DEFPIN_ARM_IDENTITY_P0(22); // P0.22 - _DEFPIN_ARM_IDENTITY_P0(23); // P0.23 - _DEFPIN_ARM_IDENTITY_P0(24); // P0.24 - _DEFPIN_ARM_IDENTITY_P0(25); // P0.25 - _DEFPIN_ARM_IDENTITY_P0(26); // P0.26 - _DEFPIN_ARM_IDENTITY_P0(27); // P0.27 - _DEFPIN_ARM_IDENTITY_P0(28); // P0.28 (A4) - _DEFPIN_ARM_IDENTITY_P0(29); // P0.29 (A5) - _DEFPIN_ARM_IDENTITY_P0(30); // P0.30 (A6) - _DEFPIN_ARM_IDENTITY_P0(31); // P0.31 (A7) -#endif // defined(ARDUINO_ELECTRONUT_hackaBLE_v2) - -// RedBear Blend 2 -// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/RedBear_Blend2/variant.cpp -#if defined(ARDUINO_RB_BLEND_2) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "RedBear Blend 2 is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - _FL_DEFPIN( 0, 11, 0); // D0 is P0.11 - _FL_DEFPIN( 1, 12, 0); // D1 is P0.12 - _FL_DEFPIN( 2, 13, 0); // D2 is P0.13 - _FL_DEFPIN( 3, 14, 0); // D3 is P0.14 - _FL_DEFPIN( 4, 15, 0); // D4 is P0.15 - _FL_DEFPIN( 5, 16, 0); // D5 is P0.16 - _FL_DEFPIN( 6, 17, 0); // D6 is P0.17 - _FL_DEFPIN( 7, 18, 0); // D7 is P0.18 - _FL_DEFPIN( 8, 19, 0); // D8 is P0.19 - _FL_DEFPIN( 9, 20, 0); // D9 is P0.20 - _FL_DEFPIN(10, 22, 0); // D10 is P0.22 (SPI SS ) - _FL_DEFPIN(11, 23, 0); // D11 is P0.23 (SPI MOSI) - _FL_DEFPIN(12, 24, 0); // D12 is P0.24 (SPI MISO) - _FL_DEFPIN(13, 25, 0); // D13 is P0.25 (SPI SCK / LED) - _FL_DEFPIN(14, 3, 0); // D14 is P0.03 (A0) - _FL_DEFPIN(15, 4, 0); // D15 is P0.04 (A1) - _FL_DEFPIN(16, 28, 0); // D16 is P0.28 (A2) - _FL_DEFPIN(17, 29, 0); // D17 is P0.29 (A3) - _FL_DEFPIN(18, 30, 0); // D18 is P0.30 (A4) - _FL_DEFPIN(19, 31, 0); // D19 is P0.31 (A5) - _FL_DEFPIN(20, 26, 0); // D20 is P0.26 (SDA) - _FL_DEFPIN(21, 27, 0); // D21 is P0.27 (SCL) - _FL_DEFPIN(22, 8, 0); // D22 is P0.08 (RX) - _FL_DEFPIN(23, 6, 0); // D23 is P0.06 (TX) - _FL_DEFPIN(24, 2, 0); // D24 is P0.02 (AREF) -#endif // defined(ARDUINO_RB_BLEND_2) - -// RedBear BLE Nano 2 -// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/RedBear_BLENano2/variant.cpp -#if defined(ARDUINO_RB_BLE_NANO_2) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "RedBear BLE Nano 2 is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - _FL_DEFPIN( 0, 30, 0); // D0 is P0.30 (A0 / RX) - _FL_DEFPIN( 1, 29, 0); // D1 is P0.29 (A1 / TX) - _FL_DEFPIN( 2, 28, 0); // D2 is P0.28 (A2 / SDA) - _FL_DEFPIN( 3, 2, 0); // D3 is P0.02 (A3 / SCL) - _FL_DEFPIN( 4, 5, 0); // D4 is P0.05 (A4) - _FL_DEFPIN( 5, 4, 0); // D5 is P0.04 (A5) - _FL_DEFPIN( 6, 3, 0); // D6 is P0.03 (SPI SS ) - _FL_DEFPIN( 7, 6, 0); // D7 is P0.06 (SPI MOSI) - _FL_DEFPIN( 8, 7, 0); // D8 is P0.07 (SPI MISO) - _FL_DEFPIN( 9, 8, 0); // D9 is P0.08 (SPI SCK ) - // _FL_DEFPIN(10, 21, 0); // D10 is P0.21 (RESET) - _FL_DEFPIN(13, 11, 0); // D11 is P0.11 (LED) -#endif // defined(ARDUINO_RB_BLE_NANO_2) - -// Nordic Semiconductor nRF52 DK -// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/nRF52DK/variant.cpp -#if defined(ARDUINO_NRF52_DK) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Nordic Semiconductor nRF52 DK is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - _FL_DEFPIN( 0, 11, 0); // D0 is P0.11 - _FL_DEFPIN( 1, 12, 0); // D1 is P0.12 - _FL_DEFPIN( 2, 13, 0); // D2 is P0.13 (BUTTON1) - _FL_DEFPIN( 3, 14, 0); // D3 is P0.14 (BUTTON2) - _FL_DEFPIN( 4, 15, 0); // D4 is P0.15 (BUTTON3) - _FL_DEFPIN( 5, 16, 0); // D5 is P0.16 (BUTTON4) - _FL_DEFPIN( 6, 17, 0); // D6 is P0.17 (LED1) - _FL_DEFPIN( 7, 18, 0); // D7 is P0.18 (LED2) - _FL_DEFPIN( 8, 19, 0); // D8 is P0.19 (LED3) - _FL_DEFPIN( 9, 20, 0); // D9 is P0.20 (LED4) - _FL_DEFPIN(10, 22, 0); // D10 is P0.22 (SPI SS ) - _FL_DEFPIN(11, 23, 0); // D11 is P0.23 (SPI MOSI) - _FL_DEFPIN(12, 24, 0); // D12 is P0.24 (SPI MISO) - _FL_DEFPIN(13, 25, 0); // D13 is P0.25 (SPI SCK / LED) - _FL_DEFPIN(14, 3, 0); // D14 is P0.03 (A0) - _FL_DEFPIN(15, 4, 0); // D15 is P0.04 (A1) - _FL_DEFPIN(16, 28, 0); // D16 is P0.28 (A2) - _FL_DEFPIN(17, 29, 0); // D17 is P0.29 (A3) - _FL_DEFPIN(18, 30, 0); // D18 is P0.30 (A4) - _FL_DEFPIN(19, 31, 0); // D19 is P0.31 (A5) - _FL_DEFPIN(20, 5, 0); // D20 is P0.05 (A6) - _FL_DEFPIN(21, 2, 0); // D21 is P0.02 (A7 / AREF) - _FL_DEFPIN(22, 26, 0); // D22 is P0.26 (SDA) - _FL_DEFPIN(23, 27, 0); // D23 is P0.27 (SCL) - _FL_DEFPIN(24, 8, 0); // D24 is P0.08 (RX) - _FL_DEFPIN(25, 6, 0); // D25 is P0.06 (TX) -#endif // defined(ARDUINO_NRF52_DK) - -// Taida Century nRF52 mini board -// https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/Taida_Century_nRF52_minidev/variant.cpp -#if defined(ARDUINO_STCT_NRF52_minidev) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Taida Century nRF52 mini board is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - //_FL_DEFPIN( 0, 25, 0); // D0 is P0.xx (near radio!) - //_FL_DEFPIN( 1, 26, 0); // D1 is P0.xx (near radio!) - //_FL_DEFPIN( 2, 27, 0); // D2 is P0.xx (near radio!) - //_FL_DEFPIN( 3, 28, 0); // D3 is P0.xx (near radio!) - //_FL_DEFPIN( 4, 29, 0); // D4 is P0.xx (Not connected, near radio!) - //_FL_DEFPIN( 5, 30, 0); // D5 is P0.xx (LED1, near radio!) - //_FL_DEFPIN( 6, 31, 0); // D6 is P0.xx (LED2, near radio!) - _FL_DEFPIN( 7, 2, 0); // D7 is P0.xx (SDA) - _FL_DEFPIN( 8, 3, 0); // D8 is P0.xx (SCL) - _FL_DEFPIN( 9, 4, 0); // D9 is P0.xx (BUTTON1 / NFC1) - _FL_DEFPIN(10, 5, 0); // D10 is P0.xx - //_FL_DEFPIN(11, 0, 0); // D11 is P0.xx (Not connected) - //_FL_DEFPIN(12, 1, 0); // D12 is P0.xx (Not connected) - _FL_DEFPIN(13, 6, 0); // D13 is P0.xx - _FL_DEFPIN(14, 7, 0); // D14 is P0.xx - _FL_DEFPIN(15, 8, 0); // D15 is P0.xx - //_FL_DEFPIN(16, 9, 0); // D16 is P0.xx (Not connected) - //_FL_DEFPIN(17, 10, 0); // D17 is P0.xx (NFC2, Not connected) - _FL_DEFPIN(18, 11, 0); // D18 is P0.xx (RXD) - _FL_DEFPIN(19, 12, 0); // D19 is P0.xx (TXD) - _FL_DEFPIN(20, 13, 0); // D20 is P0.xx (SPI SS ) - _FL_DEFPIN(21, 14, 0); // D21 is P0.xx (SPI MISO) - _FL_DEFPIN(22, 15, 0); // D22 is P0.xx (SPI MOSI) - _FL_DEFPIN(23, 16, 0); // D23 is P0.xx (SPI SCK ) - _FL_DEFPIN(24, 17, 0); // D24 is P0.xx (A0) - _FL_DEFPIN(25, 18, 0); // D25 is P0.xx (A1) - _FL_DEFPIN(26, 19, 0); // D26 is P0.xx (A2) - _FL_DEFPIN(27, 20, 0); // D27 is P0.xx (A3) - //_FL_DEFPIN(28, 22, 0); // D28 is P0.xx (A4, near radio!) - //_FL_DEFPIN(29, 23, 0); // D29 is P0.xx (A5, near radio!) - _FL_DEFPIN(30, 24, 0); // D30 is P0.xx - // _FL_DEFPIN(31, 21, 0); // D31 is P0.21 (RESET) -#endif // defined(ARDUINO_STCT_NRF52_minidev) - -// Generic nRF52832 -// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/boards.txt -#if defined(ARDUINO_GENERIC) && ( defined(NRF52832_XXAA) || defined(NRF52832_XXAB) ) - #if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND) - #error "Cannot define more than one board at a time" - #else - #define __FASTPIN_ARM_NRF52_VARIANT_FOUND - #endif - #if !defined(FASTLED_NRF52_SUPPRESS_UNTESTED_BOARD_WARNING) - #warning "Using `generic` NRF52832 board is an untested configuration -- test and let use know your results via https://github.com/FastLED/FastLED/issues" - #endif - - _DEFPIN_ARM_IDENTITY_P0( 0); // P0.00 ( UART RX - _DEFPIN_ARM_IDENTITY_P0( 1); // P0.01 (A0, UART TX) - _DEFPIN_ARM_IDENTITY_P0( 2); // P0.02 (A1) - _DEFPIN_ARM_IDENTITY_P0( 3); // P0.03 (A2) - _DEFPIN_ARM_IDENTITY_P0( 4); // P0.04 (A3) - _DEFPIN_ARM_IDENTITY_P0( 5); // P0.05 (A4) - _DEFPIN_ARM_IDENTITY_P0( 6); // P0.06 (A5) - _DEFPIN_ARM_IDENTITY_P0( 7); // P0.07 - _DEFPIN_ARM_IDENTITY_P0( 8); // P0.08 - _DEFPIN_ARM_IDENTITY_P0( 9); // P0.09 - _DEFPIN_ARM_IDENTITY_P0(10); // P0.10 - _DEFPIN_ARM_IDENTITY_P0(11); // P0.11 - _DEFPIN_ARM_IDENTITY_P0(12); // P0.12 - _DEFPIN_ARM_IDENTITY_P0(13); // P0.13 (LED) - _DEFPIN_ARM_IDENTITY_P0(14); // P0.14 - _DEFPIN_ARM_IDENTITY_P0(15); // P0.15 - _DEFPIN_ARM_IDENTITY_P0(16); // P0.16 - _DEFPIN_ARM_IDENTITY_P0(17); // P0.17 - _DEFPIN_ARM_IDENTITY_P0(18); // P0.18 - _DEFPIN_ARM_IDENTITY_P0(19); // P0.19 - _DEFPIN_ARM_IDENTITY_P0(20); // P0.20 (I2C SDA) - _DEFPIN_ARM_IDENTITY_P0(21); // P0.21 (I2C SCL) - _DEFPIN_ARM_IDENTITY_P0(22); // P0.22 (SPI MISO) - _DEFPIN_ARM_IDENTITY_P0(23); // P0.23 (SPI MOSI) - _DEFPIN_ARM_IDENTITY_P0(24); // P0.24 (SPI SCK ) - _DEFPIN_ARM_IDENTITY_P0(25); // P0.25 (SPI SS ) - _DEFPIN_ARM_IDENTITY_P0(26); // P0.26 - _DEFPIN_ARM_IDENTITY_P0(27); // P0.27 - _DEFPIN_ARM_IDENTITY_P0(28); // P0.28 - _DEFPIN_ARM_IDENTITY_P0(29); // P0.29 - _DEFPIN_ARM_IDENTITY_P0(30); // P0.30 - _DEFPIN_ARM_IDENTITY_P0(31); // P0.31 -#endif // defined(ARDUINO_GENERIC) - - -#endif // __FASTPIN_ARM_NRF52_VARIANTS_H diff --git a/FastLED/src/platforms/arm/nrf52/fastspi_arm_nrf52.h b/FastLED/src/platforms/arm/nrf52/fastspi_arm_nrf52.h deleted file mode 100644 index 89d006e3983920864c673dde8994161b65d7f27d..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf52/fastspi_arm_nrf52.h +++ /dev/null @@ -1,340 +0,0 @@ -#ifndef __FASTSPI_ARM_NRF52_H -#define __FASTSPI_ARM_NRF52_H - - -#ifndef FASTLED_FORCE_SOFTWARE_SPI - - #include <nrf_spim.h> - - #define FASTLED_ALL_PINS_HARDWARE_SPI - - - // NRF52810 has SPIM0: Frequencies from 125kbps to 8Mbps - // NRF52832 adds SPIM1, SPIM2 (same frequencies) - // NRF52840 adds SPIM3 (same frequencies), adds SPIM3 that can be @ up to 32Mbps frequency(!) - #if !defined(FASTLED_NRF52_SPIM) - #define FASTLED_NRF52_SPIM NRF_SPIM0 - #endif - - /* This class is slightly simpler than fastpin, as it can rely on fastpin - * to handle the mapping to the underlying PN.XX board-level pins... - */ - - /// SPI_CLOCK_DIVIDER is number of CPU clock cycles per SPI transmission bit? - template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> - class NRF52SPIOutput { - private: - // static variables -- always using same SPIM instance - static bool s_InUse; - static bool s_NeedToWait; // a data transfer was started, and completion event was not cleared. - - /* - // TODO -- Workaround nRF52840 errata #198, which relates to - // contention between SPIM3 and CPU over AHB. - // The workaround is to ensure the SPIM TX buffer - // is on a different / dedicated RAM block. - // This also avoids AHB contention generally, so - // should be applied to all supported boards. - // - // But... how to allocate m_Buffer[] to be at a - // specific memory range? Also, might need to - // avoid use of single-transaction writeBytes() - // as cannot control where that memory lies.... - */ - static uint8_t s_BufferIndex; - static uint8_t s_Buffer[2][2]; // 2x two-byte buffers, allows one buffer currently being sent, and a second one being prepped to send. - - // This allows saving the configuration of the SPIM instance - // upon select(), and restoring the configuration upon release(). - struct spim_config { - uint32_t inten; - uint32_t shorts; - uint32_t sck_pin; - uint32_t mosi_pin; - uint32_t miso_pin; - uint32_t frequency; - // data pointers, RX/TX counts not saved as would only hide bugs - uint32_t config; // mode & bit order - uint32_t orc; - -#if false // additional configuration to save/restore for SPIM3 - uint32_t csn_pin; - uint32_t csn_polarity; // CSNPOL - uint32_t csn_duration; // IFTIMING.CSNDUR - uint32_t rx_delay; // IFTIMING.RXDELAY - uint32_t dcx_pin; // PSELDCX - uint32_t dcx_config; // DCXCNT -#endif - - } m_SpiSavedConfig; - void saveSpimConfig() { - m_SpiSavedConfig.inten = FASTLED_NRF52_SPIM->INTENSET; - m_SpiSavedConfig.shorts = FASTLED_NRF52_SPIM->SHORTS; - m_SpiSavedConfig.sck_pin = FASTLED_NRF52_SPIM->PSEL.SCK; - m_SpiSavedConfig.mosi_pin = FASTLED_NRF52_SPIM->PSEL.MOSI; - m_SpiSavedConfig.miso_pin = FASTLED_NRF52_SPIM->PSEL.MISO; - m_SpiSavedConfig.frequency = FASTLED_NRF52_SPIM->FREQUENCY; - m_SpiSavedConfig.config = FASTLED_NRF52_SPIM->CONFIG; - m_SpiSavedConfig.orc = FASTLED_NRF52_SPIM->ORC; - -#if false // additional configuration to save/restore for SPIM3 - m_SpiSavedConfig.csn_pin = FASTLED_NRF52_SPIM->PSEL.CSN; - m_SpiSavedConfig.csn_polarity = FASTLED_NRF52_SPIM->CSNPOL; - m_SpiSavedConfig.csn_duration = FASTLED_NRF52_SPIM->IFTIMING.CSNDUR; - m_SpiSavedConfig.dcx_pin = FASTLED_NRF52_SPIM->PSELDCX; - m_SpiSavedConfig.dcx_config = FASTLED_NRF52_SPIM->DCXCNT; -#endif - } - void restoreSpimConfig() { - // 0. ASSERT() the SPIM instance is not enabled - - FASTLED_NRF52_SPIM->INTENCLR = 0xFFFFFFFF; - FASTLED_NRF52_SPIM->INTENSET = m_SpiSavedConfig.inten; - FASTLED_NRF52_SPIM->SHORTS = m_SpiSavedConfig.shorts; - FASTLED_NRF52_SPIM->PSEL.SCK = m_SpiSavedConfig.sck_pin; - FASTLED_NRF52_SPIM->PSEL.MOSI = m_SpiSavedConfig.mosi_pin; - FASTLED_NRF52_SPIM->PSEL.MISO = m_SpiSavedConfig.miso_pin; - FASTLED_NRF52_SPIM->FREQUENCY = m_SpiSavedConfig.frequency; - FASTLED_NRF52_SPIM->CONFIG = m_SpiSavedConfig.config; - FASTLED_NRF52_SPIM->ORC = m_SpiSavedConfig.orc; - -#if false // additional configuration to save/restore for SPIM3 - FASTLED_NRF52_SPIM->PSEL.CSN = m_SpiSavedConfig.csn_pin; - FASTLED_NRF52_SPIM->CSNPOL = m_SpiSavedConfig.csn_polarity; - FASTLED_NRF52_SPIM->IFTIMING.CSNDUR = m_SpiSavedConfig.csn_duration; - FASTLED_NRF52_SPIM->PSELDCX = m_SpiSavedConfig.dcx_pin; - FASTLED_NRF52_SPIM->DCXCNT = m_SpiSavedConfig.dcx_config; -#endif - } - - public: - NRF52SPIOutput() {} - - // Low frequency GPIO is for signals with a frequency up to 10 kHz. Lowest speed SPIM is 125kbps. - static_assert(!FastPin<_DATA_PIN>::LowSpeedOnlyRecommended(), "Invalid (low-speed only) pin specified"); - static_assert(!FastPin<_CLOCK_PIN>::LowSpeedOnlyRecommended(), "Invalid (low-speed only) pin specified"); - - /// initialize the SPI subssytem - void init() { - // 0. ASSERT() the SPIM instance is not enabled / in use - //ASSERT(m_SPIM->ENABLE != (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos)); - - // 1. set pins to output/H0H1 drive/etc. - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); - - // 2. Configure SPIMx - nrf_spim_configure( - FASTLED_NRF52_SPIM, - NRF_SPIM_MODE_0, - NRF_SPIM_BIT_ORDER_MSB_FIRST - ); - nrf_spim_frequency_set( - FASTLED_NRF52_SPIM, - NRF_SPIM_FREQ_4M // BUGBUG -- use _SPI_CLOCK_DIVIDER to determine frequency - ); - nrf_spim_pins_set( - FASTLED_NRF52_SPIM, - FastPin<_CLOCK_PIN>::nrf_pin(), - FastPin<_DATA_PIN>::nrf_pin(), - NRF_SPIM_PIN_NOT_CONNECTED - ); - - // 4. Ensure events are cleared - nrf_spim_event_clear(FASTLED_NRF52_SPIM, NRF_SPIM_EVENT_END); - nrf_spim_event_clear(FASTLED_NRF52_SPIM, NRF_SPIM_EVENT_STARTED); - - // 5. Enable the SPIM instance - nrf_spim_enable(FASTLED_NRF52_SPIM); - } - - /// latch the CS select - void select() { - //ASSERT(!s_InUse); - saveSpimConfig(); - s_InUse = true; - init(); - } - - /// release the CS select - void release() { - //ASSERT(s_InUse); - waitFully(); - s_InUse = false; - restoreSpimConfig(); - } - - /// wait until all queued up data has been written - static void waitFully() { - if (!s_NeedToWait) return; - // else, need to wait for END event - while(!FASTLED_NRF52_SPIM->EVENTS_END) {}; - s_NeedToWait = 0; - // only use two events in this code... - nrf_spim_event_clear(FASTLED_NRF52_SPIM, NRF_SPIM_EVENT_END); - nrf_spim_event_clear(FASTLED_NRF52_SPIM, NRF_SPIM_EVENT_STARTED); - return; - } - // wait only until we can add a new transaction into the registers - // (caller must still waitFully() before actually starting this next transaction) - static void wait() { - if (!s_NeedToWait) return; - while (!FASTLED_NRF52_SPIM->EVENTS_STARTED) {}; - // leave the event set here... caller must waitFully() and start next transaction - return; - } - - /// write a byte out via SPI (returns immediately on writing register) - static void writeByte(uint8_t b) { - wait(); - // cannot use pointer to stack, so copy to m_buffer[] - uint8_t i = (s_BufferIndex ? 1u : 0u); - s_BufferIndex = !s_BufferIndex; // 1 <==> 0 swap - - s_Buffer[i][0u] = b; // cannot use the stack location, so copy to a more permanent buffer... - nrf_spim_tx_buffer_set( - FASTLED_NRF52_SPIM, - &(s_Buffer[i][0u]), - 1 - ); - - waitFully(); - nrf_spim_task_trigger( - FASTLED_NRF52_SPIM, - NRF_SPIM_TASK_START - ); - return; - } - - /// write a word out via SPI (returns immediately on writing register) - static void writeWord(uint16_t w) { - wait(); - // cannot use pointer to stack, so copy to m_buffer[] - uint8_t i = (s_BufferIndex ? 1u : 0u); - s_BufferIndex = !s_BufferIndex; // 1 <==> 0 swap - - s_Buffer[i][0u] = (w >> 8u); // cannot use the stack location, so copy to a more permanent buffer... - s_Buffer[i][1u] = (w & 0xFFu); // cannot use the stack location, so copy to a more permanent buffer... - nrf_spim_tx_buffer_set( - FASTLED_NRF52_SPIM, - &(s_Buffer[i][0u]), - 2 - ); - - waitFully(); - nrf_spim_task_trigger( - FASTLED_NRF52_SPIM, - NRF_SPIM_TASK_START - ); - return; - } - - /// A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes) - static void writeBytesValueRaw(uint8_t value, int len) { - while (len--) { writeByte(value); } - } - - /// A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytesValue(uint8_t value, int len) { - select(); - writeBytesValueRaw(value, len); - waitFully(); - release(); - } - - /// A full cycle of writing a raw block of data out, including select, release, and waiting - void writeBytes(uint8_t *data, int len) { - // This is a special-case, with no adjustment of the bytes... write them directly... - select(); - wait(); - nrf_spim_tx_buffer_set( - FASTLED_NRF52_SPIM, - data, - len - ); - waitFully(); - nrf_spim_task_trigger( - FASTLED_NRF52_SPIM, - NRF_SPIM_TASK_START - ); - waitFully(); - release(); - } - - /// A full cycle of writing a raw block of data out, including select, release, and waiting - template<class D> void writeBytes(uint8_t *data, int len) { - uint8_t * end = data + len; - select(); - wait(); - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - /// specialization for DATA_NOP ... - //template<DATA_NOP> void writeBytes(uint8_t * data, int len) { - // writeBytes(data, len); - //} - - /// write a single bit out, which bit from the passed in byte is determined by template parameter - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - // SPIM instance must be finished transmitting and then disabled - waitFully(); - nrf_spim_disable(FASTLED_NRF52_SPIM); - // set the data pin to appropriate state - if (b & (1 << BIT)) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - // delay 1/2 cycle per SPI bit - delaycycles<_SPI_CLOCK_DIVIDER/2>(); - FastPin<_CLOCK_PIN>::toggle(); - delaycycles<_SPI_CLOCK_DIVIDER/2>(); - FastPin<_CLOCK_PIN>::toggle(); - // re-enable the SPIM instance - nrf_spim_enable(FASTLED_NRF52_SPIM); - } - - /// write out pixel data from the given PixelController object, including select, release, and waiting - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - int len = pixels.mLen; - // TODO: If user indicates a pre-allocated double-buffer, - // then process all the pixels at once into that buffer, - // then use the non-templated WriteBytes(data, len) function - // to write the entire buffer as a single SPI transaction. - while (pixels.has(1)) { - if (FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - } - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - waitFully(); - release(); - } - }; - - // Static member definition and initialization using templates. - // see https://stackoverflow.com/questions/3229883/static-member-initialization-in-a-class-template#answer-3229919 - template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> - bool NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER>::s_InUse = false; - template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> - bool NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER>::s_NeedToWait = false; - template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> - uint8_t NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER>::s_BufferIndex = 0; - template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> - uint8_t NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER>::s_Buffer[2][2] = {{0,0},{0,0}}; - -#endif // #ifndef FASTLED_FORCE_SOFTWARE_SPI - - - -#endif // #ifndef __FASTPIN_ARM_NRF52_H diff --git a/FastLED/src/platforms/arm/nrf52/led_sysdefs_arm_nrf52.h b/FastLED/src/platforms/arm/nrf52/led_sysdefs_arm_nrf52.h deleted file mode 100644 index 3a7ea5820abd462d8bc924dd8ef1239ac6fc94ab..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/nrf52/led_sysdefs_arm_nrf52.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __LED_SYSDEFS_ARM_NRF52 -#define __LED_SYSDEFS_ARM_NRF52 - -#define FASTLED_ARM - -#ifndef F_CPU - #define F_CPU 64000000 // the NRF52 series has a 64MHz CPU -#endif - -// even though CPU is at 64MHz, use the 8MHz-defined timings because... -// PWM module runs at 16MHz -// SPI0..2 runs at 8MHz -#define CLOCKLESS_FREQUENCY 16000000 // the NRF52 has EasyDMA for PWM module at 16MHz - -#ifndef F_TIMER - #define F_TIMER 16000000 // the NRF52 timer is 16MHz, even though CPU is 64MHz -#endif - -#if !defined(FASTLED_USE_PROGMEM) - #define FASTLED_USE_PROGMEM 0 // nRF52 series have flat memory model -#endif - -#if !defined(FASTLED_ALLOW_INTERRUPTS) - #define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -// Use PWM instance 0 -// See clockless_arm_nrf52.h and (in root of library) platforms.cpp -#define FASTLED_NRF52_ENABLE_PWM_INSTANCE0 - -#if defined(FASTLED_NRF52_NEVER_INLINE) - #define FASTLED_NRF52_INLINE_ATTRIBUTE __attribute__((always_inline)) inline -#else - #define FASTLED_NRF52_INLINE_ATTRIBUTE __attribute__((always_inline)) inline -#endif - - - -#include <nrf.h> -#include <nrf_spim.h> // for FastSPI -#include <nrf_pwm.h> // for Clockless -#include <nrf_nvic.h> // for Clockless / anything else using interrupts -typedef __I uint32_t RoReg; -typedef __IO uint32_t RwReg; - -#define cli() __disable_irq() -#define sei() __enable_irq() - -#define FASTLED_NRF52_DEBUGPRINT(format, ...)\ -// do { FastLED_NRF52_DebugPrint(format, ##__VA_ARGS__); } while(0); - -#endif // __LED_SYSDEFS_ARM_NRF52 diff --git a/FastLED/src/platforms/arm/sam/clockless_arm_sam.h b/FastLED/src/platforms/arm/sam/clockless_arm_sam.h deleted file mode 100644 index d7c57940b6e789811efa4139277a51e9533b6387..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/sam/clockless_arm_sam.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_SAM_H -#define __INC_CLOCKLESS_ARM_SAM_H - -FASTLED_NAMESPACE_BEGIN - -// Definition for a single channel clockless controller for the sam family of arm chips, like that used in the due and rfduino -// See clockless.h for detailed info on how the template parameters are used. - -#if defined(__SAM3X8E__) - - -#define TADJUST 0 -#define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) ) - -#define FASTLED_HAS_CLOCKLESS 1 - -template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPinBB<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - FastPinBB<DATA_PIN>::setOutput(); - mPinMask = FastPinBB<DATA_PIN>::mask(); - mPort = FastPinBB<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - mWait.mark(); - } - - template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) { - // Make sure we don't slot into a wrapping spot, this will delay up to 12.5µs for WS2812 - // bool bShift=0; - // while(VAL < (TOTAL*10)) { bShift=true; } - // if(bShift) { next_mark = (VAL-TOTAL); }; - - for(register uint32_t i = BITS; i > 0; --i) { - // wait to start the bit, then set the pin high - while(DUE_TIMER_VAL < next_mark); - next_mark = (DUE_TIMER_VAL+TOTAL); - *port = 1; - - // how long we want to wait next depends on whether or not our bit is set to 1 or 0 - if(b&0x80) { - // we're a 1, wait until there's less than T3 clocks left - while((next_mark - DUE_TIMER_VAL) > (T3)); - } else { - // we're a 0, wait until there's less than (T2+T3+slop) clocks left in this bit - while((next_mark - DUE_TIMER_VAL) > (T2+T3+6+TADJUST+TADJUST)); - } - *port=0; - b <<= 1; - } - } - -#define FORCE_REFERENCE(var) asm volatile( "" : : "r" (var) ) - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - // Setup and start the clock - TC_Configure(DUE_TIMER,DUE_TIMER_CHANNEL,TC_CMR_TCCLKS_TIMER_CLOCK1); - pmc_enable_periph_clk(DUE_TIMER_ID); - TC_Start(DUE_TIMER,DUE_TIMER_CHANNEL); - - register data_ptr_t port asm("r7") = FastPinBB<DATA_PIN>::port(); FORCE_REFERENCE(port); - *port = 0; - - // Setup the pixel controller and load/scale the first byte - pixels.preStepFirstByteDithering(); - uint8_t b = pixels.loadAndScale0(); - - uint32_t next_mark = (DUE_TIMER_VAL + (TOTAL)); - while(pixels.has(1)) { - pixels.stepDithering(); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - if(DUE_TIMER_VAL > next_mark) { - if((DUE_TIMER_VAL - next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { - sei(); TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL); return 0; - } - } - #endif - - writeBits<8+XTRA0>(next_mark, port, b); - - b = pixels.loadAndScale1(); - writeBits<8+XTRA0>(next_mark, port,b); - - b = pixels.loadAndScale2(); - writeBits<8+XTRA0>(next_mark, port,b); - - b = pixels.advanceAndLoadAndScale0(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - - TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL); - return DUE_TIMER_VAL; - } -}; - -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/sam/clockless_block_arm_sam.h b/FastLED/src/platforms/arm/sam/clockless_block_arm_sam.h deleted file mode 100644 index a1799891506c53aa0b252de6d8832403db66b235..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/sam/clockless_block_arm_sam.h +++ /dev/null @@ -1,183 +0,0 @@ - #ifndef __INC_BLOCK_CLOCKLESS_H -#define __INC_BLOCK_CLOCKLESS_H - -FASTLED_NAMESPACE_BEGIN - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. The first point -// is where the line is raised hi. The second pointsnt is where the line is dropped low for a zero. The third point is where the -// line is dropped low for a one. T1, T2, and T3 correspond to the timings for those three in clock cycles. -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#if defined(__SAM3X8E__) -#define PORT_MASK (((1<<LANES)-1) & ((FIRST_PIN==2) ? 0xFF : 0xFF)) - -#define FASTLED_HAS_BLOCKLESS 1 - -#define PORTD_FIRST_PIN 25 -#define PORTA_FIRST_PIN 69 -#define PORTB_FIRST_PIN 90 - -typedef union { - uint8_t bytes[8]; - uint32_t raw[2]; -} Lines; - -#define TADJUST 0 -#define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) ) -#define T1_MARK (TOTAL - (T1+TADJUST)) -#define T2_MARK (T1_MARK - (T2+TADJUST)) -template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PORT_MASK> { - typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<FIRST_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual int size() { return CLEDController::size() * LANES; } - virtual void init() { - static_assert(LANES <= 8, "Maximum of 8 lanes for Due parallel controllers!"); - if(FIRST_PIN == PORTA_FIRST_PIN) { - switch(LANES) { - case 8: FastPin<31>::setOutput(); - case 7: FastPin<58>::setOutput(); - case 6: FastPin<100>::setOutput(); - case 5: FastPin<59>::setOutput(); - case 4: FastPin<60>::setOutput(); - case 3: FastPin<61>::setOutput(); - case 2: FastPin<68>::setOutput(); - case 1: FastPin<69>::setOutput(); - } - } else if(FIRST_PIN == PORTD_FIRST_PIN) { - switch(LANES) { - case 8: FastPin<11>::setOutput(); - case 7: FastPin<29>::setOutput(); - case 6: FastPin<15>::setOutput(); - case 5: FastPin<14>::setOutput(); - case 4: FastPin<28>::setOutput(); - case 3: FastPin<27>::setOutput(); - case 2: FastPin<26>::setOutput(); - case 1: FastPin<25>::setOutput(); - } - } else if(FIRST_PIN == PORTB_FIRST_PIN) { - switch(LANES) { - case 8: FastPin<97>::setOutput(); - case 7: FastPin<96>::setOutput(); - case 6: FastPin<95>::setOutput(); - case 5: FastPin<94>::setOutput(); - case 4: FastPin<93>::setOutput(); - case 3: FastPin<92>::setOutput(); - case 2: FastPin<91>::setOutput(); - case 1: FastPin<90>::setOutput(); - } - } - mPinMask = FastPin<FIRST_PIN>::mask(); - mPort = FastPin<FIRST_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) { - mWait.wait(); - showRGBInternal(pixels); - sei(); - mWait.mark(); - } - - static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) { - // Serial.println("Entering show"); - - int nLeds = allpixels.mLen; - - // Setup the pixel controller and load/scale the first byte - Lines b0,b1,b2; - - allpixels.preStepFirstByteDithering(); - for(uint8_t i = 0; i < LANES; i++) { - b0.bytes[i] = allpixels.loadAndScale0(i); - } - - // Setup and start the clock - TC_Configure(DUE_TIMER,DUE_TIMER_CHANNEL,TC_CMR_TCCLKS_TIMER_CLOCK1); - pmc_enable_periph_clk(DUE_TIMER_ID); - TC_Start(DUE_TIMER,DUE_TIMER_CHANNEL); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - #endif - uint32_t next_mark = (DUE_TIMER_VAL + (TOTAL)); - while(nLeds--) { - allpixels.stepDithering(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - if(DUE_TIMER_VAL > next_mark) { - if((DUE_TIMER_VAL - next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { - sei(); TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL); return DUE_TIMER_VAL; - } - } - #endif - - // Write first byte, read next byte - writeBits<8+XTRA0,1>(next_mark, b0, b1, allpixels); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(next_mark, b1, b2, allpixels); - - allpixels.advanceData(); - // Write third byte - writeBits<8+XTRA0,0>(next_mark, b2, b0, allpixels); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - } - - return DUE_TIMER_VAL; - } - - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, Lines & b3, PixelController<RGB_ORDER,LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) { - Lines b2; - transpose8x1(b.bytes,b2.bytes); - - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - for(uint32_t i = 0; (i < LANES) && (i<8); i++) { - while(DUE_TIMER_VAL < next_mark); - next_mark = (DUE_TIMER_VAL+TOTAL); - - *FastPin<FIRST_PIN>::sport() = PORT_MASK; - - while((next_mark - DUE_TIMER_VAL) > (T2+T3+6)); - *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK; - - while((next_mark - (DUE_TIMER_VAL)) > T3); - *FastPin<FIRST_PIN>::cport() = PORT_MASK; - - b3.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); - } - - for(uint32_t i = LANES; i < 8; i++) { - while(DUE_TIMER_VAL < next_mark); - next_mark = (DUE_TIMER_VAL+TOTAL); - *FastPin<FIRST_PIN>::sport() = PORT_MASK; - - while((next_mark - DUE_TIMER_VAL) > (T2+T3+6)); - *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK; - - while((next_mark - DUE_TIMER_VAL) > T3); - *FastPin<FIRST_PIN>::cport() = PORT_MASK; - } - } -}; - -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/sam/fastled_arm_sam.h b/FastLED/src/platforms/arm/sam/fastled_arm_sam.h deleted file mode 100644 index 3567bb623d307bee1fc090ce16825a39635ff3c4..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/sam/fastled_arm_sam.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __INC_FASTLED_ARM_SAM_H -#define __INC_FASTLED_ARM_SAM_H - -// Include the sam headers -#include "fastpin_arm_sam.h" -#include "fastspi_arm_sam.h" -#include "clockless_arm_sam.h" -#include "clockless_block_arm_sam.h" - -#endif diff --git a/FastLED/src/platforms/arm/sam/fastpin_arm_sam.h b/FastLED/src/platforms/arm/sam/fastpin_arm_sam.h deleted file mode 100644 index e1354c7346330b4530a97d947593cb8132ef5288..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/sam/fastpin_arm_sam.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef __INC_FASTPIN_ARM_SAM_H -#define __INC_FASTPIN_ARM_SAM_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be sloightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - - -/// Template definition for arduino due style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found -/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. -/// The registers are data register, set output register, clear output register, set data direction register -template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PDDR> class _DUEPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { _PSOR::r() = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { _PDOR::r() ^= _MASK; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_PSOR::r(); } - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_PCOR::r(); } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - - -/// Template definition for DUE style ARM pins using bit banding, providing direct access to the various GPIO registers. GCC -/// does a poor job of optimizing around these accesses so they are not being used just yet. -template<uint8_t PIN, uint32_t _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PDDR> class _DUEPIN_BITBAND { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 1; } - inline static void lo() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 0; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() ^= 1; } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return 1; } - inline static port_t loval() __attribute__ ((always_inline)) { return 0; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return _PDOR::template rx<_BIT>(); } - inline static port_t mask() __attribute__ ((always_inline)) { return 1; } -}; - -#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) -#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) - -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \ - template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } }; -#define _FL_IO(L,C) _RD32(REG_PIO ## L ## _ODSR); _RD32(REG_PIO ## L ## _SODR); _RD32(REG_PIO ## L ## _CODR); _RD32(REG_PIO ## L ## _OER); _FL_DEFINE_PORT3(L, C, _R(REG_PIO ## L ## _ODSR)); - -#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _DUEPIN<PIN, 1 << BIT, _R(REG_PIO ## L ## _ODSR), _R(REG_PIO ## L ## _SODR), _R(REG_PIO ## L ## _CODR), \ - _R(GPIO ## L ## _OER)> {}; \ - template<> class FastPinBB<PIN> : public _DUEPIN_BITBAND<PIN, BIT, _R(REG_PIO ## L ## _ODSR), _R(REG_PIO ## L ## _SODR), _R(REG_PIO ## L ## _CODR), \ - _R(GPIO ## L ## _OER)> {}; - -_FL_IO(A,0); -_FL_IO(B,1); -_FL_IO(C,2); -_FL_IO(D,3); - -#if defined(__SAM3X8E__) - -#define MAX_PIN 78 -_FL_DEFPIN(0, 8, A); _FL_DEFPIN(1, 9, A); _FL_DEFPIN(2, 25, B); _FL_DEFPIN(3, 28, C); -_FL_DEFPIN(4, 26, C); _FL_DEFPIN(5, 25, C); _FL_DEFPIN(6, 24, C); _FL_DEFPIN(7, 23, C); -_FL_DEFPIN(8, 22, C); _FL_DEFPIN(9, 21, C); _FL_DEFPIN(10, 29, C); _FL_DEFPIN(11, 7, D); -_FL_DEFPIN(12, 8, D); _FL_DEFPIN(13, 27, B); _FL_DEFPIN(14, 4, D); _FL_DEFPIN(15, 5, D); -_FL_DEFPIN(16, 13, A); _FL_DEFPIN(17, 12, A); _FL_DEFPIN(18, 11, A); _FL_DEFPIN(19, 10, A); -_FL_DEFPIN(20, 12, B); _FL_DEFPIN(21, 13, B); _FL_DEFPIN(22, 26, B); _FL_DEFPIN(23, 14, A); -_FL_DEFPIN(24, 15, A); _FL_DEFPIN(25, 0, D); _FL_DEFPIN(26, 1, D); _FL_DEFPIN(27, 2, D); -_FL_DEFPIN(28, 3, D); _FL_DEFPIN(29, 6, D); _FL_DEFPIN(30, 9, D); _FL_DEFPIN(31, 7, A); -_FL_DEFPIN(32, 10, D); _FL_DEFPIN(33, 1, C); _FL_DEFPIN(34, 2, C); _FL_DEFPIN(35, 3, C); -_FL_DEFPIN(36, 4, C); _FL_DEFPIN(37, 5, C); _FL_DEFPIN(38, 6, C); _FL_DEFPIN(39, 7, C); -_FL_DEFPIN(40, 8, C); _FL_DEFPIN(41, 9, C); _FL_DEFPIN(42, 19, A); _FL_DEFPIN(43, 20, A); -_FL_DEFPIN(44, 19, C); _FL_DEFPIN(45, 18, C); _FL_DEFPIN(46, 17, C); _FL_DEFPIN(47, 16, C); -_FL_DEFPIN(48, 15, C); _FL_DEFPIN(49, 14, C); _FL_DEFPIN(50, 13, C); _FL_DEFPIN(51, 12, C); -_FL_DEFPIN(52, 21, B); _FL_DEFPIN(53, 14, B); _FL_DEFPIN(54, 16, A); _FL_DEFPIN(55, 24, A); -_FL_DEFPIN(56, 23, A); _FL_DEFPIN(57, 22, A); _FL_DEFPIN(58, 6, A); _FL_DEFPIN(59, 4, A); -_FL_DEFPIN(60, 3, A); _FL_DEFPIN(61, 2, A); _FL_DEFPIN(62, 17, B); _FL_DEFPIN(63, 18, B); -_FL_DEFPIN(64, 19, B); _FL_DEFPIN(65, 20, B); _FL_DEFPIN(66, 15, B); _FL_DEFPIN(67, 16, B); -_FL_DEFPIN(68, 1, A); _FL_DEFPIN(69, 0, A); _FL_DEFPIN(70, 17, A); _FL_DEFPIN(71, 18, A); -_FL_DEFPIN(72, 30, C); _FL_DEFPIN(73, 21, A); _FL_DEFPIN(74, 25, A); _FL_DEFPIN(75, 26, A); -_FL_DEFPIN(76, 27, A); _FL_DEFPIN(77, 28, A); _FL_DEFPIN(78, 23, B); - -// digix pins -_FL_DEFPIN(90, 0, B); _FL_DEFPIN(91, 1, B); _FL_DEFPIN(92, 2, B); _FL_DEFPIN(93, 3, B); -_FL_DEFPIN(94, 4, B); _FL_DEFPIN(95, 5, B); _FL_DEFPIN(96, 6, B); _FL_DEFPIN(97, 7, B); -_FL_DEFPIN(98, 8, B); _FL_DEFPIN(99, 9, B); _FL_DEFPIN(100, 5, A); _FL_DEFPIN(101, 22, B); -_FL_DEFPIN(102, 23, B); _FL_DEFPIN(103, 24, B); _FL_DEFPIN(104, 27, C); _FL_DEFPIN(105, 20, C); -_FL_DEFPIN(106, 11, C); _FL_DEFPIN(107, 10, C); _FL_DEFPIN(108, 21, A); _FL_DEFPIN(109, 30, C); -_FL_DEFPIN(110, 29, B); _FL_DEFPIN(111, 30, B); _FL_DEFPIN(112, 31, B); _FL_DEFPIN(113, 28, B); - -#define SPI_DATA 75 -#define SPI_CLOCK 76 -#define ARM_HARDWARE_SPI -#define HAS_HARDWARE_PIN_SUPPORT - -#endif - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - - -#endif // __INC_FASTPIN_ARM_SAM_H diff --git a/FastLED/src/platforms/arm/sam/fastspi_arm_sam.h b/FastLED/src/platforms/arm/sam/fastspi_arm_sam.h deleted file mode 100644 index a9446439b81c5eaf664fa82077f2a03fd8d4370f..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/sam/fastspi_arm_sam.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef __INC_FASTSPI_ARM_SAM_H -#define __INC_FASTSPI_ARM_SAM_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(__SAM3X8E__) -#define m_SPI ((Spi*)SPI0) - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class SAMHardwareSPIOutput { - Selectable *m_pSelect; - - static inline void waitForEmpty() { while ((m_SPI->SPI_SR & SPI_SR_TDRE) == 0); } - - void enableConfig() { m_SPI->SPI_WPMR &= ~SPI_WPMR_WPEN; } - void disableConfig() { m_SPI->SPI_WPMR |= SPI_WPMR_WPEN; } - - void enableSPI() { m_SPI->SPI_CR = SPI_CR_SPIEN; } - void disableSPI() { m_SPI->SPI_CR = SPI_CR_SPIDIS; } - void resetSPI() { m_SPI->SPI_CR = SPI_CR_SWRST; } - - static inline void readyTransferBits(register uint32_t bits) { - bits -= 8; - // don't change the number of transfer bits while data is still being transferred from TDR to the shift register - waitForEmpty(); - m_SPI->SPI_CSR[0] = SPI_CSR_NCPHA | SPI_CSR_CSAAT | (bits << SPI_CSR_BITS_Pos) | SPI_CSR_DLYBCT(1) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER); - } - - template<int BITS> static inline void writeBits(uint16_t w) { - waitForEmpty(); - m_SPI->SPI_TDR = (uint32_t)w | SPI_PCS(0); - } - -public: - SAMHardwareSPIOutput() { m_pSelect = NULL; } - SAMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - - // set the object representing the selectable - void setSelect(Selectable *pSelect) { /* TODO */ } - - // initialize the SPI subssytem - void init() { - // m_SPI = SPI0; - - // set the output pins master out, master in, clock. Note doing this here because I still don't - // know how I want to expose this type of functionality in FastPin. - PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_DATA_PIN>::mask(), PIO_DEFAULT); - PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_DATA_PIN-1>::mask(), PIO_DEFAULT); - PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_CLOCK_PIN>::mask(), PIO_DEFAULT); - - release(); - - // Configure the SPI clock, divider between 1-255 - // SCBR = _SPI_CLOCK_DIVIDER - pmc_enable_periph_clk(ID_SPI0); - disableSPI(); - - // reset twice (what the sam code does, not sure why?) - resetSPI(); - resetSPI(); - - // Configure SPI as master, enable - // Bits we want in MR: master, disable mode fault detection, variable peripheral select - m_SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS; - - enableSPI(); - - // Send everything out in 8 bit chunks, other sizes appear to work, poorly... - readyTransferBits(8); - } - - // latch the CS select - void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->select(); } } - - // release the CS select - void inline release() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->release(); } } - - // wait until all queued up data has been written - void waitFully() { while((m_SPI->SPI_SR & SPI_SR_TXEMPTY) == 0); } - - // write a byte out via SPI (returns immediately on writing register) - static void writeByte(uint8_t b) { - writeBits<8>(b); - } - - // write a word out via SPI (returns immediately on writing register) - static void writeWord(uint16_t w) { - writeBits<16>(w); - } - - // A raw set of writing byte values, assumes setup/init/waiting done elsewhere - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { writeByte(value); } - } - - // A full cycle of writing a value for len bytes, including select, release, and waiting - void writeBytesValue(uint8_t value, int len) { - select(); writeBytesValueRaw(value, len); release(); - } - - template <class D> void writeBytes(register uint8_t *data, int len) { - uint8_t *end = data + len; - select(); - // could be optimized to write 16bit words out instead of 8bit bytes - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a single bit out, which bit from the passed in byte is determined by template parameter - // not the most efficient mechanism in the world - but should be enough for sm16716 and friends - template <uint8_t BIT> inline void writeBit(uint8_t b) { - // need to wait for all exisiting data to go out the door, first - waitFully(); - disableSPI(); - if(b & (1 << BIT)) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - - FastPin<_CLOCK_PIN>::hi(); - FastPin<_CLOCK_PIN>::lo(); - enableSPI(); - } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - select(); - int len = pixels.mLen; - - if(FLAGS & FLAG_START_BIT) { - while(pixels.has(1)) { - writeBits<9>((1<<8) | D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - pixels.advanceData(); - pixels.stepDithering(); - } - } else { - while(pixels.has(1)) { - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - pixels.advanceData(); - pixels.stepDithering(); - } - } - D::postBlock(len); - release(); - } -}; - -#endif - -FASTLED_NAMESPACE_END -#endif diff --git a/FastLED/src/platforms/arm/sam/led_sysdefs_arm_sam.h b/FastLED/src/platforms/arm/sam/led_sysdefs_arm_sam.h deleted file mode 100644 index a48286487d78e6eae5a989dbb07f067acbeab334..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/sam/led_sysdefs_arm_sam.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_ARM_SAM_H -#define __INC_LED_SYSDEFS_ARM_SAM_H - - -#define FASTLED_ARM - -// Setup DUE timer defines/channels/etc... -#ifndef DUE_TIMER_CHANNEL -#define DUE_TIMER_GROUP 0 -#endif - -#ifndef DUE_TIMER_CHANNEL -#define DUE_TIMER_CHANNEL 0 -#endif - -#define DUE_TIMER ((DUE_TIMER_GROUP==0) ? TC0 : ((DUE_TIMER_GROUP==1) ? TC1 : TC2)) -#define DUE_TIMER_ID (ID_TC0 + (DUE_TIMER_GROUP*3) + DUE_TIMER_CHANNEL) -#define DUE_TIMER_VAL (DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_CV << 1) -#define DUE_TIMER_RUNNING ((DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_SR & TC_SR_CLKSTA) != 0) - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 1 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -// reusing/abusing cli/sei defs for due -#define cli() __disable_irq(); __disable_fault_irq(); -#define sei() __enable_irq(); __enable_fault_irq(); - - -#endif diff --git a/FastLED/src/platforms/arm/stm32/clockless_arm_stm32.h b/FastLED/src/platforms/arm/stm32/clockless_arm_stm32.h deleted file mode 100644 index 0ac8a5d43637778905ce6021632ac30bc295397a..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/stm32/clockless_arm_stm32.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef __INC_CLOCKLESS_ARM_STM32_H -#define __INC_CLOCKLESS_ARM_STM32_H - -FASTLED_NAMESPACE_BEGIN -// Definition for a single channel clockless controller for the stm32 family of chips, like that used in the spark core -// See clockless.h for detailed info on how the template parameters are used. - -#define FASTLED_HAS_CLOCKLESS 1 - -template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - FastPin<DATA_PIN>::setOutput(); - mPinMask = FastPin<DATA_PIN>::mask(); - mPort = FastPin<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - mWait.wait(); - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - mWait.mark(); - } - -#define _CYCCNT (*(volatile uint32_t*)(0xE0001004UL)) - - template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) { - for(register uint32_t i = BITS-1; i > 0; --i) { - while(_CYCCNT < (T1+T2+T3-20)); - FastPin<DATA_PIN>::fastset(port, hi); - _CYCCNT = 4; - if(b&0x80) { - while(_CYCCNT < (T1+T2-20)); - FastPin<DATA_PIN>::fastset(port, lo); - } else { - while(_CYCCNT < (T1-10)); - FastPin<DATA_PIN>::fastset(port, lo); - } - b <<= 1; - } - - while(_CYCCNT < (T1+T2+T3-20)); - FastPin<DATA_PIN>::fastset(port, hi); - _CYCCNT = 4; - - if(b&0x80) { - while(_CYCCNT < (T1+T2-20)); - FastPin<DATA_PIN>::fastset(port, lo); - } else { - while(_CYCCNT < (T1-10)); - FastPin<DATA_PIN>::fastset(port, lo); - } - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) { - // Get access to the clock - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; - DWT->CYCCNT = 0; - - register data_ptr_t port = FastPin<DATA_PIN>::port(); - register data_t hi = *port | FastPin<DATA_PIN>::mask();; - register data_t lo = *port & ~FastPin<DATA_PIN>::mask();; - *port = lo; - - // Setup the pixel controller and load/scale the first byte - pixels.preStepFirstByteDithering(); - register uint8_t b = pixels.loadAndScale0(); - - cli(); - - uint32_t next_mark = (T1+T2+T3); - - DWT->CYCCNT = 0; - while(pixels.has(1)) { - pixels.stepDithering(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - cli(); - // if interrupts took longer than 45µs, punt on the current frame - if(DWT->CYCCNT > next_mark) { - if((DWT->CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; } - } - - hi = *port | FastPin<DATA_PIN>::mask(); - lo = *port & ~FastPin<DATA_PIN>::mask(); - #endif - - // Write first byte, read next byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale1(); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale2(); - - // Write third byte, read 1st byte of next pixel - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.advanceAndLoadAndScale0(); - #if (FASTLED_ALLOW_INTERRUPTS == 1) - sei(); - #endif - }; - - sei(); - return DWT->CYCCNT; - } -}; - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/arm/stm32/cm3_regs.h b/FastLED/src/platforms/arm/stm32/cm3_regs.h deleted file mode 100644 index 7bb7f759ccd1be355907e4b250517a08ec97592a..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/stm32/cm3_regs.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef __CM3_REGS -#define __CM3_REGS - -#include <stdint.h> - -#ifdef __cplusplus -#define __I volatile /*!< Defines 'read only' permissions */ -#else -#define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - - -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1]; - __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1]; - __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1]; - __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; - - -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ - -#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ - -#endif // __CM3_REGS diff --git a/FastLED/src/platforms/arm/stm32/fastled_arm_stm32.h b/FastLED/src/platforms/arm/stm32/fastled_arm_stm32.h deleted file mode 100644 index 3f86a8731e92de050fc316f229a43ad2619ab721..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/stm32/fastled_arm_stm32.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __INC_FASTLED_ARM_SAM_H -#define __INC_FASTLED_ARM_SAM_H - -// Include the sam headers -#include "fastpin_arm_stm32.h" -// #include "fastspi_arm_stm32.h" -#include "clockless_arm_stm32.h" - -#endif diff --git a/FastLED/src/platforms/arm/stm32/fastpin_arm_stm32.h b/FastLED/src/platforms/arm/stm32/fastpin_arm_stm32.h deleted file mode 100644 index bc69912c38abf0eeeb2d726d40d4d594e08306ad..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/stm32/fastpin_arm_stm32.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef __FASTPIN_ARM_STM32_H -#define __FASTPIN_ARM_STM32_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be sloightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - -/// Template definition for STM32 style ARM pins, providing direct access to the various GPIO registers. Note that this -/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found -/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. -/// The registers are data output, set output, clear output, toggle output, input, and direction - -template<uint8_t PIN, uint8_t _BIT, uint32_t _MASK, typename _GPIO> class _ARMPIN { - -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - #if 0 - inline static void setOutput() { - if(_BIT<8) { - _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4)); - } else { - _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4)); - } - } - inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - #endif - - inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; } - inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = _MASK; } - inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BRR = _MASK; } - // inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = (_MASK<<16); } - inline static void set(register port_t val) __attribute__ ((always_inline)) { _GPIO::r()->ODR = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { if(_GPIO::r()->ODR & _MASK) { lo(); } else { hi(); } } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return _GPIO::r()->ODR | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return _GPIO::r()->ODR & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_GPIO::r()->ODR; } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPIO::r()->BSRR; } - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPIO::r()->BRR; } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - -#if defined(STM32F10X_MD) -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile GPIO_TypeDef * r() { return T; } }; -#define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L)); -#elif defined(__STM32F1__) -#define _R(T) struct __gen_struct_ ## T -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline gpio_reg_map* r() { return T->regs; } }; -#define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L)); -#else -#error "Platform not supported" -#endif - -#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, _R(GPIO ## L)> {}; - -#ifdef GPIOA -_FL_IO(A,0); -#endif -#ifdef GPIOB -_FL_IO(B,1); -#endif -#ifdef GPIOC -_FL_IO(C,2); -#endif -#ifdef GPIOD -_FL_IO(D,3); -#endif -#ifdef GPIOE -_FL_IO(E,4); -#endif -#ifdef GPIOF -_FL_IO(F,5); -#endif -#ifdef GPIOG -_FL_IO(G,6); -#endif - -// Actual pin definitions -#if defined(SPARK) // Sparkfun STM32F103 based board - -#define MAX_PIN 19 -_FL_DEFPIN(0, 7, B); -_FL_DEFPIN(1, 6, B); -_FL_DEFPIN(2, 5, B); -_FL_DEFPIN(3, 4, B); -_FL_DEFPIN(4, 3, B); -_FL_DEFPIN(5, 15, A); -_FL_DEFPIN(6, 14, A); -_FL_DEFPIN(7, 13, A); -_FL_DEFPIN(8, 8, A); -_FL_DEFPIN(9, 9, A); -_FL_DEFPIN(10, 0, A); -_FL_DEFPIN(11, 1, A); -_FL_DEFPIN(12, 4, A); -_FL_DEFPIN(13, 5, A); -_FL_DEFPIN(14, 6, A); -_FL_DEFPIN(15, 7, A); -_FL_DEFPIN(16, 0, B); -_FL_DEFPIN(17, 1, B); -_FL_DEFPIN(18, 3, A); -_FL_DEFPIN(19, 2, A); - -#define SPI_DATA 15 -#define SPI_CLOCK 13 - -#define HAS_HARDWARE_PIN_SUPPORT - -#endif // SPARK - -#if defined(__STM32F1__) // Generic STM32F103 aka "Blue Pill" - -#define MAX_PIN 46 - -_FL_DEFPIN(10, 0, A); // PA0 - PA7 -_FL_DEFPIN(11, 1, A); -_FL_DEFPIN(12, 2, A); -_FL_DEFPIN(13, 3, A); -_FL_DEFPIN(14, 4, A); -_FL_DEFPIN(15, 5, A); -_FL_DEFPIN(16, 6, A); -_FL_DEFPIN(17, 7, A); -_FL_DEFPIN(29, 8, A); // PA8 - PA15 -_FL_DEFPIN(30, 9, A); -_FL_DEFPIN(31, 10, A); -_FL_DEFPIN(32, 11, A); -_FL_DEFPIN(33, 12, A); -_FL_DEFPIN(34, 13, A); -_FL_DEFPIN(37, 14, A); -_FL_DEFPIN(38, 15, A); - -_FL_DEFPIN(18, 0, B); // PB0 - PB11 -_FL_DEFPIN(19, 1, B); -_FL_DEFPIN(20, 2, B); -_FL_DEFPIN(39, 3, B); -_FL_DEFPIN(40, 4, B); -_FL_DEFPIN(41, 5, B); -_FL_DEFPIN(42, 6, B); -_FL_DEFPIN(43, 7, B); -_FL_DEFPIN(45, 8, B); -_FL_DEFPIN(46, 9, B); -_FL_DEFPIN(21, 10, B); -_FL_DEFPIN(22, 11, B); - -_FL_DEFPIN(2, 13, C); // PC13 - PC15 -_FL_DEFPIN(3, 14, C); -_FL_DEFPIN(4, 15, C); - -#define SPI_DATA BOARD_SPI1_MOSI_PIN -#define SPI_CLOCK BOARD_SPI1_SCK_PIN - -#define HAS_HARDWARE_PIN_SUPPORT - -#endif // __STM32F1__ - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - -#endif // __INC_FASTPIN_ARM_STM32 diff --git a/FastLED/src/platforms/arm/stm32/led_sysdefs_arm_stm32.h b/FastLED/src/platforms/arm/stm32/led_sysdefs_arm_stm32.h deleted file mode 100644 index afcf1785355a296dea4409f35f72d1fbfbcc83d1..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/arm/stm32/led_sysdefs_arm_stm32.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_ARM_SAM_H -#define __INC_LED_SYSDEFS_ARM_SAM_H - -#if defined(STM32F10X_MD) - -#include <application.h> - -#define FASTLED_NAMESPACE_BEGIN namespace NSFastLED { -#define FASTLED_NAMESPACE_END } -#define FASTLED_USING_NAMESPACE using namespace NSFastLED; - -// reusing/abusing cli/sei defs for due -#define cli() __disable_irq(); __disable_fault_irq(); -#define sei() __enable_irq(); __enable_fault_irq(); - -#elif defined (__STM32F1__) - -#include "cm3_regs.h" - -#define cli() nvic_globalirq_disable() -#define sei() nvic_globalirq_enable() - -#else -#error "Platform not supported" -#endif - -#define FASTLED_ARM - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - -// Default to allowing interrupts -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 0 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - -// pgmspace definitions -#define PROGMEM -#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) -#define pgm_read_dword_near(addr) pgm_read_dword(addr) - -// Default to NOT using PROGMEM here -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 0 -#endif - -// data type defs -typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ -typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ - -#define FASTLED_NO_PINMAP - -#ifndef F_CPU -#define F_CPU 72000000 -#endif -#endif diff --git a/FastLED/src/platforms/avr/clockless_trinket.h b/FastLED/src/platforms/avr/clockless_trinket.h deleted file mode 100644 index 971a5a71264ecd7d73f54a30b0aba3d23f338ead..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/avr/clockless_trinket.h +++ /dev/null @@ -1,475 +0,0 @@ -#ifndef __INC_CLOCKLESS_TRINKET_H -#define __INC_CLOCKLESS_TRINKET_H - -#include "../../controller.h" -#include "../../lib8tion.h" -#include <avr/interrupt.h> // for cli/se definitions - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_AVR) - -// Scaling macro choice -#ifndef TRINKET_SCALE -#define TRINKET_SCALE 1 -// whether or not to use dithering -#define DITHER 1 -#endif - -#if (F_CPU==8000000) -#define FASTLED_SLOW_CLOCK_ADJUST // asm __volatile__ ("mov r0,r0\n\t"); -#else -#define FASTLED_SLOW_CLOCK_ADJUST -#endif - -#define US_PER_TICK (64 / (F_CPU/1000000)) - -// Variations on the functions in delay.h - w/a loop var passed in to preserve registers across calls by the optimizer/compiler -template<int CYCLES> inline void _dc(register uint8_t & loopvar); - -template<int _LOOP, int PAD> __attribute__((always_inline)) inline void _dc_AVR(register uint8_t & loopvar) { - _dc<PAD>(loopvar); - // The convolution in here is to ensure that the state of the carry flag coming into the delay loop is preserved - asm __volatile__ ( "BRCS L_PC%=\n\t" - " LDI %[loopvar], %[_LOOP]\n\tL_%=: DEC %[loopvar]\n\t BRNE L_%=\n\tBREQ L_DONE%=\n\t" - "L_PC%=: LDI %[loopvar], %[_LOOP]\n\tLL_%=: DEC %[loopvar]\n\t BRNE LL_%=\n\tBSET 0\n\t" - "L_DONE%=:\n\t" - : - [loopvar] "+a" (loopvar) : [_LOOP] "M" (_LOOP) : ); -} - -template<int CYCLES> __attribute__((always_inline)) inline void _dc(register uint8_t & loopvar) { - _dc_AVR<CYCLES/6,CYCLES%6>(loopvar); -} -template<> __attribute__((always_inline)) inline void _dc<-6>(register uint8_t & ) {} -template<> __attribute__((always_inline)) inline void _dc<-5>(register uint8_t & ) {} -template<> __attribute__((always_inline)) inline void _dc<-4>(register uint8_t & ) {} -template<> __attribute__((always_inline)) inline void _dc<-3>(register uint8_t & ) {} -template<> __attribute__((always_inline)) inline void _dc<-2>(register uint8_t & ) {} -template<> __attribute__((always_inline)) inline void _dc<-1>(register uint8_t & ) {} -template<> __attribute__((always_inline)) inline void _dc< 0>(register uint8_t & ) {} -template<> __attribute__((always_inline)) inline void _dc< 1>(register uint8_t & ) {asm __volatile__("mov r0,r0":::);} -#if defined(__LGT8F__) -template<> __attribute__((always_inline)) inline void _dc< 2>(register uint8_t & loopvar) { _dc<1>(loopvar); _dc<1>(loopvar); } -#else -template<> __attribute__((always_inline)) inline void _dc< 2>(register uint8_t & ) {asm __volatile__("rjmp .+0":::);} -#endif -template<> __attribute__((always_inline)) inline void _dc< 3>(register uint8_t & loopvar) { _dc<2>(loopvar); _dc<1>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc< 4>(register uint8_t & loopvar) { _dc<2>(loopvar); _dc<2>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc< 5>(register uint8_t & loopvar) { _dc<2>(loopvar); _dc<3>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc< 6>(register uint8_t & loopvar) { _dc<2>(loopvar); _dc<2>(loopvar); _dc<2>(loopvar);} -template<> __attribute__((always_inline)) inline void _dc< 7>(register uint8_t & loopvar) { _dc<4>(loopvar); _dc<3>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc< 8>(register uint8_t & loopvar) { _dc<4>(loopvar); _dc<4>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc< 9>(register uint8_t & loopvar) { _dc<5>(loopvar); _dc<4>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<10>(register uint8_t & loopvar) { _dc<6>(loopvar); _dc<4>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<11>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<1>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<12>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<2>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<13>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<3>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<14>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<4>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<15>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<5>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<16>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<6>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<17>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<7>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<18>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<8>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<19>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<9>(loopvar); } -template<> __attribute__((always_inline)) inline void _dc<20>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<10>(loopvar); } - -#define DINTPIN(T,ADJ,PINADJ) (T-(PINADJ+ADJ)>0) ? _dc<T-(PINADJ+ADJ)>(loopvar) : _dc<0>(loopvar); -#define DINT(T,ADJ) if(AVR_PIN_CYCLES(DATA_PIN)==1) { DINTPIN(T,ADJ,1) } else { DINTPIN(T,ADJ,2); } -#define _D1(ADJ) DINT(T1,ADJ) -#define _D2(ADJ) DINT(T2,ADJ) -#define _D3(ADJ) DINT(T3,ADJ) - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. The first point -// is where the line is raised hi. The second point is where the line is dropped low for a zero. The third point is where the -// line is dropped low for a one. T1, T2, and T3 correspond to the timings for those three in clock cycles. -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#if (!defined(NO_CORRECTION) || (NO_CORRECTION == 0)) && (FASTLED_ALLOW_INTERRUPTS == 0) -static uint8_t gTimeErrorAccum256ths; -#endif - -#define FASTLED_HAS_CLOCKLESS 1 - -template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 10> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - static_assert(T1 >= 2 && T2 >= 2 && T3 >= 3, "Not enough cycles - use a higher clock speed"); - - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<DATA_PIN>::port_t data_t; - - CMinWait<WAIT_TIME> mWait; - -public: - virtual void init() { - FastPin<DATA_PIN>::setOutput(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - - mWait.wait(); - cli(); - - showRGBInternal(pixels); - - // Adjust the timer -#if (!defined(NO_CORRECTION) || (NO_CORRECTION == 0)) && (FASTLED_ALLOW_INTERRUPTS == 0) - uint32_t microsTaken = (uint32_t)pixels.size() * (uint32_t)CLKS_TO_MICROS(24 * (T1 + T2 + T3)); - - // adust for approximate observed actal runtime (as of January 2015) - // roughly 9.6 cycles per pixel, which is 0.6us/pixel at 16MHz - // microsTaken += nLeds * 0.6 * CLKS_TO_MICROS(16); - microsTaken += scale16by8(pixels.size(),(0.6 * 256) + 1) * CLKS_TO_MICROS(16); - - // if less than 1000us, there is NO timer impact, - // this is because the ONE interrupt that might come in while interrupts - // are disabled is queued up, and it will be serviced as soon as - // interrupts are re-enabled. - // This actually should technically also account for the runtime of the - // interrupt handler itself, but we're just not going to worry about that. - if( microsTaken > 1000) { - - // Since up to one timer tick will be queued, we don't need - // to adjust the MS_COUNTER for that one. - microsTaken -= 1000; - - // Now convert microseconds to 256ths of a second, approximately like this: - // 250ths = (us/4) - // 256ths = 250ths * (263/256); - uint16_t x256ths = microsTaken >> 2; - x256ths += scale16by8(x256ths,7); - - x256ths += gTimeErrorAccum256ths; - MS_COUNTER += (x256ths >> 8); - gTimeErrorAccum256ths = x256ths & 0xFF; - } - -#if 0 - // For pixel counts of 30 and under at 16Mhz, no correction is necessary. - // For pixel counts of 15 and under at 8Mhz, no correction is necessary. - // - // This code, below, is smaller, and quicker clock correction, which drifts much - // more significantly, but is a few bytes smaller. Presented here for consideration - // as an alternate on the ATtiny, which can't have more than about 150 pixels MAX - // anyway, meaning that microsTaken will never be more than about 4,500, which fits in - // a 16-bit variable. The difference between /1000 and /1024 only starts showing - // up in the range of about 100 pixels, so many ATtiny projects won't even - // see a clock difference due to the approximation there. - uint16_t microsTaken = (uint32_t)nLeds * (uint32_t)CLKS_TO_MICROS((24) * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken >> 10); -#endif - -#endif - - sei(); - mWait.mark(); - } -#define USE_ASM_MACROS - -#if defined(__AVR_ATmega4809__) -#define ASM_VAR_PORT "r" (((PORT_t*)FastPin<DATA_PIN>::port())->OUT) -#else -#define ASM_VAR_PORT "M" (FastPin<DATA_PIN>::port() - 0x20) -#endif - -// The variables that our various asm statements use. The same block of variables needs to be declared for -// all the asm blocks because GCC is pretty stupid and it would clobber variables happily or optimize code away too aggressively -#define ASM_VARS : /* write variables */ \ - [count] "+x" (count), \ - [data] "+z" (data), \ - [b1] "+a" (b1), \ - [d0] "+r" (d0), \ - [d1] "+r" (d1), \ - [d2] "+r" (d2), \ - [loopvar] "+a" (loopvar), \ - [scale_base] "+a" (scale_base) \ - : /* use variables */ \ - [ADV] "r" (advanceBy), \ - [b0] "a" (b0), \ - [hi] "r" (hi), \ - [lo] "r" (lo), \ - [s0] "r" (s0), \ - [s1] "r" (s1), \ - [s2] "r" (s2), \ - [e0] "r" (e0), \ - [e1] "r" (e1), \ - [e2] "r" (e2), \ - [PORT] ASM_VAR_PORT, \ - [O0] "M" (RGB_BYTE0(RGB_ORDER)), \ - [O1] "M" (RGB_BYTE1(RGB_ORDER)), \ - [O2] "M" (RGB_BYTE2(RGB_ORDER)) \ - : "cc" /* clobber registers */ -// Note: the code in the else in HI1/LO1 will be turned into an sts (2 cycle, 2 word) opcode -// 1 cycle, write hi to the port -#define HI1 FASTLED_SLOW_CLOCK_ADJUST if((int)(FastPin<DATA_PIN>::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); } else { *FastPin<DATA_PIN>::port()=hi; } -// 1 cycle, write lo to the port -#define LO1 if((int)(FastPin<DATA_PIN>::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); } else { *FastPin<DATA_PIN>::port()=lo; } - -// 2 cycles, sbrs on flipping the line to lo if we're pushing out a 0 -#define QLO2(B, N) asm __volatile__("sbrs %[" #B "], " #N ASM_VARS ); LO1; -// load a byte from ram into the given var with the given offset -#define LD2(B,O) asm __volatile__("ldd %[" #B "], Z + %[" #O "]\n\t" ASM_VARS ); -// 4 cycles - load a byte from ram into the scaling scratch space with the given offset, clear the target var, clear carry -#define LDSCL4(B,O) asm __volatile__("ldd %[scale_base], Z + %[" #O "]\n\tclr %[" #B "]\n\tclc\n\t" ASM_VARS ); - -#if (DITHER==1) -// apply dithering value before we do anything with scale_base -#define PRESCALE4(D) asm __volatile__("cpse %[scale_base], __zero_reg__\n\t add %[scale_base],%[" #D "]\n\tbrcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\t" ASM_VARS); - -// Do the add for the prescale -#define PRESCALEA2(D) asm __volatile__("cpse %[scale_base], __zero_reg__\n\t add %[scale_base],%[" #D "]\n\t" ASM_VARS); - -// Do the clamp for the prescale, clear carry when we're done - NOTE: Must ensure carry flag state is preserved! -#define PRESCALEB4(D) asm __volatile__("brcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\tneg %[" #D "]\n\tCLC" ASM_VARS); - -// Clamp for prescale, increment data, since we won't ever wrap 65k, this also effectively clears carry for us -#define PSBIDATA4(D) asm __volatile__("brcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\tadd %A[data], %[ADV]\n\tadc %B[data], __zero_reg__\n\t" ASM_VARS); - -#else -#define PRESCALE4(D) _dc<4>(loopvar); -#define PRESCALEA2(D) _dc<2>(loopvar); -#define PRESCALEB4(D) _dc<4>(loopvar); -#define PSBIDATA4(D) asm __volatile__( "add %A[data], %[ADV]\n\tadc %B[data], __zero_reg__\n\trjmp .+0\n\t" ASM_VARS ); -#endif - -// 2 cycles - perform one step of the scaling (if a given bit is set in scale, add scale-base to the scratch space) -#define _SCALE02(B, N) "sbrc %[s0], " #N "\n\tadd %[" #B "], %[scale_base]\n\t" -#define _SCALE12(B, N) "sbrc %[s1], " #N "\n\tadd %[" #B "], %[scale_base]\n\t" -#define _SCALE22(B, N) "sbrc %[s2], " #N "\n\tadd %[" #B "], %[scale_base]\n\t" -#define SCALE02(B,N) asm __volatile__( _SCALE02(B,N) ASM_VARS ); -#define SCALE12(B,N) asm __volatile__( _SCALE12(B,N) ASM_VARS ); -#define SCALE22(B,N) asm __volatile__( _SCALE22(B,N) ASM_VARS ); - -// 1 cycle - rotate right, pulling in from carry -#define _ROR1(B) "ror %[" #B "]\n\t" -#define ROR1(B) asm __volatile__( _ROR1(B) ASM_VARS); - -// 1 cycle, clear the carry bit -#define _CLC1 "clc\n\t" -#define CLC1 asm __volatile__( _CLC1 ASM_VARS ); - -// 2 cycles, rortate right, pulling in from carry then clear the carry bit -#define RORCLC2(B) asm __volatile__( _ROR1(B) _CLC1 ASM_VARS ); - -// 4 cycles, rotate, clear carry, scale next bit -#define RORSC04(B, N) asm __volatile__( _ROR1(B) _CLC1 _SCALE02(B, N) ASM_VARS ); -#define RORSC14(B, N) asm __volatile__( _ROR1(B) _CLC1 _SCALE12(B, N) ASM_VARS ); -#define RORSC24(B, N) asm __volatile__( _ROR1(B) _CLC1 _SCALE22(B, N) ASM_VARS ); - -// 4 cycles, scale bit, rotate, clear carry -#define SCROR04(B, N) asm __volatile__( _SCALE02(B,N) _ROR1(B) _CLC1 ASM_VARS ); -#define SCROR14(B, N) asm __volatile__( _SCALE12(B,N) _ROR1(B) _CLC1 ASM_VARS ); -#define SCROR24(B, N) asm __volatile__( _SCALE22(B,N) _ROR1(B) _CLC1 ASM_VARS ); - -///////////////////////////////////////////////////////////////////////////////////// -// Loop life cycle - -// dither adjustment macro - should be kept in sync w/what's in stepDithering -// #define ADJDITHER2(D, E) D = E - D; -#define _NEGD1(D) "neg %[" #D "]\n\t" -#define _ADJD1(D,E) "add %[" #D "], %[" #E "]\n\t" -#define ADJDITHER2(D, E) asm __volatile__ ( _NEGD1(D) _ADJD1(D, E) ASM_VARS); -#define ADDDE1(D, E) asm __volatile__ ( _ADJD1(D, E) ASM_VARS ); - -// #define xstr(a) str(a) -// #define str(a) #a -// #define ADJDITHER2(D,E) asm __volatile__("subi %[" #D "], " xstr(DUSE) "\n\tand %[" #D "], %[" #E "]\n\t" ASM_VARS); - -// define the beginning of the loop -#define LOOP asm __volatile__("1:" ASM_VARS ); -// define the end of the loop -#define DONE asm __volatile__("2:" ASM_VARS ); - -// 2 cycles - increment the data pointer -#define IDATA2 asm __volatile__("add %A[data], %[ADV]\n\tadc %B[data], __zero_reg__\n\t" ASM_VARS ); -#define IDATACLC3 asm __volatile__("add %A[data], %[ADV]\n\tadc %B[data], __zero_reg__\n\t" _CLC1 ASM_VARS ); - -// 1 cycle mov -#define _MOV1(B1, B2) "mov %[" #B1 "], %[" #B2 "]\n\t" - -#define MOV1(B1, B2) asm __volatile__( _MOV1(B1,B2) ASM_VARS ); - -// 3 cycle mov - skip if scale fix is happening -#if (FASTLED_SCALE8_FIXED == 1) -#define _MOV_FIX03(B1, B2) "mov %[" #B1 "], %[scale_base]\n\tcpse %[s0], __zero_reg__\n\t" _MOV1(B1, B2) -#define _MOV_FIX13(B1, B2) "mov %[" #B1 "], %[scale_base]\n\tcpse %[s1], __zero_reg__\n\t" _MOV1(B1, B2) -#define _MOV_FIX23(B1, B2) "mov %[" #B1 "], %[scale_base]\n\tcpse %[s2], __zero_reg__\n\t" _MOV1(B1, B2) -#else -// if we haven't fixed scale8, just do the move and nop the 2 cycles that would be used to -// do the fixed adjustment -#define _MOV_FIX03(B1, B2) _MOV1(B1, B2) "rjmp .+0\n\t" -#define _MOV_FIX13(B1, B2) _MOV1(B1, B2) "rjmp .+0\n\t" -#define _MOV_FIX23(B1, B2) _MOV1(B1, B2) "rjmp .+0\n\t" -#endif - -// 3 cycle mov + negate D for dither adjustment -#define MOV_NEGD04(B1, B2, D) asm __volatile( _MOV_FIX03(B1, B2) _NEGD1(D) ASM_VARS ); -#define MOV_ADDDE04(B1, B2, D, E) asm __volatile( _MOV_FIX03(B1, B2) _ADJD1(D, E) ASM_VARS ); -#define MOV_NEGD14(B1, B2, D) asm __volatile( _MOV_FIX13(B1, B2) _NEGD1(D) ASM_VARS ); -#define MOV_ADDDE14(B1, B2, D, E) asm __volatile( _MOV_FIX13(B1, B2) _ADJD1(D, E) ASM_VARS ); -#define MOV_NEGD24(B1, B2, D) asm __volatile( _MOV_FIX23(B1, B2) _NEGD1(D) ASM_VARS ); - -// 2 cycles - decrement the counter -#define DCOUNT2 asm __volatile__("sbiw %[count], 1" ASM_VARS ); -// 2 cycles - jump to the beginning of the loop -#define JMPLOOP2 asm __volatile__("rjmp 1b" ASM_VARS ); -// 2 cycles - jump out of the loop -#define BRLOOP1 asm __volatile__("brne 3\n\trjmp 2f\n\t3:" ASM_VARS ); - -// 5 cycles 2 sbiw, 3 for the breq/rjmp -#define ENDLOOP5 asm __volatile__("sbiw %[count], 1\n\tbreq L_%=\n\trjmp 1b\n\tL_%=:\n\t" ASM_VARS); - -// NOP using the variables, forcing a move -#define DNOP asm __volatile__("mov r0,r0" ASM_VARS); - -#define DADVANCE 3 -#define DUSE (0xFF - (DADVANCE-1)) - -// Silence compiler warnings about switch/case that is explicitly intended to fall through. -#define FL_FALLTHROUGH __attribute__ ((fallthrough)); - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static void /*__attribute__((optimize("O0")))*/ /*__attribute__ ((always_inline))*/ showRGBInternal(PixelController<RGB_ORDER> & pixels) { - uint8_t *data = (uint8_t*)pixels.mData; - data_ptr_t port = FastPin<DATA_PIN>::port(); - data_t mask = FastPin<DATA_PIN>::mask(); - uint8_t scale_base = 0; - - // register uint8_t *end = data + nLeds; - data_t hi = *port | mask; - data_t lo = *port & ~mask; - *port = lo; - - // the byte currently being written out - uint8_t b0 = 0; - // the byte currently being worked on to write the next out - uint8_t b1 = 0; - - // Setup the pixel controller - pixels.preStepFirstByteDithering(); - - // pull the dithering/adjustment values out of the pixels object for direct asm access - uint8_t advanceBy = pixels.advanceBy(); - uint16_t count = pixels.mLen; - - uint8_t s0 = pixels.mScale.raw[RO(0)]; - uint8_t s1 = pixels.mScale.raw[RO(1)]; - uint8_t s2 = pixels.mScale.raw[RO(2)]; -#if (FASTLED_SCALE8_FIXED==1) - s0++; s1++; s2++; -#endif - uint8_t d0 = pixels.d[RO(0)]; - uint8_t d1 = pixels.d[RO(1)]; - uint8_t d2 = pixels.d[RO(2)]; - uint8_t e0 = pixels.e[RO(0)]; - uint8_t e1 = pixels.e[RO(1)]; - uint8_t e2 = pixels.e[RO(2)]; - - uint8_t loopvar=0; - - // This has to be done in asm to keep gcc from messing up the asm code further down - b0 = data[RO(0)]; - { - LDSCL4(b0,O0) PRESCALEA2(d0) - PRESCALEB4(d0) SCALE02(b0,0) - RORSC04(b0,1) ROR1(b0) CLC1 - SCROR04(b0,2) SCALE02(b0,3) - RORSC04(b0,4) ROR1(b0) CLC1 - SCROR04(b0,5) SCALE02(b0,6) - RORSC04(b0,7) ROR1(b0) CLC1 - MOV_ADDDE04(b1,b0,d0,e0) - MOV1(b0,b1) - } - - { - // while(--count) - { - // Loop beginning - DNOP; - LOOP; - - // Sum of the clock counts across each row should be 10 for 8Mhz, WS2811 - // The values in the D1/D2/D3 indicate how many cycles the previous column takes - // to allow things to line back up. - // - // While writing out byte 0, we're loading up byte 1, applying the dithering adjustment, - // then scaling it using 8 cycles of shift/add interleaved in between writing the bits - // out. When doing byte 1, we're doing the above for byte 2. When we're doing byte 2, - // we're cycling back around and doing the above for byte 0. - - // Inline scaling - RGB ordering - // DNOP - HI1 _D1(1) QLO2(b0, 7) LDSCL4(b1,O1) _D2(4) LO1 PRESCALEA2(d1) _D3(2) - HI1 _D1(1) QLO2(b0, 6) PRESCALEB4(d1) _D2(4) LO1 SCALE12(b1,0) _D3(2) - HI1 _D1(1) QLO2(b0, 5) RORSC14(b1,1) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 4) SCROR14(b1,2) _D2(4) LO1 SCALE12(b1,3) _D3(2) - HI1 _D1(1) QLO2(b0, 3) RORSC14(b1,4) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 2) SCROR14(b1,5) _D2(4) LO1 SCALE12(b1,6) _D3(2) - HI1 _D1(1) QLO2(b0, 1) RORSC14(b1,7) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 0) - switch(XTRA0) { - case 4: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 3: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 2: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 1: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) - } - MOV_ADDDE14(b0,b1,d1,e1) _D2(4) LO1 _D3(0) - - HI1 _D1(1) QLO2(b0, 7) LDSCL4(b1,O2) _D2(4) LO1 PRESCALEA2(d2) _D3(2) - HI1 _D1(1) QLO2(b0, 6) PSBIDATA4(d2) _D2(4) LO1 SCALE22(b1,0) _D3(2) - HI1 _D1(1) QLO2(b0, 5) RORSC24(b1,1) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 4) SCROR24(b1,2) _D2(4) LO1 SCALE22(b1,3) _D3(2) - HI1 _D1(1) QLO2(b0, 3) RORSC24(b1,4) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 2) SCROR24(b1,5) _D2(4) LO1 SCALE22(b1,6) _D3(2) - HI1 _D1(1) QLO2(b0, 1) RORSC24(b1,7) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 0) - switch(XTRA0) { - case 4: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 3: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 2: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 1: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) - } - - // Because Prescale on the middle byte also increments the data counter, - // we have to do both halves of updating d2 here - negating it (in the - // MOV_NEGD24 macro) and then adding E back into it - MOV_NEGD24(b0,b1,d2) _D2(4) LO1 ADDDE1(d2,e2) _D3(1) - HI1 _D1(1) QLO2(b0, 7) LDSCL4(b1,O0) _D2(4) LO1 PRESCALEA2(d0) _D3(2) - HI1 _D1(1) QLO2(b0, 6) PRESCALEB4(d0) _D2(4) LO1 SCALE02(b1,0) _D3(2) - HI1 _D1(1) QLO2(b0, 5) RORSC04(b1,1) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 4) SCROR04(b1,2) _D2(4) LO1 SCALE02(b1,3) _D3(2) - HI1 _D1(1) QLO2(b0, 3) RORSC04(b1,4) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 2) SCROR04(b1,5) _D2(4) LO1 SCALE02(b1,6) _D3(2) - HI1 _D1(1) QLO2(b0, 1) RORSC04(b1,7) _D2(4) LO1 RORCLC2(b1) _D3(2) - HI1 _D1(1) QLO2(b0, 0) - switch(XTRA0) { - case 4: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 3: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 2: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) /* fall through */ - case 1: _D2(0) LO1 _D3(0) HI1 _D1(1) QLO2(b0,0) - } - MOV_ADDDE04(b0,b1,d0,e0) _D2(4) LO1 _D3(5) - ENDLOOP5 - } - DONE; - } - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - // stop using the clock juggler - TCCR0A &= ~0x30; - #endif - } - -}; - -#endif - -FASTLED_NAMESPACE_END - -#endif diff --git a/FastLED/src/platforms/avr/fastled_avr.h b/FastLED/src/platforms/avr/fastled_avr.h deleted file mode 100644 index 47236f44b264a4c10d9616d7716044aa9ed760e3..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/avr/fastled_avr.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __INC_FASTLED_AVR_H -#define __INC_FASTLED_AVR_H - -#include "fastpin_avr.h" -#include "fastspi_avr.h" -#include "clockless_trinket.h" - -// Default to using PROGMEM -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 1 -#endif - -#endif diff --git a/FastLED/src/platforms/avr/fastpin_avr.h b/FastLED/src/platforms/avr/fastpin_avr.h deleted file mode 100644 index db2beeaf27ea4bec5282763ee6b17c0c263dc6d3..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/avr/fastpin_avr.h +++ /dev/null @@ -1,410 +0,0 @@ -#ifndef __INC_FASTPIN_AVR_H -#define __INC_FASTPIN_AVR_H - -FASTLED_NAMESPACE_BEGIN - -#if defined(FASTLED_FORCE_SOFTWARE_PINS) -#warning "Software pin support forced, pin access will be slightly slower." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - -#define AVR_PIN_CYCLES(_PIN) ((((int)FastPin<_PIN>::port())-0x20 < 64) ? 1 : 2) - -/// Class definition for a Pin where we know the port registers at compile time for said pin. This allows us to make -/// a lot of optimizations, as the inlined hi/lo methods will devolve to a single io register write/bitset. -template<uint8_t PIN, uint8_t _MASK, typename _PORT, typename _DDR, typename _PIN> class _AVRPIN { -public: - typedef volatile uint8_t * port_ptr_t; - typedef uint8_t port_t; - - inline static void setOutput() { _DDR::r() |= _MASK; } - inline static void setInput() { _DDR::r() &= ~_MASK; } - - inline static void hi() __attribute__ ((always_inline)) { _PORT::r() |= _MASK; } - inline static void lo() __attribute__ ((always_inline)) { _PORT::r() &= ~_MASK; } - inline static void set(register uint8_t val) __attribute__ ((always_inline)) { _PORT::r() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { _PIN::r() = _MASK; } - - inline static void hi(register port_ptr_t /*port*/) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t /*port*/) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t /*port*/, register uint8_t val) __attribute__ ((always_inline)) { set(val); } - - inline static port_t hival() __attribute__ ((always_inline)) { return _PORT::r() | _MASK; } - inline static port_t loval() __attribute__ ((always_inline)) { return _PORT::r() & ~_MASK; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PORT::r(); } - inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } -}; - - - -/// AVR definitions for pins. Getting around the fact that I can't pass GPIO register addresses in as template arguments by instead creating -/// a custom type for each GPIO register with a single, static, aggressively inlined function that returns that specific GPIO register. A similar -/// trick is used a bit further below for the ARM GPIO registers (of which there are far more than on AVR!) -typedef volatile uint8_t & reg8_t; -#define _R(T) struct __gen_struct_ ## T -#define _RD8(T) struct __gen_struct_ ## T { static inline reg8_t r() { return T; }}; - -// Register name equivalent (using flat names) -#if defined(AVR_ATtinyxy7) || defined(AVR_ATtinyxy6) || defined(AVR_ATtinyxy4) || defined(AVR_ATtinyxy2) || defined(__AVR_ATmega4809__) -// ATtiny series 0/1 and ATmega series 0 -#define _FL_IO(L,C) _RD8(PORT ## L ## _DIR); _RD8(PORT ## L ## _OUT); _RD8(PORT ## L ## _IN); _FL_DEFINE_PORT3(L, C, _R(PORT ## L ## _OUT)); -#define _FL_DEFPIN(_PIN, BIT, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1<<BIT, _R(PORT ## L ## _OUT), _R(PORT ## L ## _DIR), _R(PORT ## L ## _IN)> {}; -#else -// Others -#define _FL_IO(L,C) _RD8(DDR ## L); _RD8(PORT ## L); _RD8(PIN ## L); _FL_DEFINE_PORT3(L, C, _R(PORT ## L)); -#define _FL_DEFPIN(_PIN, BIT, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1<<BIT, _R(PORT ## L), _R(DDR ## L), _R(PIN ## L)> {}; -#endif - -// Pre-do all the port definitions -#ifdef PORTA - _FL_IO(A,0) -#endif -#ifdef PORTB - _FL_IO(B,1) -#endif -#ifdef PORTC - _FL_IO(C,2) -#endif -#ifdef PORTD - _FL_IO(D,3) -#endif -#ifdef PORTE - _FL_IO(E,4) -#endif -#ifdef PORTF - _FL_IO(F,5) -#endif -#ifdef PORTG - _FL_IO(G,6) -#endif -#ifdef PORTH - _FL_IO(H,7) -#endif -#ifdef PORTI - _FL_IO(I,8) -#endif -#ifdef PORTJ - _FL_IO(J,9) -#endif -#ifdef PORTK - _FL_IO(K,10) -#endif -#ifdef PORTL - _FL_IO(L,11) -#endif -#ifdef PORTM - _FL_IO(M,12) -#endif -#ifdef PORTN - _FL_IO(N,13) -#endif - -#if defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny25__) - -#if defined(__AVR_ATtiny25__) -#pragma message "ATtiny25 has very limited storage. This library could use up to more than 100% of its flash size" -#endif - -#define MAX_PIN 5 - -_FL_DEFPIN(0, 0, B); _FL_DEFPIN(1, 1, B); _FL_DEFPIN(2, 2, B); _FL_DEFPIN(3, 3, B); -_FL_DEFPIN(4, 4, B); _FL_DEFPIN(5, 5, B); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(__AVR_ATtiny841__) || defined(__AVR_ATtiny441__) -#define MAX_PIN 11 - -_FL_DEFPIN(0, 0, B); _FL_DEFPIN(1, 1, B); _FL_DEFPIN(2, 2, B); -_FL_DEFPIN(3, 7, A); _FL_DEFPIN(4, 6, A); _FL_DEFPIN(5, 5, A); -_FL_DEFPIN(6, 4, A); _FL_DEFPIN(7, 3, A); _FL_DEFPIN(8, 2, A); -_FL_DEFPIN(9, 1, A); _FL_DEFPIN(10, 0, A); _FL_DEFPIN(11, 3, B); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_AVR_DIGISPARK) // digispark pin layout -#define MAX_PIN 5 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -_FL_DEFPIN(0, 0, B); _FL_DEFPIN(1, 1, B); _FL_DEFPIN(2, 2, B); -_FL_DEFPIN(3, 7, A); _FL_DEFPIN(4, 6, A); _FL_DEFPIN(5, 5, A); - -#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) - -#define MAX_PIN 10 - -_FL_DEFPIN(0, 0, A); _FL_DEFPIN(1, 1, A); _FL_DEFPIN(2, 2, A); _FL_DEFPIN(3, 3, A); -_FL_DEFPIN(4, 4, A); _FL_DEFPIN(5, 5, A); _FL_DEFPIN(6, 6, A); _FL_DEFPIN(7, 7, A); -_FL_DEFPIN(8, 2, B); _FL_DEFPIN(9, 1, B); _FL_DEFPIN(10, 0, B); - -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(ARDUINO_AVR_DIGISPARKPRO) - -#define MAX_PIN 12 - -_FL_DEFPIN(0, 0, B); _FL_DEFPIN(1, 1, B); _FL_DEFPIN(2, 2, B); _FL_DEFPIN(3, 5, B); -_FL_DEFPIN(4, 3, B); _FL_DEFPIN(5, 7, A); _FL_DEFPIN(6, 0, A); _FL_DEFPIN(7, 1, A); -_FL_DEFPIN(8, 2, A); _FL_DEFPIN(9, 3, A); _FL_DEFPIN(10, 4, A); _FL_DEFPIN(11, 5, A); -_FL_DEFPIN(12, 6, A); - -#elif defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny87__) - -#define MAX_PIN 15 - -_FL_DEFPIN(0, 0, A); _FL_DEFPIN(1, 1, A); _FL_DEFPIN(2, 2, A); _FL_DEFPIN(3, 3, A); -_FL_DEFPIN(4, 4, A); _FL_DEFPIN(5, 5, A); _FL_DEFPIN(6, 6, A); _FL_DEFPIN(7, 7, A); -_FL_DEFPIN(8, 0, B); _FL_DEFPIN(9, 1, B); _FL_DEFPIN(10, 2, B); _FL_DEFPIN(11, 3, B); -_FL_DEFPIN(12, 4, B); _FL_DEFPIN(13, 5, B); _FL_DEFPIN(14, 6, B); _FL_DEFPIN(15, 7, B); - -#define SPI_DATA 4 -#define SPI_CLOCK 5 -#define AVR_HARDWARE_SPI 1 - -#define HAS_HARDWARE_PIN_SUPPORT 1 -#elif defined(ARDUINO_HOODLOADER2) && (defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)) || defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) - -#define MAX_PIN 20 - -_FL_DEFPIN( 0, 0, B); _FL_DEFPIN( 1, 1, B); _FL_DEFPIN( 2, 2, B); _FL_DEFPIN( 3, 3, B); -_FL_DEFPIN( 4, 4, B); _FL_DEFPIN( 5, 5, B); _FL_DEFPIN( 6, 6, B); _FL_DEFPIN( 7, 7, B); - -_FL_DEFPIN( 8, 7, C); _FL_DEFPIN( 9, 6, C); _FL_DEFPIN( 10, 5,C); _FL_DEFPIN( 11, 4, C); -_FL_DEFPIN( 12, 2, C); _FL_DEFPIN( 13, 0, D); _FL_DEFPIN( 14, 1, D); _FL_DEFPIN(15, 2, D); -_FL_DEFPIN( 16, 3, D); _FL_DEFPIN( 17, 4, D); _FL_DEFPIN( 18, 5, D); _FL_DEFPIN( 19, 6, D); -_FL_DEFPIN( 20, 7, D); - -#define HAS_HARDWARE_PIN_SUPPORT 1 -// #define SPI_DATA 2 -// #define SPI_CLOCK 1 -// #define AVR_HARDWARE_SPI 1 - -#elif defined(IS_BEAN) - -#define MAX_PIN 19 -_FL_DEFPIN( 0, 6, D); _FL_DEFPIN( 1, 1, B); _FL_DEFPIN( 2, 2, B); _FL_DEFPIN( 3, 3, B); -_FL_DEFPIN( 4, 4, B); _FL_DEFPIN( 5, 5, B); _FL_DEFPIN( 6, 0, D); _FL_DEFPIN( 7, 7, D); -_FL_DEFPIN( 8, 0, B); _FL_DEFPIN( 9, 1, D); _FL_DEFPIN(10, 2, D); _FL_DEFPIN(11, 3, D); -_FL_DEFPIN(12, 4, D); _FL_DEFPIN(13, 5, D); _FL_DEFPIN(14, 0, C); _FL_DEFPIN(15, 1, C); -_FL_DEFPIN(16, 2, C); _FL_DEFPIN(17, 3, C); _FL_DEFPIN(18, 4, C); _FL_DEFPIN(19, 5, C); - -#define SPI_DATA 3 -#define SPI_CLOCK 5 -#define SPI_SELECT 2 -#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#ifndef __AVR_ATmega8__ -#define SPI_UART0_DATA 9 -#define SPI_UART0_CLOCK 12 -#endif - -#elif defined(ARDUINO_AVR_NANO_EVERY) - -#define MAX_PIN 22 -_FL_DEFPIN(0, 5, C); _FL_DEFPIN(1, 4, C); _FL_DEFPIN(2, 0, A); _FL_DEFPIN(3, 5, F); -_FL_DEFPIN(4, 6, C); _FL_DEFPIN(5, 2, B); _FL_DEFPIN(6, 4, F); _FL_DEFPIN(7, 1, A); -_FL_DEFPIN(8, 3, E); _FL_DEFPIN(9, 0, B); _FL_DEFPIN(10, 1, B); _FL_DEFPIN(11, 0, E); -_FL_DEFPIN(12, 1, E); _FL_DEFPIN(13, 2, E); _FL_DEFPIN(14, 3, D); _FL_DEFPIN(15, 2, D); -_FL_DEFPIN(16, 1, D); _FL_DEFPIN(17, 0, D); _FL_DEFPIN(18, 2, A); _FL_DEFPIN(19, 3, A); -_FL_DEFPIN(20, 4, D); _FL_DEFPIN(21, 5, D); _FL_DEFPIN(22, 2, A); - -// To confirm for the SPI interfaces -//#define SPI_DATA 18 -//#define SPI_CLOCK 13 -//#define SPI_SELECT 19 -//#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -//#define SPI_UART0_DATA 1 -//#define SPI_UART0_CLOCK 4 - -#elif defined(__AVR_ATmega4809__) - -#define MAX_PIN 21 -_FL_DEFPIN(0, 4, C); _FL_DEFPIN(1, 5, C); _FL_DEFPIN(2, 0, A); _FL_DEFPIN(3, 5, F); -_FL_DEFPIN(4, 6, C); _FL_DEFPIN(5, 2, B); _FL_DEFPIN(6, 4, F); _FL_DEFPIN(7, 1, A); -_FL_DEFPIN(8, 3, E); _FL_DEFPIN(9, 0, B); _FL_DEFPIN(10, 1, B); _FL_DEFPIN(11, 0, E); -_FL_DEFPIN(12, 1, E); _FL_DEFPIN(13, 2, E); _FL_DEFPIN(14, 3, D); _FL_DEFPIN(15, 2, D); -_FL_DEFPIN(16, 1, D); _FL_DEFPIN(17, 0, D); _FL_DEFPIN(18, 2, A); _FL_DEFPIN(19, 3, A); -_FL_DEFPIN(20, 4, D); _FL_DEFPIN(21, 5, D); - -// To confirm for the SPI interfaces -//#define SPI_DATA 18 -//#define SPI_CLOCK 13 -//#define SPI_SELECT 19 -//#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -//#define SPI_UART0_DATA 1 -//#define SPI_UART0_CLOCK 4 - -#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega8__) - -#define MAX_PIN 19 -_FL_DEFPIN( 0, 0, D); _FL_DEFPIN( 1, 1, D); _FL_DEFPIN( 2, 2, D); _FL_DEFPIN( 3, 3, D); -_FL_DEFPIN( 4, 4, D); _FL_DEFPIN( 5, 5, D); _FL_DEFPIN( 6, 6, D); _FL_DEFPIN( 7, 7, D); -_FL_DEFPIN( 8, 0, B); _FL_DEFPIN( 9, 1, B); _FL_DEFPIN(10, 2, B); _FL_DEFPIN(11, 3, B); -_FL_DEFPIN(12, 4, B); _FL_DEFPIN(13, 5, B); _FL_DEFPIN(14, 0, C); _FL_DEFPIN(15, 1, C); -_FL_DEFPIN(16, 2, C); _FL_DEFPIN(17, 3, C); _FL_DEFPIN(18, 4, C); _FL_DEFPIN(19, 5, C); - -#define SPI_DATA 11 -#define SPI_CLOCK 13 -#define SPI_SELECT 10 -#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#ifndef __AVR_ATmega8__ -#define SPI_UART0_DATA 1 -#define SPI_UART0_CLOCK 4 -#endif - -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega32__) || defined(__AVR_ATmega16__) - -#define MAX_PIN 31 -_FL_DEFPIN(0, 0, B); _FL_DEFPIN(1, 1, B); _FL_DEFPIN(2, 2, B); _FL_DEFPIN(3, 3, B); -_FL_DEFPIN(4, 4, B); _FL_DEFPIN(5, 5, B); _FL_DEFPIN(6, 6, B); _FL_DEFPIN(7, 7, B); -_FL_DEFPIN(8, 0, D); _FL_DEFPIN(9, 1, D); _FL_DEFPIN(10, 2, D); _FL_DEFPIN(11, 3, D); -_FL_DEFPIN(12, 4, D); _FL_DEFPIN(13, 5, D); _FL_DEFPIN(14, 6, D); _FL_DEFPIN(15, 7, D); -_FL_DEFPIN(16, 0, C); _FL_DEFPIN(17, 1, C); _FL_DEFPIN(18, 2, C); _FL_DEFPIN(19, 3, C); -_FL_DEFPIN(20, 4, C); _FL_DEFPIN(21, 5, C); _FL_DEFPIN(22, 6, C); _FL_DEFPIN(23, 7, C); -_FL_DEFPIN(24, 0, A); _FL_DEFPIN(25, 1, A); _FL_DEFPIN(26, 2, A); _FL_DEFPIN(27, 3, A); -_FL_DEFPIN(28, 4, A); _FL_DEFPIN(29, 5, A); _FL_DEFPIN(30, 6, A); _FL_DEFPIN(31, 7, A); - -#define SPI_DATA 5 -#define SPI_CLOCK 7 -#define SPI_SELECT 4 -#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) - -// AKA the Pinoccio -_FL_DEFPIN( 0, 0, E); _FL_DEFPIN( 1, 1, E); _FL_DEFPIN( 2, 7, B); _FL_DEFPIN( 3, 3, E); -_FL_DEFPIN( 4, 4, E); _FL_DEFPIN( 5, 5, E); _FL_DEFPIN( 6, 2, E); _FL_DEFPIN( 7, 6, E); -_FL_DEFPIN( 8, 5, D); _FL_DEFPIN( 9, 0, B); _FL_DEFPIN(10, 2, B); _FL_DEFPIN(11, 3, B); -_FL_DEFPIN(12, 1, B); _FL_DEFPIN(13, 2, D); _FL_DEFPIN(14, 3, D); _FL_DEFPIN(15, 0, D); -_FL_DEFPIN(16, 1, D); _FL_DEFPIN(17, 4, D); _FL_DEFPIN(18, 7, E); _FL_DEFPIN(19, 6, D); -_FL_DEFPIN(20, 7, D); _FL_DEFPIN(21, 4, B); _FL_DEFPIN(22, 5, B); _FL_DEFPIN(23, 6, B); -_FL_DEFPIN(24, 0, F); _FL_DEFPIN(25, 1, F); _FL_DEFPIN(26, 2, F); _FL_DEFPIN(27, 3, F); -_FL_DEFPIN(28, 4, F); _FL_DEFPIN(29, 5, F); _FL_DEFPIN(30, 6, F); _FL_DEFPIN(31, 7, F); - -#define SPI_DATA 10 -#define SPI_CLOCK 12 -#define SPI_SELECT 9 - -#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -// megas -#define MAX_PIN 69 -_FL_DEFPIN(0, 0, E); _FL_DEFPIN(1, 1, E); _FL_DEFPIN(2, 4, E); _FL_DEFPIN(3, 5, E); -_FL_DEFPIN(4, 5, G); _FL_DEFPIN(5, 3, E); _FL_DEFPIN(6, 3, H); _FL_DEFPIN(7, 4, H); -_FL_DEFPIN(8, 5, H); _FL_DEFPIN(9, 6, H); _FL_DEFPIN(10, 4, B); _FL_DEFPIN(11, 5, B); -_FL_DEFPIN(12, 6, B); _FL_DEFPIN(13, 7, B); _FL_DEFPIN(14, 1, J); _FL_DEFPIN(15, 0, J); -_FL_DEFPIN(16, 1, H); _FL_DEFPIN(17, 0, H); _FL_DEFPIN(18, 3, D); _FL_DEFPIN(19, 2, D); -_FL_DEFPIN(20, 1, D); _FL_DEFPIN(21, 0, D); _FL_DEFPIN(22, 0, A); _FL_DEFPIN(23, 1, A); -_FL_DEFPIN(24, 2, A); _FL_DEFPIN(25, 3, A); _FL_DEFPIN(26, 4, A); _FL_DEFPIN(27, 5, A); -_FL_DEFPIN(28, 6, A); _FL_DEFPIN(29, 7, A); _FL_DEFPIN(30, 7, C); _FL_DEFPIN(31, 6, C); -_FL_DEFPIN(32, 5, C); _FL_DEFPIN(33, 4, C); _FL_DEFPIN(34, 3, C); _FL_DEFPIN(35, 2, C); -_FL_DEFPIN(36, 1, C); _FL_DEFPIN(37, 0, C); _FL_DEFPIN(38, 7, D); _FL_DEFPIN(39, 2, G); -_FL_DEFPIN(40, 1, G); _FL_DEFPIN(41, 0, G); _FL_DEFPIN(42, 7, L); _FL_DEFPIN(43, 6, L); -_FL_DEFPIN(44, 5, L); _FL_DEFPIN(45, 4, L); _FL_DEFPIN(46, 3, L); _FL_DEFPIN(47, 2, L); -_FL_DEFPIN(48, 1, L); _FL_DEFPIN(49, 0, L); _FL_DEFPIN(50, 3, B); _FL_DEFPIN(51, 2, B); -_FL_DEFPIN(52, 1, B); _FL_DEFPIN(53, 0, B); _FL_DEFPIN(54, 0, F); _FL_DEFPIN(55, 1, F); -_FL_DEFPIN(56, 2, F); _FL_DEFPIN(57, 3, F); _FL_DEFPIN(58, 4, F); _FL_DEFPIN(59, 5, F); -_FL_DEFPIN(60, 6, F); _FL_DEFPIN(61, 7, F); _FL_DEFPIN(62, 0, K); _FL_DEFPIN(63, 1, K); -_FL_DEFPIN(64, 2, K); _FL_DEFPIN(65, 3, K); _FL_DEFPIN(66, 4, K); _FL_DEFPIN(67, 5, K); -_FL_DEFPIN(68, 6, K); _FL_DEFPIN(69, 7, K); - -#define SPI_DATA 51 -#define SPI_CLOCK 52 -#define SPI_SELECT 53 -#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -// Leonardo, teensy, blinkm -#elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) - -// teensy defs -#define MAX_PIN 23 -_FL_DEFPIN(0, 0, B); _FL_DEFPIN(1, 1, B); _FL_DEFPIN(2, 2, B); _FL_DEFPIN(3, 3, B); -_FL_DEFPIN(4, 7, B); _FL_DEFPIN(5, 0, D); _FL_DEFPIN(6, 1, D); _FL_DEFPIN(7, 2, D); -_FL_DEFPIN(8, 3, D); _FL_DEFPIN(9, 6, C); _FL_DEFPIN(10, 7, C); _FL_DEFPIN(11, 6, D); -_FL_DEFPIN(12, 7, D); _FL_DEFPIN(13, 4, B); _FL_DEFPIN(14, 5, B); _FL_DEFPIN(15, 6, B); -_FL_DEFPIN(16, 7, F); _FL_DEFPIN(17, 6, F); _FL_DEFPIN(18, 5, F); _FL_DEFPIN(19, 4, F); -_FL_DEFPIN(20, 1, F); _FL_DEFPIN(21, 0, F); _FL_DEFPIN(22, 4, D); _FL_DEFPIN(23, 5, D); - -#define SPI_DATA 2 -#define SPI_CLOCK 1 -#define SPI_SELECT 0 -#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -// PD3/PD5 -#define SPI_UART1_DATA 8 -#define SPI_UART1_CLOCK 23 - -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) -// teensy++ 2 defs -#define MAX_PIN 45 -_FL_DEFPIN(0, 0, D); _FL_DEFPIN(1, 1, D); _FL_DEFPIN(2, 2, D); _FL_DEFPIN(3, 3, D); -_FL_DEFPIN(4, 4, D); _FL_DEFPIN(5, 5, D); _FL_DEFPIN(6, 6, D); _FL_DEFPIN(7, 7, D); -_FL_DEFPIN(8, 0, E); _FL_DEFPIN(9, 1, E); _FL_DEFPIN(10, 0, C); _FL_DEFPIN(11, 1, C); -_FL_DEFPIN(12, 2, C); _FL_DEFPIN(13, 3, C); _FL_DEFPIN(14, 4, C); _FL_DEFPIN(15, 5, C); -_FL_DEFPIN(16, 6, C); _FL_DEFPIN(17, 7, C); _FL_DEFPIN(18, 6, E); _FL_DEFPIN(19, 7, E); -_FL_DEFPIN(20, 0, B); _FL_DEFPIN(21, 1, B); _FL_DEFPIN(22, 2, B); _FL_DEFPIN(23, 3, B); -_FL_DEFPIN(24, 4, B); _FL_DEFPIN(25, 5, B); _FL_DEFPIN(26, 6, B); _FL_DEFPIN(27, 7, B); -_FL_DEFPIN(28, 0, A); _FL_DEFPIN(29, 1, A); _FL_DEFPIN(30, 2, A); _FL_DEFPIN(31, 3, A); -_FL_DEFPIN(32, 4, A); _FL_DEFPIN(33, 5, A); _FL_DEFPIN(34, 6, A); _FL_DEFPIN(35, 7, A); -_FL_DEFPIN(36, 4, E); _FL_DEFPIN(37, 5, E); _FL_DEFPIN(38, 0, F); _FL_DEFPIN(39, 1, F); -_FL_DEFPIN(40, 2, F); _FL_DEFPIN(41, 3, F); _FL_DEFPIN(42, 4, F); _FL_DEFPIN(43, 5, F); -_FL_DEFPIN(44, 6, F); _FL_DEFPIN(45, 7, F); - -#define SPI_DATA 22 -#define SPI_CLOCK 21 -#define SPI_SELECT 20 -#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -// PD3/PD5 -#define SPI_UART1_DATA 3 -#define SPI_UART1_CLOCK 5 - - -#elif defined(__AVR_ATmega32U4__) - -// leonard defs -#define MAX_PIN 30 -_FL_DEFPIN(0, 2, D); _FL_DEFPIN(1, 3, D); _FL_DEFPIN(2, 1, D); _FL_DEFPIN(3, 0, D); -_FL_DEFPIN(4, 4, D); _FL_DEFPIN(5, 6, C); _FL_DEFPIN(6, 7, D); _FL_DEFPIN(7, 6, E); -_FL_DEFPIN(8, 4, B); _FL_DEFPIN(9, 5, B); _FL_DEFPIN(10, 6, B); _FL_DEFPIN(11, 7, B); -_FL_DEFPIN(12, 6, D); _FL_DEFPIN(13, 7, C); _FL_DEFPIN(14, 3, B); _FL_DEFPIN(15, 1, B); -_FL_DEFPIN(16, 2, B); _FL_DEFPIN(17, 0, B); _FL_DEFPIN(18, 7, F); _FL_DEFPIN(19, 6, F); -_FL_DEFPIN(20, 5, F); _FL_DEFPIN(21, 4, F); _FL_DEFPIN(22, 1, F); _FL_DEFPIN(23, 0, F); -_FL_DEFPIN(24, 4, D); _FL_DEFPIN(25, 7, D); _FL_DEFPIN(26, 4, B); _FL_DEFPIN(27, 5, B); -_FL_DEFPIN(28, 6, B); _FL_DEFPIN(29, 6, D); _FL_DEFPIN(30, 5, D); - -#define SPI_DATA 16 -#define SPI_CLOCK 15 -#define AVR_HARDWARE_SPI 1 -#define HAS_HARDWARE_PIN_SUPPORT 1 - -// PD3/PD5 -#define SPI_UART1_DATA 1 -#define SPI_UART1_CLOCK 30 - - -#endif - -#endif // FASTLED_FORCE_SOFTWARE_PINS - -FASTLED_NAMESPACE_END - -#endif // __INC_FASTPIN_AVR_H diff --git a/FastLED/src/platforms/avr/fastspi_avr.h b/FastLED/src/platforms/avr/fastspi_avr.h deleted file mode 100644 index 245e40654ba2e76af5c1df9d45b090d40cf069c6..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/avr/fastspi_avr.h +++ /dev/null @@ -1,683 +0,0 @@ -#ifndef __INC_FASTSPI_AVR_H -#define __INC_FASTSPI_AVR_H - -FASTLED_NAMESPACE_BEGIN - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Hardware SPI support using USART registers and friends -// -// TODO: Complete/test implementation - right now this doesn't work -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// uno/mini/duemilanove -#if defined(AVR_HARDWARE_SPI) - -#if defined(UBRR1) - -#ifndef UCPHA1 -#define UCPHA1 1 -#endif - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class AVRUSART1SPIOutput { - Selectable *m_pSelect; - -public: - AVRUSART1SPIOutput() { m_pSelect = NULL; } - AVRUSART1SPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - void init() { - UBRR1 = 0; - - /* Set MSPI mode of operation and SPI data mode 0. */ - UCSR1C = (1<<UMSEL11)|(1<<UMSEL10)|(0<<UCPHA1)|(0<<UCPOL1); - /* Enable receiver and transmitter. */ - UCSR1B = (1<<RXEN1)|(1<<TXEN1); - - FastPin<_CLOCK_PIN>::setOutput(); - FastPin<_DATA_PIN>::setOutput(); - - // must be done last, see page 206 - setSPIRate(); - } - - void setSPIRate() { - if(_SPI_CLOCK_DIVIDER > 2) { - UBRR1 = (_SPI_CLOCK_DIVIDER/2)-1; - } else { - UBRR1 = 0; - } - } - - - static void stop() { - // TODO: stop the uart spi output - } - - static bool shouldWait(bool wait = false) __attribute__((always_inline)) { - static bool sWait=false; - if(sWait) { - sWait = wait; return true; - } else { - sWait = wait; return false; - } - // return true; - } - static void wait() __attribute__((always_inline)) { - if(shouldWait()) { - while(!(UCSR1A & (1<<UDRE1))); - } - } - static void waitFully() __attribute__((always_inline)) { wait(); } - - static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); UDR1=b; shouldWait(true); } - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { UDR1=b; shouldWait(true); wait(); } - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { UDR1=b; shouldWait(true); } - - - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - if(b && (1 << BIT)) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - - FastPin<_CLOCK_PIN>::hi(); - FastPin<_CLOCK_PIN>::lo(); - } - - void enable_pins() { } - void disable_pins() { } - - void select() { - if(m_pSelect != NULL) { - m_pSelect->select(); - } - enable_pins(); - setSPIRate(); - } - - void release() { - if(m_pSelect != NULL) { - m_pSelect->release(); - } - disable_pins(); - } - - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { - writeByte(value); - } - } - - void writeBytesValue(uint8_t value, int len) { - //setSPIRate(); - select(); - while(len--) { - writeByte(value); - } - release(); - } - - // Write a block of n uint8_ts out - template <class D> void writeBytes(register uint8_t *data, int len) { - //setSPIRate(); - uint8_t *end = data + len; - select(); - while(data != end) { - // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM) - writeByte(D::adjust(*data++)); delaycycles<3>(); - } - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - //setSPIRate(); - int len = pixels.mLen; - - select(); - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - writeBytePostWait(D::adjust(pixels.loadAndScale0())); - writeBytePostWait(D::adjust(pixels.loadAndScale1())); - writeBytePostWait(D::adjust(pixels.loadAndScale2())); - } else { - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - } - - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - release(); - } -}; -#endif - -#if defined(UBRR0) -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class AVRUSART0SPIOutput { - Selectable *m_pSelect; - -public: - AVRUSART0SPIOutput() { m_pSelect = NULL; } - AVRUSART0SPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - void init() { - UBRR0 = 0; - - /* Set MSPI mode of operation and SPI data mode 0. */ - UCSR0C = (1<<UMSEL01)|(1<<UMSEL00)/*|(0<<UCPHA0)*/|(0<<UCPOL0); - /* Enable receiver and transmitter. */ - UCSR0B = (1<<RXEN0)|(1<<TXEN0); - - FastPin<_CLOCK_PIN>::setOutput(); - FastPin<_DATA_PIN>::setOutput(); - - // must be done last, see page 206 - setSPIRate(); - } - - void setSPIRate() { - if(_SPI_CLOCK_DIVIDER > 2) { - UBRR0 = (_SPI_CLOCK_DIVIDER/2)-1; - } else { - UBRR0 = 0; - } - } - - static void stop() { - // TODO: stop the uart spi output - } - - static bool shouldWait(bool wait = false) __attribute__((always_inline)) { - static bool sWait=false; - if(sWait) { - sWait = wait; return true; - } else { - sWait = wait; return false; - } - // return true; - } - static void wait() __attribute__((always_inline)) { - if(shouldWait()) { - while(!(UCSR0A & (1<<UDRE0))); - } - } - static void waitFully() __attribute__((always_inline)) { wait(); } - - static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); UDR0=b; shouldWait(true); } - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { UDR0=b; shouldWait(true); wait(); } - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { UDR0=b; shouldWait(true); } - - - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - if(b && (1 << BIT)) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - - FastPin<_CLOCK_PIN>::hi(); - FastPin<_CLOCK_PIN>::lo(); - } - - void enable_pins() { } - void disable_pins() { } - - void select() { - if(m_pSelect != NULL) { - m_pSelect->select(); - } - enable_pins(); - setSPIRate(); - } - - void release() { - if(m_pSelect != NULL) { - m_pSelect->release(); - } - disable_pins(); - } - - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { - writeByte(value); - } - } - - void writeBytesValue(uint8_t value, int len) { - //setSPIRate(); - select(); - while(len--) { - writeByte(value); - } - release(); - } - - // Write a block of n uint8_ts out - template <class D> void writeBytes(register uint8_t *data, int len) { - //setSPIRate(); - uint8_t *end = data + len; - select(); - while(data != end) { - // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM) - writeByte(D::adjust(*data++)); delaycycles<3>(); - } - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - //setSPIRate(); - int len = pixels.mLen; - - select(); - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - writeBytePostWait(D::adjust(pixels.loadAndScale0())); - writeBytePostWait(D::adjust(pixels.loadAndScale1())); - writeBytePostWait(D::adjust(pixels.loadAndScale2())); - } else { - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - } - - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - waitFully(); - release(); - } -}; - -#endif - - -#if defined(SPSR) - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Hardware SPI support using SPDR registers and friends -// -// Technically speaking, this uses the AVR SPI registers. This will work on the Teensy 3.0 because Paul made a set of compatability -// classes that map the AVR SPI registers to ARM's, however this caps the performance of output. -// -// TODO: implement ARMHardwareSPIOutput -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class AVRHardwareSPIOutput { - Selectable *m_pSelect; - bool mWait; - -public: - AVRHardwareSPIOutput() { m_pSelect = NULL; mWait = false;} - AVRHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - void setSPIRate() { - SPCR &= ~ ( (1<<SPR1) | (1<<SPR0) ); // clear out the prescalar bits - - bool b2x = false; - - if(_SPI_CLOCK_DIVIDER >= 128) { SPCR |= (1<<SPR1); SPCR |= (1<<SPR0); } - else if(_SPI_CLOCK_DIVIDER >= 64) { SPCR |= (1<<SPR1);} - else if(_SPI_CLOCK_DIVIDER >= 32) { SPCR |= (1<<SPR1); b2x = true; } - else if(_SPI_CLOCK_DIVIDER >= 16) { SPCR |= (1<<SPR0); } - else if(_SPI_CLOCK_DIVIDER >= 8) { SPCR |= (1<<SPR0); b2x = true; } - else if(_SPI_CLOCK_DIVIDER >= 4) { /* do nothing - default rate */ } - else { b2x = true; } - - if(b2x) { SPSR |= (1<<SPI2X); } - else { SPSR &= ~ (1<<SPI2X); } - } - - void init() { - volatile uint8_t clr; - - // set the pins to output - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); -#ifdef SPI_SELECT - // Make sure the slave select line is set to output, or arduino will block us - FastPin<SPI_SELECT>::setOutput(); - FastPin<SPI_SELECT>::lo(); -#endif - - SPCR |= ((1<<SPE) | (1<<MSTR) ); // enable SPI as master - SPCR &= ~ ( (1<<SPR1) | (1<<SPR0) ); // clear out the prescalar bits - - clr = SPSR; // clear SPI status register - clr = SPDR; // clear SPI data register - clr; - - bool b2x = false; - - if(_SPI_CLOCK_DIVIDER >= 128) { SPCR |= (1<<SPR1); SPCR |= (1<<SPR0); } - else if(_SPI_CLOCK_DIVIDER >= 64) { SPCR |= (1<<SPR1);} - else if(_SPI_CLOCK_DIVIDER >= 32) { SPCR |= (1<<SPR1); b2x = true; } - else if(_SPI_CLOCK_DIVIDER >= 16) { SPCR |= (1<<SPR0); } - else if(_SPI_CLOCK_DIVIDER >= 8) { SPCR |= (1<<SPR0); b2x = true; } - else if(_SPI_CLOCK_DIVIDER >= 4) { /* do nothing - default rate */ } - else { b2x = true; } - - if(b2x) { SPSR |= (1<<SPI2X); } - else { SPSR &= ~ (1<<SPI2X); } - - SPDR=0; - shouldWait(false); - release(); - } - - static bool shouldWait(bool wait = false) __attribute__((always_inline)) { - static bool sWait=false; - if(sWait) { sWait = wait; return true; } else { sWait = wait; return false; } - // return true; - } - static void wait() __attribute__((always_inline)) { if(shouldWait()) { while(!(SPSR & (1<<SPIF))); } } - static void waitFully() __attribute__((always_inline)) { wait(); } - - static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPDR=b; shouldWait(true); } - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPDR=b; shouldWait(true); wait(); } - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPDR=b; shouldWait(true); } - - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - SPCR &= ~(1 << SPE); - if(b & (1 << BIT)) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - - FastPin<_CLOCK_PIN>::hi(); - FastPin<_CLOCK_PIN>::lo(); - SPCR |= 1 << SPE; - shouldWait(false); - } - - void enable_pins() { - SPCR |= ((1<<SPE) | (1<<MSTR) ); // enable SPI as master - } - - void disable_pins() { - SPCR &= ~(((1<<SPE) | (1<<MSTR) )); // disable SPI - } - - void select() { - if(m_pSelect != NULL) { m_pSelect->select(); } - enable_pins(); - setSPIRate(); - } - - void release() { - if(m_pSelect != NULL) { m_pSelect->release(); } - disable_pins(); - } - - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { writeByte(value); } - } - - void writeBytesValue(uint8_t value, int len) { - //setSPIRate(); - select(); - while(len--) { - writeByte(value); - } - release(); - } - - // Write a block of n uint8_ts out - template <class D> void writeBytes(register uint8_t *data, int len) { - //setSPIRate(); - uint8_t *end = data + len; - select(); - while(data != end) { - // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM) - writeByte(D::adjust(*data++)); delaycycles<3>(); - } - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - //setSPIRate(); - int len = pixels.mLen; - - select(); - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - writeBytePostWait(D::adjust(pixels.loadAndScale0())); - writeBytePostWait(D::adjust(pixels.loadAndScale1())); - writeBytePostWait(D::adjust(pixels.loadAndScale2())); - } else { - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - } - - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - waitFully(); - release(); - } -}; -#elif defined(SPSR0) - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Hardware SPI support using SPDR0 registers and friends -// -// Technically speaking, this uses the AVR SPI registers. This will work on the Teensy 3.0 because Paul made a set of compatability -// classes that map the AVR SPI registers to ARM's, however this caps the performance of output. -// -// TODO: implement ARMHardwareSPIOutput -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER> -class AVRHardwareSPIOutput { - Selectable *m_pSelect; - bool mWait; - -public: - AVRHardwareSPIOutput() { m_pSelect = NULL; mWait = false;} - AVRHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - void setSPIRate() { - SPCR0 &= ~ ( (1<<SPR10) | (1<<SPR0) ); // clear out the prescalar bits - - bool b2x = false; - - if(_SPI_CLOCK_DIVIDER >= 128) { SPCR0 |= (1<<SPR1); SPCR0 |= (1<<SPR0); } - else if(_SPI_CLOCK_DIVIDER >= 64) { SPCR0 |= (1<<SPR1);} - else if(_SPI_CLOCK_DIVIDER >= 32) { SPCR0 |= (1<<SPR1); b2x = true; } - else if(_SPI_CLOCK_DIVIDER >= 16) { SPCR0 |= (1<<SPR0); } - else if(_SPI_CLOCK_DIVIDER >= 8) { SPCR0 |= (1<<SPR0); b2x = true; } - else if(_SPI_CLOCK_DIVIDER >= 4) { /* do nothing - default rate */ } - else { b2x = true; } - - if(b2x) { SPSR0 |= (1<<SPI2X); } - else { SPSR0 &= ~ (1<<SPI2X); } - } - - void init() { - volatile uint8_t clr; - - // set the pins to output - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); -#ifdef SPI_SELECT - // Make sure the slave select line is set to output, or arduino will block us - FastPin<SPI_SELECT>::setOutput(); - FastPin<SPI_SELECT>::lo(); -#endif - - SPCR0 |= ((1<<SPE) | (1<<MSTR) ); // enable SPI as master - SPCR0 &= ~ ( (1<<SPR1) | (1<<SPR0) ); // clear out the prescalar bits - - clr = SPSR0; // clear SPI status register - clr = SPDR0; // clear SPI data register - clr; - - bool b2x = false; - - if(_SPI_CLOCK_DIVIDER >= 128) { SPCR0 |= (1<<SPR1); SPCR0 |= (1<<SPR0); } - else if(_SPI_CLOCK_DIVIDER >= 64) { SPCR0 |= (1<<SPR1);} - else if(_SPI_CLOCK_DIVIDER >= 32) { SPCR0 |= (1<<SPR1); b2x = true; } - else if(_SPI_CLOCK_DIVIDER >= 16) { SPCR0 |= (1<<SPR0); } - else if(_SPI_CLOCK_DIVIDER >= 8) { SPCR0 |= (1<<SPR0); b2x = true; } - else if(_SPI_CLOCK_DIVIDER >= 4) { /* do nothing - default rate */ } - else { b2x = true; } - - if(b2x) { SPSR0 |= (1<<SPI2X); } - else { SPSR0 &= ~ (1<<SPI2X); } - - SPDR0=0; - shouldWait(false); - release(); - } - - static bool shouldWait(bool wait = false) __attribute__((always_inline)) { - static bool sWait=false; - if(sWait) { sWait = wait; return true; } else { sWait = wait; return false; } - // return true; - } - static void wait() __attribute__((always_inline)) { if(shouldWait()) { while(!(SPSR0 & (1<<SPIF))); } } - static void waitFully() __attribute__((always_inline)) { wait(); } - - static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPDR0=b; shouldWait(true); } - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPDR0=b; shouldWait(true); wait(); } - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPDR0=b; shouldWait(true); } - - template <uint8_t BIT> inline static void writeBit(uint8_t b) { - SPCR0 &= ~(1 << SPE); - if(b & (1 << BIT)) { - FastPin<_DATA_PIN>::hi(); - } else { - FastPin<_DATA_PIN>::lo(); - } - - FastPin<_CLOCK_PIN>::hi(); - FastPin<_CLOCK_PIN>::lo(); - SPCR0 |= 1 << SPE; - shouldWait(false); - } - - void enable_pins() { - SPCR0 |= ((1<<SPE) | (1<<MSTR) ); // enable SPI as master - } - - void disable_pins() { - SPCR0 &= ~(((1<<SPE) | (1<<MSTR) )); // disable SPI - } - - void select() { - if(m_pSelect != NULL) { m_pSelect->select(); } - enable_pins(); - setSPIRate(); - } - - void release() { - if(m_pSelect != NULL) { m_pSelect->release(); } - disable_pins(); - } - - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { writeByte(value); } - } - - void writeBytesValue(uint8_t value, int len) { - //setSPIRate(); - select(); - while(len--) { - writeByte(value); - } - release(); - } - - // Write a block of n uint8_ts out - template <class D> void writeBytes(register uint8_t *data, int len) { - //setSPIRate(); - uint8_t *end = data + len; - select(); - while(data != end) { - // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM) - writeByte(D::adjust(*data++)); delaycycles<3>(); - } - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); } - - // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template - // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping - template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) { - //setSPIRate(); - int len = pixels.mLen; - - select(); - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - writeBytePostWait(D::adjust(pixels.loadAndScale0())); - writeBytePostWait(D::adjust(pixels.loadAndScale1())); - writeBytePostWait(D::adjust(pixels.loadAndScale2())); - } else { - writeByte(D::adjust(pixels.loadAndScale0())); - writeByte(D::adjust(pixels.loadAndScale1())); - writeByte(D::adjust(pixels.loadAndScale2())); - } - - pixels.advanceData(); - pixels.stepDithering(); - } - D::postBlock(len); - waitFully(); - release(); - } -}; -#endif - -#else -// #define FASTLED_FORCE_SOFTWARE_SPI -#endif - -FASTLED_NAMESPACE_END; - - -#endif diff --git a/FastLED/src/platforms/avr/led_sysdefs_avr.h b/FastLED/src/platforms/avr/led_sysdefs_avr.h deleted file mode 100644 index 05d6e5ed56e43dc473bd45c9d10677453116c934..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/avr/led_sysdefs_avr.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef __INC_LED_SYSDEFS_AVR_H -#define __INC_LED_SYSDEFS_AVR_H - -#define FASTLED_AVR - -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 2 -#endif - -#define FASTLED_SPI_BYTE_ONLY - -#include <avr/io.h> -#include <avr/interrupt.h> // for cli/se definitions - -// Define the register types -typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ -typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ - - -// Default to disallowing interrupts (may want to gate this on teensy2 vs. other arm platforms, since the -// teensy2 has a good, fast millis interrupt implementation) -#ifndef FASTLED_ALLOW_INTERRUPTS -#define FASTLED_ALLOW_INTERRUPTS 0 -#endif - -#if FASTLED_ALLOW_INTERRUPTS == 1 -#define FASTLED_ACCURATE_CLOCK -#endif - - -// Default to using PROGMEM here -#ifndef FASTLED_USE_PROGMEM -#define FASTLED_USE_PROGMEM 1 -#endif - -#if defined(ARDUINO_AVR_DIGISPARK) || defined(ARDUINO_AVR_DIGISPARKPRO) -#ifndef NO_CORRECTION -#define NO_CORRECTION 1 -#endif -#endif - -extern "C" { -# if defined(CORE_TEENSY) || defined(TEENSYDUINO) -extern volatile unsigned long timer0_millis_count; -# define MS_COUNTER timer0_millis_count -# elif defined(ATTINY_CORE) -extern volatile unsigned long millis_timer_millis; -# define MS_COUNTER millis_timer_millis -# elif defined(__AVR_ATmega4809__) -extern volatile unsigned long timer_millis; -# define MS_COUNTER timer_millis -# else -extern volatile unsigned long timer0_millis; -# define MS_COUNTER timer0_millis -# endif -}; - -// special defs for the tiny environments -#if defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtinyX41__) || defined(__AVR_ATtiny841__) || defined(__AVR_ATtiny441__) -#define LIB8_ATTINY 1 -#define FASTLED_NEEDS_YIELD -#endif - -#if defined(ARDUINO) && (ARDUINO > 150) && !defined(IS_BEAN) && !defined (ARDUINO_AVR_DIGISPARK) && !defined (LIB8_TINY) && !defined (ARDUINO_AVR_LARDU_328E) -// don't need YIELD defined by the library -#else -#define FASTLED_NEEDS_YIELD -extern "C" void yield(); -#endif -#endif diff --git a/FastLED/src/platforms/esp/32/clockless_block_esp32.h b/FastLED/src/platforms/esp/32/clockless_block_esp32.h deleted file mode 100644 index 45b7671cf8d4f1ce74245e0aa6df199df3e34a72..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/32/clockless_block_esp32.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef __INC_CLOCKLESS_BLOCK_ESP8266_H -#define __INC_CLOCKLESS_BLOCK_ESP8266_H - -#define FASTLED_HAS_BLOCKLESS 1 - -#define PORT_MASK (((1<<LANES)-1) & 0x0000FFFFL) -#define MIN(X,Y) (((X)<(Y)) ? (X):(Y)) -#define USED_LANES (MIN(LANES,4)) -#define REAL_FIRST_PIN 12 -#define LAST_PIN (12 + USED_LANES - 1) - -FASTLED_NAMESPACE_BEGIN - -#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES -extern uint32_t _frame_cnt; -extern uint32_t _retry_cnt; -#endif - -template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 5> -class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PORT_MASK> { - typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<FIRST_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; - -public: - virtual int size() { return CLEDController::size() * LANES; } - - virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) { - // mWait.wait(); - /*uint32_t clocks = */ - int cnt=FASTLED_INTERRUPT_RETRY_COUNT; - while(!showRGBInternal(pixels) && cnt--) { - ets_intr_unlock(); -#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES - ++_retry_cnt; -#endif - delayMicroseconds(WAIT_TIME * 10); - ets_intr_lock(); - } - // #if FASTLED_ALLOW_INTTERUPTS == 0 - // Adjust the timer - // long microsTaken = CLKS_TO_MICROS(clocks); - // MS_COUNTER += (1 + (microsTaken / 1000)); - // #endif - - // mWait.mark(); - } - - template<int PIN> static void initPin() { - if(PIN >= REAL_FIRST_PIN && PIN <= LAST_PIN) { - _ESPPIN<PIN, 1<<(PIN & 0xFF)>::setOutput(); - // FastPin<PIN>::setOutput(); - } - } - - virtual void init() { - // Only supportd on pins 12-15 - // SZG: This probably won't work (check pins definitions in fastpin_esp32) - initPin<12>(); - initPin<13>(); - initPin<14>(); - initPin<15>(); - mPinMask = FastPin<FIRST_PIN>::mask(); - mPort = FastPin<FIRST_PIN>::port(); - - // Serial.print("Mask is "); Serial.println(PORT_MASK); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - typedef union { - uint8_t bytes[8]; - uint16_t shorts[4]; - uint32_t raw[2]; - } Lines; - -#define ESP_ADJUST 0 // (2*(F_CPU/24000000)) -#define ESP_ADJUST2 0 - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register Lines & b, PixelController<RGB_ORDER, LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) { - Lines b2 = b; - transpose8x1_noinline(b.bytes,b2.bytes); - - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - for(register uint32_t i = 0; i < USED_LANES; ++i) { - while((__clock_cycles() - last_mark) < (T1+T2+T3)); - last_mark = __clock_cycles(); - *FastPin<FIRST_PIN>::sport() = PORT_MASK << REAL_FIRST_PIN; - - uint32_t nword = ((uint32_t)(~b2.bytes[7-i]) & PORT_MASK) << REAL_FIRST_PIN; - while((__clock_cycles() - last_mark) < (T1-6)); - *FastPin<FIRST_PIN>::cport() = nword; - - while((__clock_cycles() - last_mark) < (T1+T2)); - *FastPin<FIRST_PIN>::cport() = PORT_MASK << REAL_FIRST_PIN; - - b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); - } - - for(register uint32_t i = USED_LANES; i < 8; ++i) { - while((__clock_cycles() - last_mark) < (T1+T2+T3)); - last_mark = __clock_cycles(); - *FastPin<FIRST_PIN>::sport() = PORT_MASK << REAL_FIRST_PIN; - - uint32_t nword = ((uint32_t)(~b2.bytes[7-i]) & PORT_MASK) << REAL_FIRST_PIN; - while((__clock_cycles() - last_mark) < (T1-6)); - *FastPin<FIRST_PIN>::cport() = nword; - - while((__clock_cycles() - last_mark) < (T1+T2)); - *FastPin<FIRST_PIN>::cport() = PORT_MASK << REAL_FIRST_PIN; - } - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) { - - // Setup the pixel controller and load/scale the first byte - Lines b0; - - for(int i = 0; i < USED_LANES; ++i) { - b0.bytes[i] = allpixels.loadAndScale0(i); - } - allpixels.preStepFirstByteDithering(); - - ets_intr_lock(); - uint32_t _start = __clock_cycles(); - uint32_t last_mark = _start; - - while(allpixels.has(1)) { - // Write first byte, read next byte - writeBits<8+XTRA0,1>(last_mark, b0, allpixels); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(last_mark, b0, allpixels); - allpixels.advanceData(); - - // Write third byte - writeBits<8+XTRA0,0>(last_mark, b0, allpixels); - -#if (FASTLED_ALLOW_INTERRUPTS == 1) - ets_intr_unlock(); -#endif - - allpixels.stepDithering(); - -#if (FASTLED_ALLOW_INTERRUPTS == 1) - ets_intr_lock(); - // if interrupts took longer than 45µs, punt on the current frame - if((int32_t)(__clock_cycles()-last_mark) > 0) { - if((int32_t)(__clock_cycles()-last_mark) > (T1+T2+T3+((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US))) { ets_intr_unlock(); return 0; } - } -#endif - }; - - ets_intr_unlock(); -#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES - ++_frame_cnt; -#endif - return __clock_cycles() - _start; - } -}; - -FASTLED_NAMESPACE_END -#endif diff --git a/FastLED/src/platforms/esp/32/clockless_i2s_esp32.h b/FastLED/src/platforms/esp/32/clockless_i2s_esp32.h deleted file mode 100644 index d7af459d8262172b12c91fb1053ab5de6cfe3d78..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/32/clockless_i2s_esp32.h +++ /dev/null @@ -1,773 +0,0 @@ -/* - * I2S Driver - * - * Copyright (c) 2019 Yves Bazin - * Copyright (c) 2019 Samuel Z. Guyer - * Derived from lots of code examples from other people. - * - * The I2S implementation can drive up to 24 strips in parallel, but - * with the following limitation: all the strips must have the same - * timing (i.e., they must all use the same chip). - * - * To enable the I2S driver, add the following line *before* including - * FastLED.h (no other changes are necessary): - * - * #define FASTLED_ESP32_I2S true - * - * The overall strategy is to use the parallel mode of the I2S "audio" - * peripheral to send up to 24 bits in parallel to 24 different pins. - * Unlike the RMT peripheral the I2S system cannot send bits of - * different lengths. Instead, we set the I2S data clock fairly high - * and then encode a signal as a series of bits. - * - * For example, with a clock divider of 10 the data clock will be - * 8MHz, so each bit is 125ns. The WS2812 expects a "1" bit to be - * encoded as a HIGH signal for around 875ns, followed by LOW for - * 375ns. Sending the following pattern results in the right shape - * signal: - * - * 1111111000 WS2812 "1" bit encoded as 10 125ns pulses - * - * The I2S peripheral expects the bits for all 24 outputs to be packed - * into a single 32-bit word. The complete signal is a series of these - * 32-bit values -- one for each bit for each strip. The pixel data, - * however, is stored "serially" as a series of RGB values separately - * for each strip. To prepare the data we need to do three things: (1) - * take 1 pixel from each strip, and (2) tranpose the bits so that - * they are in the parallel form, (3) translate each data bit into the - * bit pattern that encodes the signal for that bit. This code is in - * the fillBuffer() method: - * - * 1. Read 1 pixel from each strip into an array; store this data by - * color channel (e.g., all the red bytes, then all the green - * bytes, then all the blue bytes). For three color channels, the - * array is 3 X 24 X 8 bits. - * - * 2. Tranpose the array so that it is 3 X 8 X 24 bits. The hardware - * wants the data in 32-bit chunks, so the actual form is 3 X 8 X - * 32, with the low 8 bits unused. - * - * 3. Take each group of 24 parallel bits and "expand" them into a - * pattern according to the encoding. For example, with a 8MHz - * data clock, each data bit turns into 10 I2s pulses, so 24 - * parallel data bits turn into 10 X 24 pulses. - * - * We send data to the I2S peripheral using the DMA interface. We use - * two DMA buffers, so that we can fill one buffer while the other - * buffer is being sent. Each DMA buffer holds the fully-expanded - * pulse pattern for one pixel on up to 24 strips. The exact amount of - * memory required depends on the number of color channels and the - * number of pulses used to encode each bit. - * - * We get an interrupt each time a buffer is sent; we then fill that - * buffer while the next one is being sent. The DMA interface allows - * us to configure the buffers as a circularly linked list, so that it - * can automatically start on the next buffer. - */ -/* - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -#pragma message "NOTE: ESP32 support using I2S parallel driver. All strips must use the same chipset" - -FASTLED_NAMESPACE_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif - -#include "esp_heap_caps.h" -#include "soc/soc.h" -#include "soc/gpio_sig_map.h" -#include "soc/i2s_reg.h" -#include "soc/i2s_struct.h" -#include "soc/io_mux_reg.h" -#include "driver/gpio.h" -#include "driver/periph_ctrl.h" -#include "rom/lldesc.h" -#include "esp_intr.h" -#include "esp_log.h" - -#ifdef __cplusplus -} -#endif - -__attribute__ ((always_inline)) inline static uint32_t __clock_cycles() { - uint32_t cyc; - __asm__ __volatile__ ("rsr %0,ccount":"=a" (cyc)); - return cyc; -} - -#define FASTLED_HAS_CLOCKLESS 1 -#define NUM_COLOR_CHANNELS 3 - -// -- Choose which I2S device to use -#ifndef I2S_DEVICE -#define I2S_DEVICE 0 -#endif - -// -- Max number of controllers we can support -#ifndef FASTLED_I2S_MAX_CONTROLLERS -#define FASTLED_I2S_MAX_CONTROLLERS 24 -#endif - -// -- I2S clock -#define I2S_BASE_CLK (80000000L) -#define I2S_MAX_CLK (20000000L) //more tha a certain speed and the I2s looses some bits -#define I2S_MAX_PULSE_PER_BIT 20 //put it higher to get more accuracy but it could decrease the refresh rate without real improvement -// -- Convert ESP32 cycles back into nanoseconds -#define ESPCLKS_TO_NS(_CLKS) (((long)(_CLKS) * 1000L) / F_CPU_MHZ) - -// -- Array of all controllers -static CLEDController * gControllers[FASTLED_I2S_MAX_CONTROLLERS]; -static int gNumControllers = 0; -static int gNumStarted = 0; - -// -- Global semaphore for the whole show process -// Semaphore is not given until all data has been sent -static xSemaphoreHandle gTX_sem = NULL; - -// -- One-time I2S initialization -static bool gInitialized = false; - -// -- Interrupt handler -static intr_handle_t gI2S_intr_handle = NULL; - -// -- A pointer to the memory-mapped structure: I2S0 or I2S1 -static i2s_dev_t * i2s; - -// -- I2S goes to these pins until we remap them using the GPIO matrix -static int i2s_base_pin_index; - -// --- I2S DMA buffers -struct DMABuffer { - lldesc_t descriptor; - uint8_t * buffer; -}; - -#define NUM_DMA_BUFFERS 2 -static DMABuffer * dmaBuffers[NUM_DMA_BUFFERS]; - -// -- Bit patterns -// For now, we require all strips to be the same chipset, so these -// are global variables. - -static int gPulsesPerBit = 0; -static uint32_t gOneBit[40] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -static uint32_t gZeroBit[40] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -// -- Counters to track progress -static int gCurBuffer = 0; -static bool gDoneFilling = false; -static int ones_for_one; -static int ones_for_zero; - -// -- Temp buffers for pixels and bits being formatted for DMA -static uint8_t gPixelRow[NUM_COLOR_CHANNELS][32]; -static uint8_t gPixelBits[NUM_COLOR_CHANNELS][8][4]; -static int CLOCK_DIVIDER_N; -static int CLOCK_DIVIDER_A; -static int CLOCK_DIVIDER_B; - -template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 5> -class ClocklessController : public CPixelLEDController<RGB_ORDER> -{ - // -- Store the GPIO pin - gpio_num_t mPin; - - // -- This instantiation forces a check on the pin choice - FastPin<DATA_PIN> mFastPin; - - // -- Save the pixel controller - PixelController<RGB_ORDER> * mPixels; - - // -- Make sure we can't call show() too quickly - CMinWait<50> mWait; - -public: - void init() - { - i2sInit(); - - // -- Allocate space to save the pixel controller - // during parallel output - mPixels = (PixelController<RGB_ORDER> *) malloc(sizeof(PixelController<RGB_ORDER>)); - - gControllers[gNumControllers] = this; - int my_index = gNumControllers; - ++gNumControllers; - - // -- Set up the pin We have to do two things: configure the - // actual GPIO pin, and route the output from the default - // pin (determined by the I2S device) to the pin we - // want. We compute the default pin using the index of this - // controller in the array. This order is crucial because - // the bits must go into the DMA buffer in the same order. - mPin = gpio_num_t(DATA_PIN); - - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[DATA_PIN], PIN_FUNC_GPIO); - gpio_set_direction(mPin, (gpio_mode_t)GPIO_MODE_DEF_OUTPUT); - pinMode(mPin,OUTPUT); - gpio_matrix_out(mPin, i2s_base_pin_index + my_index, false, false); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - static int pgcd(int smallest,int precision,int a,int b,int c) - { - int pgc_=1; - for( int i=smallest;i>0;--i) - { - - if( a%i<=precision && b%i<=precision && c%i<=precision) - { - pgc_=i; - break; - } - } - return pgc_; - } - - /** Compute pules/bit patterns - * - * This is Yves Bazin's mad code for computing the pulse pattern - * and clock timing given the target signal given by T1, T2, and - * T3. In general, these parameters are interpreted as follows: - * - * a "1" bit is encoded by setting the pin HIGH to T1+T2 ns, then LOW for T3 ns - * a "0" bit is encoded by setting the pin HIGH to T1 ns, then LOW for T2+T3 ns - * - */ - static void initBitPatterns() - { - // Precompute the bit patterns based on the I2S sample rate - // Serial.println("Setting up fastled using I2S"); - - // -- First, convert back to ns from CPU clocks - uint32_t T1ns = ESPCLKS_TO_NS(T1); - uint32_t T2ns = ESPCLKS_TO_NS(T2); - uint32_t T3ns = ESPCLKS_TO_NS(T3); - - // Serial.print("T1 = "); Serial.print(T1); Serial.print(" ns "); Serial.println(T1ns); - // Serial.print("T2 = "); Serial.print(T2); Serial.print(" ns "); Serial.println(T2ns); - // Serial.print("T3 = "); Serial.print(T3); Serial.print(" ns "); Serial.println(T3ns); - - /* - We calculate the best pcgd to the timing - ie - WS2811 77 77 154 => 1 1 2 => nb pulses= 4 - WS2812 60 150 90 => 2 5 3 => nb pulses=10 - */ - int smallest=0; - if (T1>T2) - smallest=T2; - else - smallest=T1; - if(smallest>T3) - smallest=T3; - double freq=(double)1/(double)(T1ns + T2ns + T3ns); - // Serial.printf("chipset frequency:%f Khz\n", 1000000L*freq); - // Serial.printf("smallest %d\n",smallest); - int pgc_=1; - int precision=0; - pgc_=pgcd(smallest,precision,T1,T2,T3); - //Serial.printf("%f\n",I2S_MAX_CLK/(1000000000L*freq)); - while(pgc_==1 || (T1/pgc_ +T2/pgc_ +T3/pgc_)>I2S_MAX_PULSE_PER_BIT) //while(pgc_==1 || (T1/pgc_ +T2/pgc_ +T3/pgc_)>I2S_MAX_CLK/(1000000000L*freq)) - { - ++precision; - pgc_=pgcd(smallest,precision,T1,T2,T3); - //Serial.printf("%d %d\n",pgc_,(a+b+c)/pgc_); - } - pgc_=pgcd(smallest,precision,T1,T2,T3); - // Serial.printf("pgcd %d precision:%d\n",pgc_,precision); - // Serial.printf("nb pulse per bit:%d\n",T1/pgc_ +T2/pgc_ +T3/pgc_); - gPulsesPerBit=(int)T1/pgc_ +(int)T2/pgc_ +(int)T3/pgc_; - /* - we calculate the duration of one pulse nd htre base frequency of the led - ie WS2812B F=1/(250+625+375)=800kHz or 1250ns - as we need 10 pulses each pulse is 125ns => frequency 800Khz*10=8MHz - WS2811 T=320+320+641=1281ns qnd we need 4 pulses => pulse duration 320.25ns =>frequency 3.1225605Mhz - - */ - - freq=1000000000L*freq*gPulsesPerBit; - // Serial.printf("needed frequency (nbpiulse per bit)*(chispset frequency):%f Mhz\n",freq/1000000); - - /* - we do calculate the needed N a and b - as f=basefred/(N+b/a); - as a is max 63 the precision for the decimal is 1/63 - - */ - - CLOCK_DIVIDER_N=(int)((double)I2S_BASE_CLK/freq); - double v=I2S_BASE_CLK/freq-CLOCK_DIVIDER_N; - - double prec=(double)1/63; - int a=1; - int b=0; - CLOCK_DIVIDER_A=1; - CLOCK_DIVIDER_B=0; - for(a=1;a<64;++a) - { - for(b=0;b<a;++b) - { - //printf("%d %d %f %f %f\n",b,a,v,(double)v*(double)a,fabsf(v-(double)b/a)); - if(fabsf(v-(double)b/a) <= prec/2) - break; - } - if(fabsf(v-(double)b/a) ==0) - { - CLOCK_DIVIDER_A=a; - CLOCK_DIVIDER_B=b; - break; - } - if(fabsf(v-(double)b/a) < prec/2) - { - if (fabsf(v-(double)b/a) <fabsf(v-(double)CLOCK_DIVIDER_B/CLOCK_DIVIDER_A)) - { - CLOCK_DIVIDER_A=a; - CLOCK_DIVIDER_B=b; - } - - } - } - //top take care of an issue with double 0.9999999999 - if(CLOCK_DIVIDER_A==CLOCK_DIVIDER_B) - { - CLOCK_DIVIDER_A=1; - CLOCK_DIVIDER_B=0; - ++CLOCK_DIVIDER_N; - } - - //printf("%d %d %f %f %d\n",CLOCK_DIVIDER_B,CLOCK_DIVIDER_A,(double)CLOCK_DIVIDER_B/CLOCK_DIVIDER_A,v,CLOCK_DIVIDER_N); - //Serial.printf("freq %f %f\n",freq,I2S_BASE_CLK/(CLOCK_DIVIDER_N+(double)CLOCK_DIVIDER_B/CLOCK_DIVIDER_A)); - freq=1/(CLOCK_DIVIDER_N+(double)CLOCK_DIVIDER_B/CLOCK_DIVIDER_A); - freq=freq*I2S_BASE_CLK; - // Serial.printf("calculted for i2s frequency:%f Mhz N:%d B:%d A:%d\n",freq/1000000,CLOCK_DIVIDER_N,CLOCK_DIVIDER_B,CLOCK_DIVIDER_A); - // double pulseduration=1000000000/freq; - // Serial.printf("Pulse duration: %f ns\n",pulseduration); - // gPulsesPerBit = (T1ns + T2ns + T3ns)/FASTLED_I2S_NS_PER_PULSE; - - //Serial.print("Pulses per bit: "); Serial.println(gPulsesPerBit); - - //int ones_for_one = ((T1ns + T2ns - 1)/FASTLED_I2S_NS_PER_PULSE) + 1; - ones_for_one = T1/pgc_ +T2/pgc_; - //Serial.print("One bit: target "); - //Serial.print(T1ns+T2ns); Serial.print("ns --- "); - //Serial.print(ones_for_one); Serial.print(" 1 bits"); - //Serial.print(" = "); Serial.print(ones_for_one * FASTLED_I2S_NS_PER_PULSE); Serial.println("ns"); - // Serial.printf("one bit : target %d ns --- %d pulses 1 bit = %f ns\n",T1ns+T2ns,ones_for_one ,ones_for_one*pulseduration); - - - int i = 0; - while ( i < ones_for_one ) { - gOneBit[i] = 0xFFFFFF00; - ++i; - } - while ( i < gPulsesPerBit ) { - gOneBit[i] = 0x00000000; - ++i; - } - - //int ones_for_zero = ((T1ns - 1)/FASTLED_I2S_NS_PER_PULSE) + 1; - ones_for_zero =T1/pgc_ ; - // Serial.print("Zero bit: target "); - // Serial.print(T1ns); Serial.print("ns --- "); - //Serial.print(ones_for_zero); Serial.print(" 1 bits"); - //Serial.print(" = "); Serial.print(ones_for_zero * FASTLED_I2S_NS_PER_PULSE); Serial.println("ns"); - // Serial.printf("Zero bit : target %d ns --- %d pulses 1 bit = %f ns\n",T1ns,ones_for_zero ,ones_for_zero*pulseduration); - i = 0; - while ( i < ones_for_zero ) { - gZeroBit[i] = 0xFFFFFF00; - ++i; - } - while ( i < gPulsesPerBit ) { - gZeroBit[i] = 0x00000000; - ++i; - } - - memset(gPixelRow, 0, NUM_COLOR_CHANNELS * 32); - memset(gPixelBits, 0, NUM_COLOR_CHANNELS * 32); - } - - static DMABuffer * allocateDMABuffer(int bytes) - { - DMABuffer * b = (DMABuffer *)heap_caps_malloc(sizeof(DMABuffer), MALLOC_CAP_DMA); - - b->buffer = (uint8_t *)heap_caps_malloc(bytes, MALLOC_CAP_DMA); - memset(b->buffer, 0, bytes); - - b->descriptor.length = bytes; - b->descriptor.size = bytes; - b->descriptor.owner = 1; - b->descriptor.sosf = 1; - b->descriptor.buf = b->buffer; - b->descriptor.offset = 0; - b->descriptor.empty = 0; - b->descriptor.eof = 1; - b->descriptor.qe.stqe_next = 0; - - return b; - } - - static void i2sInit() - { - // -- Only need to do this once - if (gInitialized) return; - - // -- Construct the bit patterns for ones and zeros - initBitPatterns(); - - // -- Choose whether to use I2S device 0 or device 1 - // Set up the various device-specific parameters - int interruptSource; - if (I2S_DEVICE == 0) { - i2s = &I2S0; - periph_module_enable(PERIPH_I2S0_MODULE); - interruptSource = ETS_I2S0_INTR_SOURCE; - i2s_base_pin_index = I2S0O_DATA_OUT0_IDX; - } else { - i2s = &I2S1; - periph_module_enable(PERIPH_I2S1_MODULE); - interruptSource = ETS_I2S1_INTR_SOURCE; - i2s_base_pin_index = I2S1O_DATA_OUT0_IDX; - } - - // -- Reset everything - i2sReset(); - i2sReset_DMA(); - i2sReset_FIFO(); - - // -- Main configuration - i2s->conf.tx_msb_right = 1; - i2s->conf.tx_mono = 0; - i2s->conf.tx_short_sync = 0; - i2s->conf.tx_msb_shift = 0; - i2s->conf.tx_right_first = 1; // 0;//1; - i2s->conf.tx_slave_mod = 0; - - // -- Set parallel mode - i2s->conf2.val = 0; - i2s->conf2.lcd_en = 1; - i2s->conf2.lcd_tx_wrx2_en = 0; // 0 for 16 or 32 parallel output - i2s->conf2.lcd_tx_sdx2_en = 0; // HN - - // -- Set up the clock rate and sampling - i2s->sample_rate_conf.val = 0; - i2s->sample_rate_conf.tx_bits_mod = 32; // Number of parallel bits/pins - i2s->sample_rate_conf.tx_bck_div_num = 1; - i2s->clkm_conf.val = 0; - i2s->clkm_conf.clka_en = 0; - - // -- Data clock is computed as Base/(div_num + (div_b/div_a)) - // Base is 80Mhz, so 80/(10 + 0/1) = 8Mhz - // One cycle is 125ns - i2s->clkm_conf.clkm_div_a = CLOCK_DIVIDER_A; - i2s->clkm_conf.clkm_div_b = CLOCK_DIVIDER_B; - i2s->clkm_conf.clkm_div_num = CLOCK_DIVIDER_N; - - i2s->fifo_conf.val = 0; - i2s->fifo_conf.tx_fifo_mod_force_en = 1; - i2s->fifo_conf.tx_fifo_mod = 3; // 32-bit single channel data - i2s->fifo_conf.tx_data_num = 32; // fifo length - i2s->fifo_conf.dscr_en = 1; // fifo will use dma - - i2s->conf1.val = 0; - i2s->conf1.tx_stop_en = 0; - i2s->conf1.tx_pcm_bypass = 1; - - i2s->conf_chan.val = 0; - i2s->conf_chan.tx_chan_mod = 1; // Mono mode, with tx_msb_right = 1, everything goes to right-channel - - i2s->timing.val = 0; - - // -- Allocate two DMA buffers - dmaBuffers[0] = allocateDMABuffer(32 * NUM_COLOR_CHANNELS * gPulsesPerBit); - dmaBuffers[1] = allocateDMABuffer(32 * NUM_COLOR_CHANNELS * gPulsesPerBit); - - // -- Arrange them as a circularly linked list - dmaBuffers[0]->descriptor.qe.stqe_next = &(dmaBuffers[1]->descriptor); - dmaBuffers[1]->descriptor.qe.stqe_next = &(dmaBuffers[0]->descriptor); - - // -- Allocate i2s interrupt - SET_PERI_REG_BITS(I2S_INT_ENA_REG(I2S_DEVICE), I2S_OUT_EOF_INT_ENA_V, 1, I2S_OUT_EOF_INT_ENA_S); - esp_intr_alloc(interruptSource, 0, // ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL3, - &interruptHandler, 0, &gI2S_intr_handle); - - // -- Create a semaphore to block execution until all the controllers are done - if (gTX_sem == NULL) { - gTX_sem = xSemaphoreCreateBinary(); - xSemaphoreGive(gTX_sem); - } - - // Serial.println("Init I2S"); - gInitialized = true; - } - - /** Clear DMA buffer - * - * Yves' clever trick: initialize the bits that we know must be 0 - * or 1 regardless of what bit they encode. - */ - static void empty( uint32_t *buf) - { - for(int i=0;i<8*NUM_COLOR_CHANNELS;++i) - { - int offset=gPulsesPerBit*i; - for(int j=0;j<ones_for_zero;++j) - buf[offset+j]=0xffffffff; - - for(int j=ones_for_one;j<gPulsesPerBit;++j) - buf[offset+j]=0; - } - } - - // -- Show pixels - // This is the main entry point for the controller. - virtual void showPixels(PixelController<RGB_ORDER> & pixels) - { - if (gNumStarted == 0) { - // -- First controller: make sure everything is set up - xSemaphoreTake(gTX_sem, portMAX_DELAY); - } - - // -- Initialize the local state, save a pointer to the pixel - // data. We need to make a copy because pixels is a local - // variable in the calling function, and this data structure - // needs to outlive this call to showPixels. - (*mPixels) = pixels; - - // -- Keep track of the number of strips we've seen - ++gNumStarted; - - // Serial.print("Show pixels "); - // Serial.println(gNumStarted); - - // -- The last call to showPixels is the one responsible for doing - // all of the actual work - if (gNumStarted == gNumControllers) { - empty((uint32_t*)dmaBuffers[0]->buffer); - empty((uint32_t*)dmaBuffers[1]->buffer); - gCurBuffer = 0; - gDoneFilling = false; - - // -- Prefill both buffers - fillBuffer(); - fillBuffer(); - - // -- Make sure it's been at least 50ms since last show - mWait.wait(); - - i2sStart(); - - // -- Wait here while the rest of the data is sent. The interrupt handler - // will keep refilling the DMA buffers until it is all sent; then it - // gives the semaphore back. - xSemaphoreTake(gTX_sem, portMAX_DELAY); - xSemaphoreGive(gTX_sem); - - i2sStop(); - - mWait.mark(); - - // -- Reset the counters - gNumStarted = 0; - } - } - - // -- Custom interrupt handler - static IRAM_ATTR void interruptHandler(void *arg) - { - if (i2s->int_st.out_eof) { - i2s->int_clr.val = i2s->int_raw.val; - - if ( ! gDoneFilling) { - fillBuffer(); - } else { - portBASE_TYPE HPTaskAwoken = 0; - xSemaphoreGiveFromISR(gTX_sem, &HPTaskAwoken); - if(HPTaskAwoken == pdTRUE) portYIELD_FROM_ISR(); - } - } - } - - /** Fill DMA buffer - * - * This is where the real work happens: take a row of pixels (one - * from each strip), transpose and encode the bits, and store - * them in the DMA buffer for the I2S peripheral to read. - */ - static void fillBuffer() - { - // -- Alternate between buffers - volatile uint32_t * buf = (uint32_t *) dmaBuffers[gCurBuffer]->buffer; - gCurBuffer = (gCurBuffer + 1) % NUM_DMA_BUFFERS; - - // -- Get the requested pixel from each controller. Store the - // data for each color channel in a separate array. - uint32_t has_data_mask = 0; - for (int i = 0; i < gNumControllers; ++i) { - // -- Store the pixels in reverse controller order starting at index 23 - // This causes the bits to come out in the right position after we - // transpose them. - int bit_index = 23-i; - ClocklessController * pController = static_cast<ClocklessController*>(gControllers[i]); - if (pController->mPixels->has(1)) { - gPixelRow[0][bit_index] = pController->mPixels->loadAndScale0(); - gPixelRow[1][bit_index] = pController->mPixels->loadAndScale1(); - gPixelRow[2][bit_index] = pController->mPixels->loadAndScale2(); - pController->mPixels->advanceData(); - pController->mPixels->stepDithering(); - - // -- Record that this controller still has data to send - has_data_mask |= (1 << (i+8)); - } - } - - // -- None of the strips has data? We are done. - if (has_data_mask == 0) { - gDoneFilling = true; - return; - } - - // -- Transpose and encode the pixel data for the DMA buffer - // int buf_index = 0; - for (int channel = 0; channel < NUM_COLOR_CHANNELS; ++channel) { - - // -- Tranpose each array: all the bit 7's, then all the bit 6's, ... - transpose32(gPixelRow[channel], gPixelBits[channel][0] ); - - //Serial.print("Channel: "); Serial.print(channel); Serial.print(" "); - for (int bitnum = 0; bitnum < 8; ++bitnum) { - uint8_t * row = (uint8_t *) (gPixelBits[channel][bitnum]); - uint32_t bit = (row[0] << 24) | (row[1] << 16) | (row[2] << 8) | row[3]; - - /* SZG: More general, but too slow: - for (int pulse_num = 0; pulse_num < gPulsesPerBit; ++pulse_num) { - buf[buf_index++] = has_data_mask & ( (bit & gOneBit[pulse_num]) | (~bit & gZeroBit[pulse_num]) ); - } - */ - - // -- Only fill in the pulses that are different between the "0" and "1" encodings - for(int pulse_num = ones_for_zero; pulse_num < ones_for_one; ++pulse_num) { - buf[bitnum*gPulsesPerBit+channel*8*gPulsesPerBit+pulse_num] = has_data_mask & bit; - } - } - } - } - - static void transpose32(uint8_t * pixels, uint8_t * bits) - { - transpose8rS32(& pixels[0], 1, 4, & bits[0]); - transpose8rS32(& pixels[8], 1, 4, & bits[1]); - transpose8rS32(& pixels[16], 1, 4, & bits[2]); - //transpose8rS32(& pixels[24], 1, 4, & bits[3]); Can only use 24 bits - } - - /** Transpose 8x8 bit matrix - * From Hacker's Delight - */ - static void transpose8rS32(uint8_t * A, int m, int n, uint8_t * B) - { - uint32_t x, y, t; - - // Load the array and pack it into x and y. - - x = (A[0]<<24) | (A[m]<<16) | (A[2*m]<<8) | A[3*m]; - y = (A[4*m]<<24) | (A[5*m]<<16) | (A[6*m]<<8) | A[7*m]; - - t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7); - t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7); - - t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14); - t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14); - - t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F); - y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F); - x = t; - - B[0]=x>>24; B[n]=x>>16; B[2*n]=x>>8; B[3*n]=x; - B[4*n]=y>>24; B[5*n]=y>>16; B[6*n]=y>>8; B[7*n]=y; - } - - /** Start I2S transmission - */ - static void i2sStart() - { - // esp_intr_disable(gI2S_intr_handle); - // Serial.println("I2S start"); - i2sReset(); - //Serial.println(dmaBuffers[0]->sampleCount()); - i2s->lc_conf.val=I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN; - i2s->out_link.addr = (uint32_t) & (dmaBuffers[0]->descriptor); - i2s->out_link.start = 1; - ////vTaskDelay(5); - i2s->int_clr.val = i2s->int_raw.val; - // //vTaskDelay(5); - i2s->int_ena.out_dscr_err = 1; - //enable interrupt - ////vTaskDelay(5); - esp_intr_enable(gI2S_intr_handle); - // //vTaskDelay(5); - i2s->int_ena.val = 0; - i2s->int_ena.out_eof = 1; - - //start transmission - i2s->conf.tx_start = 1; - } - - static void i2sReset() - { - // Serial.println("I2S reset"); - const unsigned long lc_conf_reset_flags = I2S_IN_RST_M | I2S_OUT_RST_M | I2S_AHBM_RST_M | I2S_AHBM_FIFO_RST_M; - i2s->lc_conf.val |= lc_conf_reset_flags; - i2s->lc_conf.val &= ~lc_conf_reset_flags; - - const uint32_t conf_reset_flags = I2S_RX_RESET_M | I2S_RX_FIFO_RESET_M | I2S_TX_RESET_M | I2S_TX_FIFO_RESET_M; - i2s->conf.val |= conf_reset_flags; - i2s->conf.val &= ~conf_reset_flags; - } - - static void i2sReset_DMA() - { - i2s->lc_conf.in_rst=1; i2s->lc_conf.in_rst=0; - i2s->lc_conf.out_rst=1; i2s->lc_conf.out_rst=0; - } - - static void i2sReset_FIFO() - { - i2s->conf.rx_fifo_reset=1; i2s->conf.rx_fifo_reset=0; - i2s->conf.tx_fifo_reset=1; i2s->conf.tx_fifo_reset=0; - } - - static void i2sStop() - { - // Serial.println("I2S stop"); - esp_intr_disable(gI2S_intr_handle); - i2sReset(); - i2s->conf.rx_start = 0; - i2s->conf.tx_start = 0; - } -}; - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/platforms/esp/32/clockless_rmt_esp32.cpp b/FastLED/src/platforms/esp/32/clockless_rmt_esp32.cpp deleted file mode 100644 index 20db53513ec09b514e5fc1f6ed0cede3e5af1b19..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/32/clockless_rmt_esp32.cpp +++ /dev/null @@ -1,437 +0,0 @@ - -#ifdef ESP32 - -#define FASTLED_INTERNAL -#include "FastLED.h" - -// -- Forward reference -class ESP32RMTController; - -// -- Array of all controllers -// This array is filled at the time controllers are registered -// (Usually when the sketch calls addLeds) -static ESP32RMTController * gControllers[FASTLED_RMT_MAX_CONTROLLERS]; - -// -- Current set of active controllers, indexed by the RMT -// channel assigned to them. -static ESP32RMTController * gOnChannel[FASTLED_RMT_MAX_CHANNELS]; - -static int gNumControllers = 0; -static int gNumStarted = 0; -static int gNumDone = 0; -static int gNext = 0; - -static intr_handle_t gRMT_intr_handle = NULL; - -// -- Global semaphore for the whole show process -// Semaphore is not given until all data has been sent -static xSemaphoreHandle gTX_sem = NULL; - -// -- Make sure we can't call show() too quickly -CMinWait<50> gWait; - -static bool gInitialized = false; - -ESP32RMTController::ESP32RMTController(int DATA_PIN, int T1, int T2, int T3) - : mPixelData(0), - mSize(0), - mCur(0), - mWhichHalf(0), - mBuffer(0), - mBufferSize(0), - mCurPulse(0) -{ - // -- Precompute rmt items corresponding to a zero bit and a one bit - // according to the timing values given in the template instantiation - // T1H - mOne.level0 = 1; - mOne.duration0 = ESP_TO_RMT_CYCLES(T1+T2); // TO_RMT_CYCLES(T1+T2); - // T1L - mOne.level1 = 0; - mOne.duration1 = ESP_TO_RMT_CYCLES(T3); // TO_RMT_CYCLES(T3); - - // T0H - mZero.level0 = 1; - mZero.duration0 = ESP_TO_RMT_CYCLES(T1); // TO_RMT_CYCLES(T1); - // T0L - mZero.level1 = 0; - mZero.duration1 = ESP_TO_RMT_CYCLES(T2+T3); // TO_RMT_CYCLES(T2 + T3); - - gControllers[gNumControllers] = this; - gNumControllers++; - - // -- Expected number of CPU cycles between buffer fills - mCyclesPerFill = (T1 + T2 + T3) * PULSES_PER_FILL; - - // -- If there is ever an interval greater than 1.5 times - // the expected time, then bail out. - mMaxCyclesPerFill = mCyclesPerFill + mCyclesPerFill/2; - - mPin = gpio_num_t(DATA_PIN); -} - -// -- Get or create the buffer for the pixel data -// We can't allocate it ahead of time because we don't have -// the PixelController object until show is called. -uint32_t * ESP32RMTController::getPixelBuffer(int size_in_bytes) -{ - if (mPixelData == 0) { - mSize = ((size_in_bytes-1) / sizeof(uint32_t)) + 1; - mPixelData = (uint32_t *) calloc( mSize, sizeof(uint32_t)); - } - return mPixelData; -} - -// -- Initialize RMT subsystem -// This only needs to be done once -void ESP32RMTController::init(gpio_num_t pin) -{ - if (gInitialized) return; - - for (int i = 0; i < FASTLED_RMT_MAX_CHANNELS; i++) { - gOnChannel[i] = NULL; - - // -- RMT configuration for transmission - rmt_config_t rmt_tx; - rmt_tx.channel = rmt_channel_t(i); - rmt_tx.rmt_mode = RMT_MODE_TX; - rmt_tx.gpio_num = pin; // The particular pin will be assigned later - rmt_tx.mem_block_num = FASTLED_RMT_MEM_BLOCKS; - rmt_tx.clk_div = DIVIDER; - rmt_tx.tx_config.loop_en = false; - rmt_tx.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW; - rmt_tx.tx_config.carrier_en = false; - rmt_tx.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; - rmt_tx.tx_config.idle_output_en = true; - - // -- Apply the configuration - rmt_config(&rmt_tx); - - if (FASTLED_RMT_BUILTIN_DRIVER) { - rmt_driver_install(rmt_channel_t(i), 0, 0); - } else { - // -- Set up the RMT to send 32 bits of the pulse buffer and then - // generate an interrupt. When we get this interrupt we - // fill the other part in preparation (like double-buffering) - rmt_set_tx_thr_intr_en(rmt_channel_t(i), true, PULSES_PER_FILL); - } - } - - // -- Create a semaphore to block execution until all the controllers are done - if (gTX_sem == NULL) { - gTX_sem = xSemaphoreCreateBinary(); - xSemaphoreGive(gTX_sem); - } - - if ( ! FASTLED_RMT_BUILTIN_DRIVER) { - // -- Allocate the interrupt if we have not done so yet. This - // interrupt handler must work for all different kinds of - // strips, so it delegates to the refill function for each - // specific instantiation of ClocklessController. - if (gRMT_intr_handle == NULL) - esp_intr_alloc(ETS_RMT_INTR_SOURCE, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL3, interruptHandler, 0, &gRMT_intr_handle); - } - - gInitialized = true; -} - -// -- Show this string of pixels -// This is the main entry point for the pixel controller -void IRAM_ATTR ESP32RMTController::showPixels() -{ - if (gNumStarted == 0) { - // -- First controller: make sure everything is set up - ESP32RMTController::init(mPin); - -#if FASTLED_ESP32_FLASH_LOCK == 1 - // -- Make sure no flash operations happen right now - spi_flash_op_lock(); -#endif - } - - // -- Keep track of the number of strips we've seen - gNumStarted++; - - // -- The last call to showPixels is the one responsible for doing - // all of the actual worl - if (gNumStarted == gNumControllers) { - gNext = 0; - - // -- This Take always succeeds immediately - xSemaphoreTake(gTX_sem, portMAX_DELAY); - - // -- Make sure it's been at least 50us since last show - gWait.wait(); - - // -- First, fill all the available channels - int channel = 0; - while (channel < FASTLED_RMT_MAX_CHANNELS && gNext < gNumControllers) { - ESP32RMTController::startNext(channel); - // -- Important: when we use more than one memory block, we need to - // skip the channels that would otherwise overlap in memory. - channel += FASTLED_RMT_MEM_BLOCKS; - } - - // -- Wait here while the data is sent. The interrupt handler - // will keep refilling the RMT buffers until it is all - // done; then it gives the semaphore back. - xSemaphoreTake(gTX_sem, portMAX_DELAY); - xSemaphoreGive(gTX_sem); - - // -- Make sure we don't call showPixels too quickly - gWait.mark(); - - // -- Reset the counters - gNumStarted = 0; - gNumDone = 0; - gNext = 0; - -#if FASTLED_ESP32_FLASH_LOCK == 1 - // -- Release the lock on flash operations - spi_flash_op_unlock(); -#endif - - } -} - -// -- Start up the next controller -// This method is static so that it can dispatch to the -// appropriate startOnChannel method of the given controller. -void IRAM_ATTR ESP32RMTController::startNext(int channel) -{ - if (gNext < gNumControllers) { - ESP32RMTController * pController = gControllers[gNext]; - pController->startOnChannel(channel); - gNext++; - } -} - -// -- Start this controller on the given channel -// This function just initiates the RMT write; it does not wait -// for it to finish. -void IRAM_ATTR ESP32RMTController::startOnChannel(int channel) -{ - // -- Assign this channel and configure the RMT - mRMT_channel = rmt_channel_t(channel); - - // -- Store a reference to this controller, so we can get it - // inside the interrupt handler - gOnChannel[channel] = this; - - // -- Assign the pin to this channel - rmt_set_pin(mRMT_channel, RMT_MODE_TX, mPin); - - if (FASTLED_RMT_BUILTIN_DRIVER) { - // -- Use the built-in RMT driver to send all the data in one shot - rmt_register_tx_end_callback(doneOnChannel, 0); - rmt_write_items(mRMT_channel, mBuffer, mBufferSize, false); - } else { - // -- Use our custom driver to send the data incrementally - - // -- Initialize the counters that keep track of where we are in - // the pixel data and the RMT buffer - mRMT_mem_start = & (RMTMEM.chan[mRMT_channel].data32[0].val); - mRMT_mem_ptr = mRMT_mem_start; - mCur = 0; - mWhichHalf = 0; - mLastFill = 0; - - // -- Fill both halves of the RMT buffer (a totaly of 64 bits of pixel data) - fillNext(false); - fillNext(false); - - // -- Turn on the interrupts - rmt_set_tx_intr_en(mRMT_channel, true); - - // -- Kick off the transmission - tx_start(); - } -} - -// -- Start RMT transmission -// Setting this RMT flag is what actually kicks off the peripheral -void IRAM_ATTR ESP32RMTController::tx_start() -{ - // rmt_tx_start(mRMT_channel, true); - // Inline the code for rmt_tx_start, so it can be placed in IRAM - RMT.conf_ch[mRMT_channel].conf1.mem_rd_rst = 1; - RMT.conf_ch[mRMT_channel].conf1.mem_rd_rst = 0; - RMT.int_ena.val &= ~(1 << (mRMT_channel * 3)); - RMT.int_ena.val |= (1 << (mRMT_channel * 3)); - RMT.conf_ch[mRMT_channel].conf1.tx_start = 1; - mLastFill = __clock_cycles(); -} - -// -- A controller is done -// This function is called when a controller finishes writing -// its data. It is called either by the custom interrupt -// handler (below), or as a callback from the built-in -// interrupt handler. It is static because we don't know which -// controller is done until we look it up. -void IRAM_ATTR ESP32RMTController::doneOnChannel(rmt_channel_t channel, void * arg) -{ - ESP32RMTController * pController = gOnChannel[channel]; - - // -- Turn off output on the pin - // SZG: Do I really need to do this? - gpio_matrix_out(pController->mPin, 0x100, 0, 0); - - // -- Turn off the interrupts - // rmt_set_tx_intr_en(channel, false); - // Inline the code for rmt_tx_stop, so it can be placed in IRAM - RMT.int_ena.val &= ~(1 << (channel * 3)); - RMT.conf_ch[channel].conf1.mem_rd_rst = 1; - RMT.conf_ch[channel].conf1.mem_rd_rst = 0; - - gOnChannel[channel] = NULL; - gNumDone++; - - if (gNumDone == gNumControllers) { - // -- If this is the last controller, signal that we are all done - if (FASTLED_RMT_BUILTIN_DRIVER) { - xSemaphoreGive(gTX_sem); - } else { - portBASE_TYPE HPTaskAwoken = 0; - xSemaphoreGiveFromISR(gTX_sem, &HPTaskAwoken); - if (HPTaskAwoken == pdTRUE) portYIELD_FROM_ISR(); - } - } else { - // -- Otherwise, if there are still controllers waiting, then - // start the next one on this channel - if (gNext < gNumControllers) { - startNext(channel); - } - } -} - -// -- Custom interrupt handler -// This interrupt handler handles two cases: a controller is -// done writing its data, or a controller needs to fill the -// next half of the RMT buffer with data. -void IRAM_ATTR ESP32RMTController::interruptHandler(void *arg) -{ - // -- The basic structure of this code is borrowed from the - // interrupt handler in esp-idf/components/driver/rmt.c - uint32_t intr_st = RMT.int_st.val; - uint8_t channel; - - bool stuff_to_do = false; - for (channel = 0; channel < FASTLED_RMT_MAX_CHANNELS; channel++) { - int tx_done_bit = channel * 3; - int tx_next_bit = channel + 24; - - ESP32RMTController * pController = gOnChannel[channel]; - if (pController != NULL) { - if (intr_st & BIT(tx_next_bit)) { - // -- More to send on this channel - pController->fillNext(true); - RMT.int_clr.val |= BIT(tx_next_bit); - } else { - // -- Transmission is complete on this channel - if (intr_st & BIT(tx_done_bit)) { - RMT.int_clr.val |= BIT(tx_done_bit); - doneOnChannel(rmt_channel_t(channel), 0); - } - } - } - } -} - -// -- Fill RMT buffer -// Puts 32 bits of pixel data into the next 32 slots in the RMT memory -// Each data bit is represented by a 32-bit RMT item that specifies how -// long to hold the signal high, followed by how long to hold it low. -void IRAM_ATTR ESP32RMTController::fillNext(bool check_time) -{ - uint32_t now = __clock_cycles(); - if (check_time) { - if (mLastFill != 0 and now > mLastFill) { - uint32_t delta = (now - mLastFill); - if (delta > mMaxCyclesPerFill) { - // Serial.print(delta); - // Serial.print(" BAIL "); - // Serial.println(mCur); - // rmt_tx_stop(mRMT_channel); - // Inline the code for rmt_tx_stop, so it can be placed in IRAM - /** -- Go back to the original strategy of just setting mCur = mSize - and letting the regular 'stop' process happen - * mRMT_mem_start = 0; - RMT.int_ena.val &= ~(1 << (mRMT_channel * 3)); - RMT.conf_ch[mRMT_channel].conf1.tx_start = 0; - RMT.conf_ch[mRMT_channel].conf1.mem_rd_rst = 1; - RMT.conf_ch[mRMT_channel].conf1.mem_rd_rst = 0; - */ - mCur = mSize; - } - } - } - mLastFill = now; - - // -- Get the zero and one values into local variables - register uint32_t one_val = mOne.val; - register uint32_t zero_val = mZero.val; - - // -- Use locals for speed - volatile register uint32_t * pItem = mRMT_mem_ptr; - - for (register int i = 0; i < PULSES_PER_FILL/32; i++) { - if (mCur < mSize) { - - // -- Get the next four bytes of pixel data - register uint32_t pixeldata = mPixelData[mCur]; - mCur++; - - // Shift bits out, MSB first, setting RMTMEM.chan[n].data32[x] to the - // rmt_item32_t value corresponding to the buffered bit value - for (register uint32_t j = 0; j < 32; j++) { - *pItem++ = (pixeldata & 0x80000000L) ? one_val : zero_val; - // Replaces: RMTMEM.chan[mRMT_channel].data32[mCurPulse].val = val; - - pixeldata <<= 1; - } - } else { - // -- No more data; signal to the RMT we are done by filling the - // rest of the buffer with zeros - *pItem++ = 0; - } - } - - // -- Flip to the other half, resetting the pointer if necessary - mWhichHalf++; - if (mWhichHalf == 2) { - pItem = mRMT_mem_start; - mWhichHalf = 0; - } - - // -- Store the new pointer back into the object - mRMT_mem_ptr = pItem; -} - -// -- Init pulse buffer -// Set up the buffer that will hold all of the pulse items for this -// controller. -// This function is only used when the built-in RMT driver is chosen -void ESP32RMTController::initPulseBuffer(int size_in_bytes) -{ - if (mBuffer == 0) { - // -- Each byte has 8 bits, each bit needs a 32-bit RMT item - mBufferSize = size_in_bytes * 8 * 4; - mBuffer = (rmt_item32_t *) calloc( mBufferSize, sizeof(rmt_item32_t)); - } - mCurPulse = 0; -} - -// -- Convert a byte into RMT pulses -// This function is only used when the built-in RMT driver is chosen -void ESP32RMTController::convertByte(uint32_t byteval) -{ - // -- Write one byte's worth of RMT pulses to the big buffer - byteval <<= 24; - for (register uint32_t j = 0; j < 8; j++) { - mBuffer[mCurPulse] = (byteval & 0x80000000L) ? mOne : mZero; - byteval <<= 1; - mCurPulse++; - } -} - -#endif diff --git a/FastLED/src/platforms/esp/32/clockless_rmt_esp32.h b/FastLED/src/platforms/esp/32/clockless_rmt_esp32.h deleted file mode 100644 index 2e723179ebae66fa8e29c8da83af2e0dfe068533..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/32/clockless_rmt_esp32.h +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Integration into FastLED ClocklessController - * Copyright (c) 2018,2019,2020 Samuel Z. Guyer - * Copyright (c) 2017 Thomas Basler - * Copyright (c) 2017 Martin F. Falatic - * - * ESP32 support is provided using the RMT peripheral device -- a unit - * on the chip designed specifically for generating (and receiving) - * precisely-timed digital signals. Nominally for use in infrared - * remote controls, we use it to generate the signals for clockless - * LED strips. The main advantage of using the RMT device is that, - * once programmed, it generates the signal asynchronously, allowing - * the CPU to continue executing other code. It is also not vulnerable - * to interrupts or other timing problems that could disrupt the signal. - * - * The implementation strategy is borrowed from previous work and from - * the RMT support built into the ESP32 IDF. The RMT device has 8 - * channels, which can be programmed independently to send sequences - * of high/low bits. Memory for each channel is limited, however, so - * in order to send a long sequence of bits, we need to continuously - * refill the buffer until all the data is sent. To do this, we fill - * half the buffer and then set an interrupt to go off when that half - * is sent. Then we refill that half while the second half is being - * sent. This strategy effectively overlaps computation (by the CPU) - * and communication (by the RMT). - * - * Since the RMT device only has 8 channels, we need a strategy to - * allow more than 8 LED controllers. Our driver assigns controllers - * to channels on the fly, queuing up controllers as necessary until a - * channel is free. The main showPixels routine just fires off the - * first 8 controllers; the interrupt handler starts new controllers - * asynchronously as previous ones finish. So, for example, it can - * send the data for 8 controllers simultaneously, but 16 controllers - * would take approximately twice as much time. - * - * There is a #define that allows a program to control the total - * number of channels that the driver is allowed to use. It defaults - * to 8 -- use all the channels. Setting it to 1, for example, results - * in fully serial output: - * - * #define FASTLED_RMT_MAX_CHANNELS 1 - * - * OTHER RMT APPLICATIONS - * - * The default FastLED driver takes over control of the RMT interrupt - * handler, making it hard to use the RMT device for other - * (non-FastLED) purposes. You can change it's behavior to use the ESP - * core driver instead, allowing other RMT applications to - * co-exist. To switch to this mode, add the following directive - * before you include FastLED.h: - * - * #define FASTLED_RMT_BUILTIN_DRIVER 1 - * - * There may be a performance penalty for using this mode. We need to - * compute the RMT signal for the entire LED strip ahead of time, - * rather than overlapping it with communication. We also need a large - * buffer to hold the signal specification. Each bit of pixel data is - * represented by a 32-bit pulse specification, so it is a 32X blow-up - * in memory use. - * - * NEW: Use of Flash memory on the ESP32 can interfere with the timing - * of pixel output. The ESP-IDF system code disables all other - * code running on *either* core during these operation. To prevent - * this from happening, define this flag. It will force flash - * operations to wait until the show() is done. - * - * #define FASTLED_ESP32_FLASH_LOCK 1 - * - * NEW (June 2020): The RMT controller has been split into two - * classes: ClocklessController, which is an instantiation of the - * FastLED CPixelLEDController template, and ESP32RMTController, - * which just handles driving the RMT peripheral. One benefit of - * this design is that ESP32RMTContoller is not a template, so - * its methods can be marked with the IRAM_ATTR and end up in - * IRAM memory. Another benefit is that all of the color channel - * processing is done up-front, in the templated class, so we - * can fill the RMT buffers more quickly. - * - * IN THEORY, this design would also allow FastLED.show() to - * send the data while the program continues to prepare the next - * frame of data. - * - * Based on public domain code created 19 Nov 2016 by Chris Osborn <fozztexx@fozztexx.com> - * http://insentricity.com * - * - */ -/* - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -FASTLED_NAMESPACE_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif - -#include "esp32-hal.h" -#include "esp_intr.h" -#include "driver/gpio.h" -#include "driver/rmt.h" -#include "driver/periph_ctrl.h" -#include "freertos/semphr.h" -#include "soc/rmt_struct.h" - -#include "esp_log.h" - -extern void spi_flash_op_lock(void); -extern void spi_flash_op_unlock(void); - -#ifdef __cplusplus -} -#endif - -__attribute__ ((always_inline)) inline static uint32_t __clock_cycles() { - uint32_t cyc; - __asm__ __volatile__ ("rsr %0,ccount":"=a" (cyc)); - return cyc; -} - -#define FASTLED_HAS_CLOCKLESS 1 -#define NUM_COLOR_CHANNELS 3 - -// NOT CURRENTLY IMPLEMENTED: -// -- Set to true to print debugging information about timing -// Useful for finding out if timing is being messed up by other things -// on the processor (WiFi, for example) -//#ifndef FASTLED_RMT_SHOW_TIMER -//#define FASTLED_RMT_SHOW_TIMER false -//#endif - -// -- Configuration constants -#define DIVIDER 2 /* 4, 8 still seem to work, but timings become marginal */ - -// -- RMT memory configuration -// By default we use two memory blocks for each RMT channel instead of 1. The -// reason is that one memory block is only 64 bits, which causes the refill -// interrupt to fire too often. When combined with WiFi, this leads to conflicts -// between interrupts and weird flashy effects on the LEDs. Special thanks to -// Brian Bulkowski for finding this problem and developing a fix. -#ifndef FASTLED_RMT_MEM_BLOCKS -#define FASTLED_RMT_MEM_BLOCKS 2 -#endif - -#define MAX_PULSES (64 * FASTLED_RMT_MEM_BLOCKS) /* One block has a 64 "pulse" buffer */ -#define PULSES_PER_FILL (MAX_PULSES / 2) /* Half of the channel buffer */ - -// -- Convert ESP32 CPU cycles to RMT device cycles, taking into account the divider -#define F_CPU_RMT ( 80000000L) -#define RMT_CYCLES_PER_SEC (F_CPU_RMT/DIVIDER) -#define RMT_CYCLES_PER_ESP_CYCLE (F_CPU / RMT_CYCLES_PER_SEC) -#define ESP_TO_RMT_CYCLES(n) ((n) / (RMT_CYCLES_PER_ESP_CYCLE)) - -// -- Number of cycles to signal the strip to latch -#define NS_PER_CYCLE ( 1000000000L / RMT_CYCLES_PER_SEC ) -#define NS_TO_CYCLES(n) ( (n) / NS_PER_CYCLE ) -#define RMT_RESET_DURATION NS_TO_CYCLES(50000) - -// -- Core or custom driver -#ifndef FASTLED_RMT_BUILTIN_DRIVER -#define FASTLED_RMT_BUILTIN_DRIVER false -#endif - -// -- Max number of controllers we can support -#ifndef FASTLED_RMT_MAX_CONTROLLERS -#define FASTLED_RMT_MAX_CONTROLLERS 32 -#endif - -// -- Number of RMT channels to use (up to 8, but 4 by default) -// Redefine this value to 1 to force serial output -#ifndef FASTLED_RMT_MAX_CHANNELS -#define FASTLED_RMT_MAX_CHANNELS (8/FASTLED_RMT_MEM_BLOCKS) -#endif - -class ESP32RMTController -{ -private: - - // -- RMT has 8 channels, numbered 0 to 7 - rmt_channel_t mRMT_channel; - - // -- Store the GPIO pin - gpio_num_t mPin; - - // -- Timing values for zero and one bits, derived from T1, T2, and T3 - rmt_item32_t mZero; - rmt_item32_t mOne; - - // -- Total expected time to send 32 bits - // Each strip should get an interrupt roughly at this interval - uint32_t mCyclesPerFill; - uint32_t mMaxCyclesPerFill; - uint32_t mLastFill; - - // -- Pixel data - uint32_t * mPixelData; - int mSize; - int mCur; - - // -- RMT memory - volatile uint32_t * mRMT_mem_ptr; - volatile uint32_t * mRMT_mem_start; - int mWhichHalf; - - // -- Buffer to hold all of the pulses. For the version that uses - // the RMT driver built into the ESP core. - rmt_item32_t * mBuffer; - uint16_t mBufferSize; // bytes - int mCurPulse; - -public: - - // -- Constructor - // Mainly just stores the template parameters from the LEDController as - // member variables. - ESP32RMTController(int DATA_PIN, int T1, int T2, int T3); - - // -- Get max cycles per fill - uint32_t IRAM_ATTR getMaxCyclesPerFill() const { return mMaxCyclesPerFill; } - - // -- Get or create the pixel data buffer - uint32_t * getPixelBuffer(int size_in_bytes); - - // -- Initialize RMT subsystem - // This only needs to be done once. The particular pin is not important, - // because we need to configure the RMT channels on the fly. - static void init(gpio_num_t pin); - - // -- Show this string of pixels - // This is the main entry point for the pixel controller - void IRAM_ATTR showPixels(); - - // -- Start up the next controller - // This method is static so that it can dispatch to the - // appropriate startOnChannel method of the given controller. - static void IRAM_ATTR startNext(int channel); - - // -- Start this controller on the given channel - // This function just initiates the RMT write; it does not wait - // for it to finish. - void IRAM_ATTR startOnChannel(int channel); - - // -- Start RMT transmission - // Setting this RMT flag is what actually kicks off the peripheral - void IRAM_ATTR tx_start(); - - // -- A controller is done - // This function is called when a controller finishes writing - // its data. It is called either by the custom interrupt - // handler (below), or as a callback from the built-in - // interrupt handler. It is static because we don't know which - // controller is done until we look it up. - static void IRAM_ATTR doneOnChannel(rmt_channel_t channel, void * arg); - - // -- Custom interrupt handler - // This interrupt handler handles two cases: a controller is - // done writing its data, or a controller needs to fill the - // next half of the RMT buffer with data. - static void IRAM_ATTR interruptHandler(void *arg); - - // -- Fill RMT buffer - // Puts 32 bits of pixel data into the next 32 slots in the RMT memory - // Each data bit is represented by a 32-bit RMT item that specifies how - // long to hold the signal high, followed by how long to hold it low. - // NOTE: Now the default is to use 128-bit buffers, so half a buffer is - // is 64 bits. See FASTLED_RMT_MEM_BLOCKS - void IRAM_ATTR fillNext(bool check_time); - - // -- Init pulse buffer - // Set up the buffer that will hold all of the pulse items for this - // controller. - // This function is only used when the built-in RMT driver is chosen - void initPulseBuffer(int size_in_bytes); - - // -- Convert a byte into RMT pulses - // This function is only used when the built-in RMT driver is chosen - void convertByte(uint32_t byteval); -}; - -template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 5> -class ClocklessController : public CPixelLEDController<RGB_ORDER> -{ -private: - - // -- The actual controller object for ESP32 - ESP32RMTController mRMTController; - - // -- This instantiation forces a check on the pin choice - FastPin<DATA_PIN> mFastPin; - -public: - - ClocklessController() - : mRMTController(DATA_PIN, T1, T2, T3) - {} - - void init() - { - // mRMTController = new ESP32RMTController(DATA_PIN, T1, T2, T3); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - - // -- Load pixel data - // This method loads all of the pixel data into a separate buffer for use by - // by the RMT driver. Copying does two important jobs: it fixes the color - // order for the pixels, and it performs the scaling/adjusting ahead of time. - // It also packs the bytes into 32 bit chunks with the right bit order. - void loadPixelData(PixelController<RGB_ORDER> & pixels) - { - // -- Make sure the buffer is allocated - int size_in_bytes = pixels.size() * 3; - uint32_t * pData = mRMTController.getPixelBuffer(size_in_bytes); - - // -- Read out the pixel data using the pixel controller methods that - // perform the scaling and adjustments - int count = 0; - int which = 0; - while (pixels.has(1)) { - // -- Get the next four bytes of data - uint8_t four[4] = {0,0,0,0}; - for (int i = 0; i < 4; i++) { - switch (which) { - case 0: - four[i] = pixels.loadAndScale0(); - break; - case 1: - four[i] = pixels.loadAndScale1(); - break; - case 2: - four[i] = pixels.loadAndScale2(); - pixels.advanceData(); - pixels.stepDithering(); - break; - } - // -- Move to the next color - which++; - if (which > 2) which = 0; - - // -- Stop if there's no more data - if ( ! pixels.has(1)) break; - } - - // -- Pack the four bytes into a 32-bit value with the right bit order - uint8_t a = four[0]; - uint8_t b = four[1]; - uint8_t c = four[2]; - uint8_t d = four[3]; - pData[count++] = a << 24 | b << 16 | c << 8 | d; - } - } - - // -- Show pixels - // This is the main entry point for the controller. - virtual void showPixels(PixelController<RGB_ORDER> & pixels) - { - if (FASTLED_RMT_BUILTIN_DRIVER) { - convertAllPixelData(pixels); - } else { - loadPixelData(pixels); - } - - mRMTController.showPixels(); - } - - // -- Convert all pixels to RMT pulses - // This function is only used when the user chooses to use the - // built-in RMT driver, which needs all of the RMT pulses - // up-front. - void convertAllPixelData(PixelController<RGB_ORDER> & pixels) - { - // -- Make sure the data buffer is allocated - mRMTController.initPulseBuffer(pixels.size() * 3); - - // -- Cycle through the R,G, and B values in the right order, - // storing the pulses in the big buffer - - uint32_t byteval; - while (pixels.has(1)) { - byteval = pixels.loadAndScale0(); - mRMTController.convertByte(byteval); - byteval = pixels.loadAndScale1(); - mRMTController.convertByte(byteval); - byteval = pixels.loadAndScale2(); - mRMTController.convertByte(byteval); - pixels.advanceData(); - pixels.stepDithering(); - } - } -}; - - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/platforms/esp/32/fastled_esp32.h b/FastLED/src/platforms/esp/32/fastled_esp32.h deleted file mode 100644 index edf27e7d997237eb7a8640b4131a7a0f08a66e08..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/32/fastled_esp32.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "fastpin_esp32.h" - -#ifdef FASTLED_ESP32_I2S -#include "clockless_i2s_esp32.h" -#else -#include "clockless_rmt_esp32.h" -#endif - -// #include "clockless_block_esp32.h" diff --git a/FastLED/src/platforms/esp/32/fastpin_esp32.h b/FastLED/src/platforms/esp/32/fastpin_esp32.h deleted file mode 100644 index 7876b281f9890b047108a7efe34bbb1f1ff5383a..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/32/fastpin_esp32.h +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once - -FASTLED_NAMESPACE_BEGIN - -template<uint8_t PIN, uint32_t MASK> class _ESPPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } - inline static void setInput() { pinMode(PIN, INPUT); } - - inline static void hi() __attribute__ ((always_inline)) { - if (PIN < 32) GPIO.out_w1ts = MASK; - else GPIO.out1_w1ts.val = MASK; - } - - inline static void lo() __attribute__ ((always_inline)) { - if (PIN < 32) GPIO.out_w1tc = MASK; - else GPIO.out1_w1tc.val = MASK; - } - - inline static void set(register port_t val) __attribute__ ((always_inline)) { - if (PIN < 32) GPIO.out = val; - else GPIO.out1.val = val; - } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { - if(PIN < 32) { GPIO.out ^= MASK; } - else { GPIO.out1.val ^=MASK; } - } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { - if (PIN < 32) return GPIO.out | MASK; - else return GPIO.out1.val | MASK; - } - - inline static port_t loval() __attribute__ ((always_inline)) { - if (PIN < 32) return GPIO.out & ~MASK; - else return GPIO.out1.val & ~MASK; - } - - inline static port_ptr_t port() __attribute__ ((always_inline)) { - if (PIN < 32) return &GPIO.out; - else return &GPIO.out1.val; - } - - inline static port_ptr_t sport() __attribute__ ((always_inline)) { - if (PIN < 32) return &GPIO.out_w1ts; - else return &GPIO.out1_w1ts.val; - } - - inline static port_ptr_t cport() __attribute__ ((always_inline)) { - if (PIN < 32) return &GPIO.out_w1tc; - else return &GPIO.out1_w1tc.val; - } - - inline static port_t mask() __attribute__ ((always_inline)) { return MASK; } - - inline static bool isset() __attribute__ ((always_inline)) { - if (PIN < 32) return GPIO.out & MASK; - else return GPIO.out1.val & MASK; - } -}; - -#define _FL_DEFPIN(PIN) template<> class FastPin<PIN> : public _ESPPIN<PIN, ((PIN<32)?((uint32_t)1 << PIN):((uint32_t)1 << (PIN-32)))> {}; - -_FL_DEFPIN(0); -_FL_DEFPIN(1); // WARNING: Using TX causes flashiness when uploading -_FL_DEFPIN(2); -_FL_DEFPIN(3); // WARNING: Using RX causes flashiness when uploading -_FL_DEFPIN(4); -_FL_DEFPIN(5); - -// -- These pins are not safe to use: -// _FL_DEFPIN(6,6); _FL_DEFPIN(7,7); _FL_DEFPIN(8,8); -// _FL_DEFPIN(9,9); _FL_DEFPIN(10,10); _FL_DEFPIN(11,11); - -_FL_DEFPIN(12); -_FL_DEFPIN(13); -_FL_DEFPIN(14); -_FL_DEFPIN(15); -_FL_DEFPIN(16); -_FL_DEFPIN(17); -_FL_DEFPIN(18); -_FL_DEFPIN(19); - -// No pin 20 : _FL_DEFPIN(20,20); - -_FL_DEFPIN(21); // Works, but note that GPIO21 is I2C SDA -_FL_DEFPIN(22); // Works, but note that GPIO22 is I2C SCL -_FL_DEFPIN(23); - -// No pin 24 : _FL_DEFPIN(24,24); - -_FL_DEFPIN(25); -_FL_DEFPIN(26); -_FL_DEFPIN(27); - -// No pin 28-31: _FL_DEFPIN(28,28); _FL_DEFPIN(29,29); _FL_DEFPIN(30,30); _FL_DEFPIN(31,31); - -// Need special handling for pins > 31 -_FL_DEFPIN(32); -_FL_DEFPIN(33); - -#define HAS_HARDWARE_PIN_SUPPORT - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/platforms/esp/32/led_sysdefs_esp32.h b/FastLED/src/platforms/esp/32/led_sysdefs_esp32.h deleted file mode 100644 index 5cd374e2f483d4e295a5f0f2325b3b8686667e53..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/32/led_sysdefs_esp32.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#ifndef ESP32 -#define ESP32 -#endif - -#define FASTLED_ESP32 - -// Use system millis timer -#define FASTLED_HAS_MILLIS - -typedef volatile uint32_t RoReg; -typedef volatile uint32_t RwReg; -typedef unsigned long prog_uint32_t; - - -// Default to NOT using PROGMEM here -#ifndef FASTLED_USE_PROGMEM -# define FASTLED_USE_PROGMEM 0 -#endif - -#ifndef FASTLED_ALLOW_INTERRUPTS -# define FASTLED_ALLOW_INTERRUPTS 1 -# define INTERRUPT_THRESHOLD 0 -#endif - -#define NEED_CXX_BITS - -// These can be overridden -# define FASTLED_ESP32_RAW_PIN_ORDER - -// #define cli() os_intr_lock(); -// #define sei() os_intr_lock(); diff --git a/FastLED/src/platforms/esp/8266/clockless_block_esp8266.h b/FastLED/src/platforms/esp/8266/clockless_block_esp8266.h deleted file mode 100644 index 3eccbe1e81dd6c7566869aae91846bde434c6907..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/8266/clockless_block_esp8266.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef __INC_CLOCKLESS_BLOCK_ESP8266_H -#define __INC_CLOCKLESS_BLOCK_ESP8266_H - -#define FASTLED_HAS_BLOCKLESS 1 - -#define FIX_BITS(bits) (((bits & 0x0fL) << 12) | (bits & 0x30)) - -#define MIN(X,Y) (((X)<(Y)) ? (X):(Y)) -#define USED_LANES (MIN(LANES, 6)) -#define PORT_MASK (((1 << USED_LANES)-1) & 0x0000FFFFL) -#define PIN_MASK FIX_BITS(PORT_MASK) - -FASTLED_NAMESPACE_BEGIN - -#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES -extern uint32_t _frame_cnt; -extern uint32_t _retry_cnt; -#endif - -template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PORT_MASK> { - typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<FIRST_PIN>::port_t data_t; - - CMinWait<WAIT_TIME> mWait; - -public: - virtual int size() { return CLEDController::size() * LANES; } - - virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) { - // mWait.wait(); - /*uint32_t clocks = */ - int cnt=FASTLED_INTERRUPT_RETRY_COUNT; - while(!showRGBInternal(pixels) && cnt--) { - os_intr_unlock(); - #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES - ++_retry_cnt; - #endif - delayMicroseconds(WAIT_TIME * 10); - os_intr_lock(); - } - // #if FASTLED_ALLOW_INTTERUPTS == 0 - // Adjust the timer - // long microsTaken = CLKS_TO_MICROS(clocks); - // MS_COUNTER += (1 + (microsTaken / 1000)); - // #endif - - // mWait.mark(); - } - - template<int PIN> static void initPin() { - _ESPPIN<PIN, 1<<(PIN & 0xFF)>::setOutput(); - } - - virtual void init() { - void (* funcs[])() ={initPin<12>, initPin<13>, initPin<14>, initPin<15>, initPin<4>, initPin<5>}; - - for (uint8_t i = 0; i < USED_LANES; ++i) { - funcs[i](); - } - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - - typedef union { - uint8_t bytes[8]; - uint16_t shorts[4]; - uint32_t raw[2]; - } Lines; - -#define ESP_ADJUST 0 // (2*(F_CPU/24000000)) -#define ESP_ADJUST2 0 - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register Lines & b, PixelController<RGB_ORDER, LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) { - Lines b2 = b; - transpose8x1_noinline(b.bytes,b2.bytes); - - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - for(register uint32_t i = 0; i < USED_LANES; ++i) { - while((__clock_cycles() - last_mark) < (T1+T2+T3)); - last_mark = __clock_cycles(); - *FastPin<FIRST_PIN>::sport() = PIN_MASK; - - uint32_t nword = (uint32_t)(~b2.bytes[7-i]); - while((__clock_cycles() - last_mark) < (T1-6)); - *FastPin<FIRST_PIN>::cport() = FIX_BITS(nword); - - while((__clock_cycles() - last_mark) < (T1+T2)); - *FastPin<FIRST_PIN>::cport() = PIN_MASK; - - b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); - } - - for(register uint32_t i = USED_LANES; i < 8; ++i) { - while((__clock_cycles() - last_mark) < (T1+T2+T3)); - last_mark = __clock_cycles(); - *FastPin<FIRST_PIN>::sport() = PIN_MASK; - - uint32_t nword = (uint32_t)(~b2.bytes[7-i]); - while((__clock_cycles() - last_mark) < (T1-6)); - *FastPin<FIRST_PIN>::cport() = FIX_BITS(nword); - - while((__clock_cycles() - last_mark) < (T1+T2)); - *FastPin<FIRST_PIN>::cport() = PIN_MASK; - } - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t ICACHE_RAM_ATTR showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) { - - // Setup the pixel controller and load/scale the first byte - Lines b0; - - for(int i = 0; i < USED_LANES; ++i) { - b0.bytes[i] = allpixels.loadAndScale0(i); - } - allpixels.preStepFirstByteDithering(); - - os_intr_lock(); - uint32_t _start = __clock_cycles(); - uint32_t last_mark = _start; - - while(allpixels.has(1)) { - // Write first byte, read next byte - writeBits<8+XTRA0,1>(last_mark, b0, allpixels); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(last_mark, b0, allpixels); - allpixels.advanceData(); - - // Write third byte - writeBits<8+XTRA0,0>(last_mark, b0, allpixels); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - os_intr_unlock(); - #endif - - allpixels.stepDithering(); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - os_intr_lock(); - // if interrupts took longer than 45µs, punt on the current frame - if((int32_t)(__clock_cycles()-last_mark) > 0) { - if((int32_t)(__clock_cycles()-last_mark) > (T1+T2+T3+((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US))) { os_intr_unlock(); return 0; } - } - #endif - }; - - os_intr_unlock(); - #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES - ++_frame_cnt; - #endif - return __clock_cycles() - _start; - } -}; - -FASTLED_NAMESPACE_END -#endif diff --git a/FastLED/src/platforms/esp/8266/clockless_esp8266.h b/FastLED/src/platforms/esp/8266/clockless_esp8266.h deleted file mode 100644 index 131f24671b22f58ba036e3fc81c70378dd2b8358..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/8266/clockless_esp8266.h +++ /dev/null @@ -1,117 +0,0 @@ -#pragma once - -FASTLED_NAMESPACE_BEGIN - -#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES -extern uint32_t _frame_cnt; -extern uint32_t _retry_cnt; -#endif - -// Info on reading cycle counter from https://github.com/kbeckmann/nodemcu-firmware/blob/ws2812-dual/app/modules/ws2812.c -__attribute__ ((always_inline)) inline static uint32_t __clock_cycles() { - uint32_t cyc; - __asm__ __volatile__ ("rsr %0,ccount":"=a" (cyc)); - return cyc; -} - -#define FASTLED_HAS_CLOCKLESS 1 - -template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CPixelLEDController<RGB_ORDER> { - typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; - typedef typename FastPin<DATA_PIN>::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait<WAIT_TIME> mWait; -public: - virtual void init() { - FastPin<DATA_PIN>::setOutput(); - mPinMask = FastPin<DATA_PIN>::mask(); - mPort = FastPin<DATA_PIN>::port(); - } - - virtual uint16_t getMaxRefreshRate() const { return 400; } - -protected: - - virtual void showPixels(PixelController<RGB_ORDER> & pixels) { - // mWait.wait(); - int cnt = FASTLED_INTERRUPT_RETRY_COUNT; - while((showRGBInternal(pixels)==0) && cnt--) { - #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES - ++_retry_cnt; - #endif - os_intr_unlock(); - delayMicroseconds(WAIT_TIME); - os_intr_lock(); - } - // mWait.mark(); - } - -#define _ESP_ADJ (0) -#define _ESP_ADJ2 (0) - - template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register uint32_t b) { - b <<= 24; b = ~b; - for(register uint32_t i = BITS; i > 0; --i) { - while((__clock_cycles() - last_mark) < (T1+T2+T3)); - last_mark = __clock_cycles(); - FastPin<DATA_PIN>::hi(); - - while((__clock_cycles() - last_mark) < T1); - if(b & 0x80000000L) { FastPin<DATA_PIN>::lo(); } - b <<= 1; - - while((__clock_cycles() - last_mark) < (T1+T2)); - FastPin<DATA_PIN>::lo(); - } - } - - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then - // gcc will use register Y for the this pointer. - static uint32_t ICACHE_RAM_ATTR showRGBInternal(PixelController<RGB_ORDER> pixels) { - // Setup the pixel controller and load/scale the first byte - pixels.preStepFirstByteDithering(); - register uint32_t b = pixels.loadAndScale0(); - pixels.preStepFirstByteDithering(); - os_intr_lock(); - uint32_t start = __clock_cycles(); - uint32_t last_mark = start; - while(pixels.has(1)) { - // Write first byte, read next byte - writeBits<8+XTRA0>(last_mark, b); - b = pixels.loadAndScale1(); - - // Write second byte, read 3rd byte - writeBits<8+XTRA0>(last_mark, b); - b = pixels.loadAndScale2(); - - // Write third byte, read 1st byte of next pixel - writeBits<8+XTRA0>(last_mark, b); - b = pixels.advanceAndLoadAndScale0(); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - os_intr_unlock(); - #endif - - pixels.stepDithering(); - - #if (FASTLED_ALLOW_INTERRUPTS == 1) - os_intr_lock(); - // if interrupts took longer than 45µs, punt on the current frame - if((int32_t)(__clock_cycles()-last_mark) > 0) { - if((int32_t)(__clock_cycles()-last_mark) > (T1+T2+T3+((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US))) { sei(); return 0; } - } - #endif - }; - - os_intr_unlock(); - #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES - ++_frame_cnt; - #endif - return __clock_cycles() - start; - } -}; - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/platforms/esp/8266/fastled_esp8266.h b/FastLED/src/platforms/esp/8266/fastled_esp8266.h deleted file mode 100644 index 8c4048db682e839beeb8f4e692ae38ce3b5629c5..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/8266/fastled_esp8266.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "fastpin_esp8266.h" -#include "clockless_esp8266.h" -#include "clockless_block_esp8266.h" diff --git a/FastLED/src/platforms/esp/8266/fastpin_esp8266.h b/FastLED/src/platforms/esp/8266/fastpin_esp8266.h deleted file mode 100644 index d64119f95aa0e4772fb5a2b2dbd93685e27c915b..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/8266/fastpin_esp8266.h +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -FASTLED_NAMESPACE_BEGIN - -struct FASTLED_ESP_IO { - volatile uint32_t _GPO; - volatile uint32_t _GPOS; - volatile uint32_t _GPOC; -}; - -#define _GPB (*(FASTLED_ESP_IO*)(0x60000000+(0x300))) - - -template<uint8_t PIN, uint32_t MASK> class _ESPPIN { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - inline static void setOutput() { pinMode(PIN, OUTPUT); } - inline static void setInput() { pinMode(PIN, INPUT); } - - inline static void hi() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPOS = MASK; } else { GP16O = 1; } } - inline static void lo() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPOC = MASK; } else { GP16O = 0; } } - inline static void set(register port_t val) __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPO = val; } else { GP16O = val; }} - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPO ^= MASK; } else { GP16O ^= MASK; } } - - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { if (PIN<16) { return GPO | MASK; } else { return GP16O | MASK; } } - inline static port_t loval() __attribute__ ((always_inline)) { if (PIN<16) { return GPO & ~MASK; } else { return GP16O & ~MASK; } } - inline static port_ptr_t port() __attribute__ ((always_inline)) { if(PIN<16) { return &_GPB._GPO; } else { return &GP16O; } } - inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPB._GPOS; } // there is no GP160 support for this - inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPB._GPOC; } - inline static port_t mask() __attribute__ ((always_inline)) { return MASK; } - - inline static bool isset() __attribute__ ((always_inline)) { return (PIN < 16) ? (GPO & MASK) : (GP16O & MASK); } -}; - -#define _FL_DEFPIN(PIN, REAL_PIN) template<> class FastPin<PIN> : public _ESPPIN<REAL_PIN, (1<<(REAL_PIN & 0x0F))> {}; - - -#ifdef FASTLED_ESP8266_RAW_PIN_ORDER -#define MAX_PIN 16 -_FL_DEFPIN(0,0); _FL_DEFPIN(1,1); _FL_DEFPIN(2,2); _FL_DEFPIN(3,3); -_FL_DEFPIN(4,4); _FL_DEFPIN(5,5); - -// These pins should be disabled, as they always cause WDT resets -// _FL_DEFPIN(6,6); _FL_DEFPIN(7,7); -// _FL_DEFPIN(8,8); _FL_DEFPIN(9,9); _FL_DEFPIN(10,10); _FL_DEFPIN(11,11); - -_FL_DEFPIN(12,12); _FL_DEFPIN(13,13); _FL_DEFPIN(14,14); _FL_DEFPIN(15,15); -_FL_DEFPIN(16,16); - -#define PORTA_FIRST_PIN 12 -#elif defined(FASTLED_ESP8266_D1_PIN_ORDER) -#define MAX_PIN 15 -_FL_DEFPIN(0,3); -_FL_DEFPIN(1,1); -_FL_DEFPIN(2,16); -_FL_DEFPIN(3,5); -_FL_DEFPIN(4,4); -_FL_DEFPIN(5,14); -_FL_DEFPIN(6,12); -_FL_DEFPIN(7,13); -_FL_DEFPIN(8,0); -_FL_DEFPIN(9,2); -_FL_DEFPIN(10,15); -_FL_DEFPIN(11,13); -_FL_DEFPIN(12,12); -_FL_DEFPIN(13,14); -_FL_DEFPIN(14,4); -_FL_DEFPIN(15,5); - -#define PORTA_FIRST_PIN 12 - -#else // if defined(FASTLED_ESP8266_NODEMCU_PIN_ORDER) -#define MAX_PIN 10 - -// This seems to be the standard Dxx pin mapping on most of the esp boards that i've found -_FL_DEFPIN(0,16); _FL_DEFPIN(1,5); _FL_DEFPIN(2,4); _FL_DEFPIN(3,0); -_FL_DEFPIN(4,2); _FL_DEFPIN(5,14); _FL_DEFPIN(6,12); _FL_DEFPIN(7,13); -_FL_DEFPIN(8,15); _FL_DEFPIN(9,3); _FL_DEFPIN(10,1); - -#define PORTA_FIRST_PIN 6 - -// The rest of the pins - these are generally not available -// _FL_DEFPIN(11,6); -// _FL_DEFPIN(12,7); _FL_DEFPIN(13,8); _FL_DEFPIN(14,9); _FL_DEFPIN(15,10); -// _FL_DEFPIN(16,11); - -#endif - -#define HAS_HARDWARE_PIN_SUPPORT - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/platforms/esp/8266/led_sysdefs_esp8266.h b/FastLED/src/platforms/esp/8266/led_sysdefs_esp8266.h deleted file mode 100644 index 26dffdcf52726f93a180d92af9a40066191e6976..0000000000000000000000000000000000000000 --- a/FastLED/src/platforms/esp/8266/led_sysdefs_esp8266.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#ifndef ESP8266 -#define ESP8266 -#endif - -#define FASTLED_ESP8266 - -// Use system millis timer -#define FASTLED_HAS_MILLIS - -typedef volatile uint32_t RoReg; -typedef volatile uint32_t RwReg; -typedef uint32_t prog_uint32_t; - - -// Default to NOT using PROGMEM here -#ifndef FASTLED_USE_PROGMEM -# define FASTLED_USE_PROGMEM 0 -#endif - -#ifndef FASTLED_ALLOW_INTERRUPTS -# define FASTLED_ALLOW_INTERRUPTS 1 -# define INTERRUPT_THRESHOLD 0 -#endif - -#define NEED_CXX_BITS - -// These can be overridden -#if !defined(FASTLED_ESP8266_RAW_PIN_ORDER) && !defined(FASTLED_ESP8266_NODEMCU_PIN_ORDER) && !defined(FASTLED_ESP8266_D1_PIN_ORDER) -# ifdef ARDUINO_ESP8266_NODEMCU -# define FASTLED_ESP8266_NODEMCU_PIN_ORDER -# else -# define FASTLED_ESP8266_RAW_PIN_ORDER -# endif -#endif - -// #define cli() os_intr_lock(); -// #define sei() os_intr_lock(); diff --git a/FastLED/src/power_mgt.cpp b/FastLED/src/power_mgt.cpp deleted file mode 100644 index e15fa709b595eafedb32a9d12389649ed45f11bf..0000000000000000000000000000000000000000 --- a/FastLED/src/power_mgt.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#define FASTLED_INTERNAL -#include "FastLED.h" -#include "power_mgt.h" - -FASTLED_NAMESPACE_BEGIN - -//// POWER MANAGEMENT - -// These power usage values are approximate, and your exact readings -// will be slightly (10%?) different from these. -// -// They were arrived at by actually measuing the power draw of a number -// of different LED strips, and a bunch of closed-loop-feedback testing -// to make sure that if we USE these values, we stay at or under -// the target power consumption. -// Actual power consumption is much, much more complicated and has -// to include things like voltage drop, etc., etc. -// However, this is good enough for most cases, and almost certainly better -// than no power management at all. -// -// You're welcome to adjust these values as needed; there may eventually be an API -// for changing these on the fly, but it saves codespace and RAM to have them -// be compile-time constants. - -static const uint8_t gRed_mW = 16 * 5; // 16mA @ 5v = 80mW -static const uint8_t gGreen_mW = 11 * 5; // 11mA @ 5v = 55mW -static const uint8_t gBlue_mW = 15 * 5; // 15mA @ 5v = 75mW -static const uint8_t gDark_mW = 1 * 5; // 1mA @ 5v = 5mW - -// Alternate calibration by RAtkins via pre-PSU wattage measurments; -// these are all probably about 20%-25% too high due to PSU heat losses, -// but if you're measuring wattage on the PSU input side, this may -// be a better set of calibrations. (WS2812B) -// static const uint8_t gRed_mW = 100; -// static const uint8_t gGreen_mW = 48; -// static const uint8_t gBlue_mW = 100; -// static const uint8_t gDark_mW = 12; - - -#define POWER_LED 1 -#define POWER_DEBUG_PRINT 0 - - -// Power consumed by the MCU -static const uint8_t gMCU_mW = 25 * 5; // 25mA @ 5v = 125 mW - -static uint8_t gMaxPowerIndicatorLEDPinNumber = 0; // default = Arduino onboard LED pin. set to zero to skip this. - - -uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds ) //25354 -{ - uint32_t red32 = 0, green32 = 0, blue32 = 0; - const CRGB* firstled = &(ledbuffer[0]); - uint8_t* p = (uint8_t*)(firstled); - - uint16_t count = numLeds; - - // This loop might benefit from an AVR assembly version -MEK - while( count) { - red32 += *p++; - green32 += *p++; - blue32 += *p++; - --count; - } - - red32 *= gRed_mW; - green32 *= gGreen_mW; - blue32 *= gBlue_mW; - - red32 >>= 8; - green32 >>= 8; - blue32 >>= 8; - - uint32_t total = red32 + green32 + blue32 + (gDark_mW * numLeds); - - return total; -} - - -uint8_t calculate_max_brightness_for_power_vmA(const CRGB* ledbuffer, uint16_t numLeds, uint8_t target_brightness, uint32_t max_power_V, uint32_t max_power_mA) { - return calculate_max_brightness_for_power_mW(ledbuffer, numLeds, target_brightness, max_power_V * max_power_mA); -} - -uint8_t calculate_max_brightness_for_power_mW(const CRGB* ledbuffer, uint16_t numLeds, uint8_t target_brightness, uint32_t max_power_mW) { - uint32_t total_mW = calculate_unscaled_power_mW( ledbuffer, numLeds); - - uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256; - - uint8_t recommended_brightness = target_brightness; - if(requested_power_mW > max_power_mW) { - recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW)); - } - - return recommended_brightness; -} - -// sets brightness to -// - no more than target_brightness -// - no more than max_mW milliwatts -uint8_t calculate_max_brightness_for_power_mW( uint8_t target_brightness, uint32_t max_power_mW) -{ - uint32_t total_mW = gMCU_mW; - - CLEDController *pCur = CLEDController::head(); - while(pCur) { - total_mW += calculate_unscaled_power_mW( pCur->leds(), pCur->size()); - pCur = pCur->next(); - } - -#if POWER_DEBUG_PRINT == 1 - Serial.print("power demand at full brightness mW = "); - Serial.println( total_mW); -#endif - - uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256; -#if POWER_DEBUG_PRINT == 1 - if( target_brightness != 255 ) { - Serial.print("power demand at scaled brightness mW = "); - Serial.println( requested_power_mW); - } - Serial.print("power limit mW = "); - Serial.println( max_power_mW); -#endif - - if( requested_power_mW < max_power_mW) { -#if POWER_LED > 0 - if( gMaxPowerIndicatorLEDPinNumber ) { - Pin(gMaxPowerIndicatorLEDPinNumber).lo(); // turn the LED off - } -#endif -#if POWER_DEBUG_PRINT == 1 - Serial.print("demand is under the limit"); -#endif - return target_brightness; - } - - uint8_t recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW)); -#if POWER_DEBUG_PRINT == 1 - Serial.print("recommended brightness # = "); - Serial.println( recommended_brightness); - - uint32_t resultant_power_mW = (total_mW * recommended_brightness) / 256; - Serial.print("resultant power demand mW = "); - Serial.println( resultant_power_mW); - - Serial.println(); -#endif - -#if POWER_LED > 0 - if( gMaxPowerIndicatorLEDPinNumber ) { - Pin(gMaxPowerIndicatorLEDPinNumber).hi(); // turn the LED on - } -#endif - - return recommended_brightness; -} - - -void set_max_power_indicator_LED( uint8_t pinNumber) -{ - gMaxPowerIndicatorLEDPinNumber = pinNumber; -} - -void set_max_power_in_volts_and_milliamps( uint8_t volts, uint32_t milliamps) -{ - FastLED.setMaxPowerInVoltsAndMilliamps(volts, milliamps); -} - -void set_max_power_in_milliwatts( uint32_t powerInmW) -{ - FastLED.setMaxPowerInMilliWatts(powerInmW); -} - -void show_at_max_brightness_for_power() -{ - // power management usage is now in FastLED.show, no need for this function - FastLED.show(); -} - -void delay_at_max_brightness_for_power( uint16_t ms) -{ - FastLED.delay(ms); -} - -FASTLED_NAMESPACE_END diff --git a/FastLED/src/power_mgt.h b/FastLED/src/power_mgt.h deleted file mode 100644 index 687188185962028a6c13af06b50d39b025e1555e..0000000000000000000000000000000000000000 --- a/FastLED/src/power_mgt.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef POWER_MGT_H -#define POWER_MGT_H - -#include "FastLED.h" - -#include "pixeltypes.h" - -FASTLED_NAMESPACE_BEGIN - -///@defgroup Power Power management functions -/// functions used to limit the amount of power used by FastLED -///@{ - -// Power Control setup functions -// -// Example: -// set_max_power_in_volts_and_milliamps( 5, 400); -// - -/// Set the maximum power used in milliamps for a given voltage -/// @deprecated - use FastLED.setMaxPowerInVoltsAndMilliamps() -void set_max_power_in_volts_and_milliamps( uint8_t volts, uint32_t milliamps); -/// Set the maximum power used in watts -/// @deprecated - use FastLED.setMaxPowerInMilliWatts -void set_max_power_in_milliwatts( uint32_t powerInmW); - -/// Select a pin with an led that will be flashed to indicate that power management -/// is pulling down the brightness -void set_max_power_indicator_LED( uint8_t pinNumber); // zero = no indicator LED - - -// Power Control 'show' and 'delay' functions -// -// These are drop-in replacements for FastLED.show() and FastLED.delay() -// In order to use these, you have to actually replace your calls to -// FastLED.show() and FastLED.delay() with these two functions. -// -// Example: -// // was: FastLED.show(); -// // now is: -// show_at_max_brightness_for_power(); -// - -/// Similar to FastLED.show, but pre-adjusts brightness to keep below the power -/// threshold. -/// @deprecated this has now been moved to FastLED.show(); -void show_at_max_brightness_for_power(); -/// Similar to FastLED.delay, but pre-adjusts brightness to keep below the power -/// threshold. -/// @deprecated this has now been rolled into FastLED.delay(); -void delay_at_max_brightness_for_power( uint16_t ms); - - -// Power Control internal helper functions - -/// calculate_unscaled_power_mW tells you how many milliwatts the current -/// LED data would draw at brightness = 255. -/// -uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds); - -/// calculate_max_brightness_for_power_mW tells you the highest brightness -/// level you can use and still stay under the specified power budget for -/// a given set of leds. It takes a pointer to an array of CRGB objects, a -/// count, a 'target brightness' which is the brightness you'd ideally like -/// to use, and the max power draw desired in milliwatts. The result from -/// this function will be no higher than the target_brightess you supply, but may be lower. -uint8_t calculate_max_brightness_for_power_mW(const CRGB* ledbuffer, uint16_t numLeds, uint8_t target_brightness, uint32_t max_power_mW); - -/// calculate_max_brightness_for_power_mW tells you the highest brightness -/// level you can use and still stay under the specified power budget for -/// a given set of leds. It takes a pointer to an array of CRGB objects, a -/// count, a 'target brightness' which is the brightness you'd ideally like -/// to use, and the max power in volts and milliamps. The result from this -/// function will be no higher than the target_brightess you supply, but may be lower. -uint8_t calculate_max_brightness_for_power_vmA(const CRGB* ledbuffer, uint16_t numLeds, uint8_t target_brightness, uint32_t max_power_V, uint32_t max_power_mA); - -/// calculate_max_brightness_for_power_mW tells you the highest brightness -/// level you can use and still stay under the specified power budget. It -/// takes a 'target brightness' which is the brightness you'd ideally like -/// to use. The result from this function will be no higher than the -/// target_brightess you supply, but may be lower. -uint8_t calculate_max_brightness_for_power_mW( uint8_t target_brightness, uint32_t max_power_mW); - -FASTLED_NAMESPACE_END -///@} -// POWER_MGT_H - -#endif diff --git a/FastLED/src/wiring.cpp b/FastLED/src/wiring.cpp deleted file mode 100644 index 744373a172c483b0dc494270850e23176eeca8a9..0000000000000000000000000000000000000000 --- a/FastLED/src/wiring.cpp +++ /dev/null @@ -1,238 +0,0 @@ -#define FASTLED_INTERNAL -#include "FastLED.h" - -FASTLED_USING_NAMESPACE - -#if 0 - -#if defined(FASTLED_AVR) && !defined(TEENSYDUINO) && !defined(LIB8_ATTINY) -extern "C" { -// the prescaler is set so that timer0 ticks every 64 clock cycles, and the -// the overflow handler is called every 256 ticks. -#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) - -typedef union { unsigned long _long; uint8_t raw[4]; } tBytesForLong; -// tBytesForLong FastLED_timer0_overflow_count; -volatile unsigned long FastLED_timer0_overflow_count=0; -volatile unsigned long FastLED_timer0_millis = 0; - -LIB8STATIC void __attribute__((always_inline)) fastinc32 (volatile uint32_t & _long) { - uint8_t b = ++((tBytesForLong&)_long).raw[0]; - if(!b) { - b = ++((tBytesForLong&)_long).raw[1]; - if(!b) { - b = ++((tBytesForLong&)_long).raw[2]; - if(!b) { - ++((tBytesForLong&)_long).raw[3]; - } - } - } -} - -#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) -ISR(TIM0_OVF_vect) -#else -ISR(TIMER0_OVF_vect) -#endif -{ - fastinc32(FastLED_timer0_overflow_count); - // FastLED_timer0_overflow_count++; -} - -// there are 1024 microseconds per overflow counter tick. -unsigned long millis() -{ - unsigned long m; - uint8_t oldSREG = SREG; - - // disable interrupts while we read FastLED_timer0_millis or we might get an - // inconsistent value (e.g. in the middle of a write to FastLED_timer0_millis) - cli(); - m = FastLED_timer0_overflow_count; //._long; - SREG = oldSREG; - - return (m*(MICROSECONDS_PER_TIMER0_OVERFLOW/8))/(1000/8); -} - -unsigned long micros() { - unsigned long m; - uint8_t oldSREG = SREG, t; - - cli(); - m = FastLED_timer0_overflow_count; // ._long; -#if defined(TCNT0) - t = TCNT0; -#elif defined(TCNT0L) - t = TCNT0L; -#else - #error TIMER 0 not defined -#endif - - -#ifdef TIFR0 - if ((TIFR0 & _BV(TOV0)) && (t < 255)) - ++m; -#else - if ((TIFR & _BV(TOV0)) && (t < 255)) - ++m; -#endif - - SREG = oldSREG; - - return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); -} - -void delay(unsigned long ms) -{ - uint16_t start = (uint16_t)micros(); - - while (ms > 0) { - if (((uint16_t)micros() - start) >= 1000) { - --ms; - start += 1000; - } - } -} - -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -void init() -{ - // this needs to be called before setup() or some functions won't - // work there - sei(); - - // on the ATmega168, timer 0 is also used for fast hardware pwm - // (using phase-correct PWM would mean that timer 0 overflowed half as often - // resulting in different millis() behavior on the ATmega8 and ATmega168) -#if defined(TCCR0A) && defined(WGM01) - sbi(TCCR0A, WGM01); - sbi(TCCR0A, WGM00); -#endif - - // set timer 0 prescale factor to 64 -#if defined(__AVR_ATmega128__) - // CPU specific: different values for the ATmega128 - sbi(TCCR0, CS02); -#elif defined(TCCR0) && defined(CS01) && defined(CS00) - // this combination is for the standard atmega8 - sbi(TCCR0, CS01); - sbi(TCCR0, CS00); -#elif defined(TCCR0B) && defined(CS01) && defined(CS00) - // this combination is for the standard 168/328/1280/2560 - sbi(TCCR0B, CS01); - sbi(TCCR0B, CS00); -#elif defined(TCCR0A) && defined(CS01) && defined(CS00) - // this combination is for the __AVR_ATmega645__ series - sbi(TCCR0A, CS01); - sbi(TCCR0A, CS00); -#else - #error Timer 0 prescale factor 64 not set correctly -#endif - - // enable timer 0 overflow interrupt -#if defined(TIMSK) && defined(TOIE0) - sbi(TIMSK, TOIE0); -#elif defined(TIMSK0) && defined(TOIE0) - sbi(TIMSK0, TOIE0); -#else - #error Timer 0 overflow interrupt not set correctly -#endif - - // timers 1 and 2 are used for phase-correct hardware pwm - // this is better for motors as it ensures an even waveform - // note, however, that fast pwm mode can achieve a frequency of up - // 8 MHz (with a 16 MHz clock) at 50% duty cycle - -#if defined(TCCR1B) && defined(CS11) && defined(CS10) - TCCR1B = 0; - - // set timer 1 prescale factor to 64 - sbi(TCCR1B, CS11); -#if F_CPU >= 8000000L - sbi(TCCR1B, CS10); -#endif -#elif defined(TCCR1) && defined(CS11) && defined(CS10) - sbi(TCCR1, CS11); -#if F_CPU >= 8000000L - sbi(TCCR1, CS10); -#endif -#endif - // put timer 1 in 8-bit phase correct pwm mode -#if defined(TCCR1A) && defined(WGM10) - sbi(TCCR1A, WGM10); -#elif defined(TCCR1) - #warning this needs to be finished -#endif - - // set timer 2 prescale factor to 64 -#if defined(TCCR2) && defined(CS22) - sbi(TCCR2, CS22); -#elif defined(TCCR2B) && defined(CS22) - sbi(TCCR2B, CS22); -#else - #warning Timer 2 not finished (may not be present on this CPU) -#endif - - // configure timer 2 for phase correct pwm (8-bit) -#if defined(TCCR2) && defined(WGM20) - sbi(TCCR2, WGM20); -#elif defined(TCCR2A) && defined(WGM20) - sbi(TCCR2A, WGM20); -#else - #warning Timer 2 not finished (may not be present on this CPU) -#endif - -#if defined(TCCR3B) && defined(CS31) && defined(WGM30) - sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 - sbi(TCCR3B, CS30); - sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode -#endif - -#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ - sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 - sbi(TCCR4B, CS41); - sbi(TCCR4B, CS40); - sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode - sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A - sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D -#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ -#if defined(TCCR4B) && defined(CS41) && defined(WGM40) - sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 - sbi(TCCR4B, CS40); - sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode -#endif -#endif /* end timer4 block for ATMEGA1280/2560 and similar */ - -#if defined(TCCR5B) && defined(CS51) && defined(WGM50) - sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 - sbi(TCCR5B, CS50); - sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode -#endif - -#if defined(ADCSRA) - // set a2d prescale factor to 128 - // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. - // XXX: this will not work properly for other clock speeds, and - // this code should use F_CPU to determine the prescale factor. - sbi(ADCSRA, ADPS2); - sbi(ADCSRA, ADPS1); - sbi(ADCSRA, ADPS0); - - // enable a2d conversions - sbi(ADCSRA, ADEN); -#endif - - // the bootloader connects pins 0 and 1 to the USART; disconnect them - // here so they can be used as normal digital i/o; they will be - // reconnected in Serial.begin() -#if defined(UCSRB) - UCSRB = 0; -#elif defined(UCSR0B) - UCSR0B = 0; -#endif -} -}; -#endif - -#endif - diff --git a/I2Cdev/I2Cdev.cpp b/I2Cdev/I2Cdev.cpp deleted file mode 100644 index c81f6b94adeb6e61905203149cdae96a9f14f1af..0000000000000000000000000000000000000000 --- a/I2Cdev/I2Cdev.cpp +++ /dev/null @@ -1,1457 +0,0 @@ -// I2Cdev library collection - Main I2C device class -// Abstracts bit and byte I2C R/W functions into a convenient class -// 6/9/2012 by Jeff Rowberg <jeff@rowberg.net> -// -// Changelog: -// 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications -// 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan) -// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire -// - add compiler warnings when using outdated or IDE or limited I2Cdev implementation -// 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums) -// 2011-10-03 - added automatic Arduino version detection for ease of use -// 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications -// 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x) -// 2011-08-03 - added optional timeout parameter to read* methods to easily change from default -// 2011-08-02 - added support for 16-bit registers -// - fixed incorrect Doxygen comments on some methods -// - added timeout value for read operations (thanks mem @ Arduino forums) -// 2011-07-30 - changed read/write function structures to return success or byte counts -// - made all methods static for multi-device memory savings -// 2011-07-28 - initial release - -/* ============================================ - I2Cdev device library code is placed under the MIT license - Copyright (c) 2013 Jeff Rowberg - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - =============================================== -*/ - -#include "./I2Cdev.h" - -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - -#ifdef I2CDEV_IMPLEMENTATION_WARNINGS -#if ARDUINO < 100 -#warning Using outdated Arduino IDE with Wire library is functionally limiting. -#warning Arduino IDE v1.0.1+ with I2Cdev Fastwire implementation is recommended. -#warning This I2Cdev implementation does not support: -#warning - Repeated starts conditions -#warning - Timeout detection (some Wire requests block forever) -#elif ARDUINO == 100 -#warning Using outdated Arduino IDE with Wire library is functionally limiting. -#warning Arduino IDE v1.0.1+ with I2Cdev Fastwire implementation is recommended. -#warning This I2Cdev implementation does not support: -#warning - Repeated starts conditions -#warning - Timeout detection (some Wire requests block forever) -#elif ARDUINO > 100 -#warning Using current Arduino IDE with Wire library is functionally limiting. -#warning Arduino IDE v1.0.1+ with I2CDEV_BUILTIN_FASTWIRE implementation is recommended. -#warning This I2Cdev implementation does not support: -#warning - Timeout detection (some Wire requests block forever) -#endif -#endif - -#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE - -//#error The I2CDEV_BUILTIN_FASTWIRE implementation is known to be broken right now. Patience, Iago! - -#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE - -#ifdef I2CDEV_IMPLEMENTATION_WARNINGS -#warning Using I2CDEV_BUILTIN_NBWIRE implementation may adversely affect interrupt detection. -#warning This I2Cdev implementation does not support: -#warning - Repeated starts conditions -#endif - -// NBWire implementation based heavily on code by Gene Knight <Gene@Telobot.com> -// Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html -// Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html -TwoWire Wire; - -#endif - -/** Default constructor. -*/ -I2Cdev::I2Cdev() { -} - -/** Read a single bit from an 8-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to read from - @param bitNum Bit position to read (0-7) - @param data Container for single bit value - @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - @return Status of read operation (true = success) -*/ -int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) { - uint8_t b; - uint8_t count = readByte(devAddr, regAddr, &b, timeout); - *data = b & (1 << bitNum); - return count; -} - -/** Read a single bit from a 16-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to read from - @param bitNum Bit position to read (0-15) - @param data Container for single bit value - @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - @return Status of read operation (true = success) -*/ -int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) { - uint16_t b; - uint8_t count = readWord(devAddr, regAddr, &b, timeout); - *data = b & (1 << bitNum); - return count; -} - -/** Read multiple bits from an 8-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to read from - @param bitStart First bit position to read (0-7) - @param length Number of bits to read (not more than 8) - @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) - @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - @return Status of read operation (true = success) -*/ -int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) { - // 01101001 read byte - // 76543210 bit numbers - // xxx args: bitStart=4, length=3 - // 010 masked - // -> 010 shifted - uint8_t count, b; - if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) { - uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); - b &= mask; - b >>= (bitStart - length + 1); - *data = b; - } - return count; -} - -/** Read multiple bits from a 16-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to read from - @param bitStart First bit position to read (0-15) - @param length Number of bits to read (not more than 16) - @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) - @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - @return Status of read operation (1 = success, 0 = failure, -1 = timeout) -*/ -int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) { - // 1101011001101001 read byte - // fedcba9876543210 bit numbers - // xxx args: bitStart=12, length=3 - // 010 masked - // -> 010 shifted - uint8_t count; - uint16_t w; - if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) { - uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); - w &= mask; - w >>= (bitStart - length + 1); - *data = w; - } - return count; -} - -/** Read single byte from an 8-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to read from - @param data Container for byte value read from device - @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - @return Status of read operation (true = success) -*/ -int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) { - return readBytes(devAddr, regAddr, 1, data, timeout); -} - -/** Read single word from a 16-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to read from - @param data Container for word value read from device - @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - @return Status of read operation (true = success) -*/ -int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) { - return readWords(devAddr, regAddr, 1, data, timeout); -} - -/** Read multiple bytes from an 8-bit device register. - @param devAddr I2C slave device address - @param regAddr First register regAddr to read from - @param length Number of bytes to read - @param data Buffer to store read data in - @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - @return Number of bytes read (-1 indicates failure) -*/ -int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) { -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print("I2C (0x"); - Serial.print(devAddr, HEX); - Serial.print(") reading "); - Serial.print(length, DEC); - Serial.print(" bytes from 0x"); - Serial.print(regAddr, HEX); - Serial.print("..."); -#endif - - int8_t count = 0; - uint32_t t1 = millis(); - -#if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE) - -#if (ARDUINO < 100) - // Arduino v00xx (before v1.0), Wire library - - // I2C/TWI subsystem uses internal buffer that breaks with large data requests - // so if user requests more than BUFFER_LENGTH bytes, we have to do it in - // smaller chunks instead of all at once - for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) { - Wire.beginTransmission(devAddr); - Wire.send(regAddr); - Wire.endTransmission(); - Wire.beginTransmission(devAddr); - Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH)); - - for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) { - data[count] = Wire.receive(); -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(data[count], HEX); - if (count + 1 < length) Serial.print(" "); -#endif - } - - Wire.endTransmission(); - } -#elif (ARDUINO == 100) - // Arduino v1.0.0, Wire library - // Adds standardized write() and read() stream methods instead of send() and receive() - - // I2C/TWI subsystem uses internal buffer that breaks with large data requests - // so if user requests more than BUFFER_LENGTH bytes, we have to do it in - // smaller chunks instead of all at once - for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) { - Wire.beginTransmission(devAddr); - Wire.write(regAddr); - Wire.endTransmission(); - Wire.beginTransmission(devAddr); - Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH)); - - for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) { - data[count] = Wire.read(); -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(data[count], HEX); - if (count + 1 < length) Serial.print(" "); -#endif - } - - Wire.endTransmission(); - } -#elif (ARDUINO > 100) - // Arduino v1.0.1+, Wire library - // Adds official support for repeated start condition, yay! - - // I2C/TWI subsystem uses internal buffer that breaks with large data requests - // so if user requests more than BUFFER_LENGTH bytes, we have to do it in - // smaller chunks instead of all at once - for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) { - Wire.beginTransmission(devAddr); - Wire.write(regAddr); - Wire.endTransmission(); - Wire.beginTransmission(devAddr); - Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH)); - - for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) { - data[count] = Wire.read(); -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(data[count], HEX); - if (count + 1 < length) Serial.print(" "); -#endif - } - } -#endif - -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) - - // Fastwire library - // no loop required for fastwire - uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, data, length); - if (status == 0) { - count = length; // success - } else { - count = -1; // error - } - -#endif - - // check for timeout - if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout - -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(". Done ("); - Serial.print(count, DEC); - Serial.println(" read)."); -#endif - - return count; -} - -/** Read multiple words from a 16-bit device register. - @param devAddr I2C slave device address - @param regAddr First register regAddr to read from - @param length Number of words to read - @param data Buffer to store read data in - @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - @return Number of words read (-1 indicates failure) -*/ -int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) { -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print("I2C (0x"); - Serial.print(devAddr, HEX); - Serial.print(") reading "); - Serial.print(length, DEC); - Serial.print(" words from 0x"); - Serial.print(regAddr, HEX); - Serial.print("..."); -#endif - - int8_t count = 0; - uint32_t t1 = millis(); - -#if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE) - -#if (ARDUINO < 100) - // Arduino v00xx (before v1.0), Wire library - - // I2C/TWI subsystem uses internal buffer that breaks with large data requests - // so if user requests more than BUFFER_LENGTH bytes, we have to do it in - // smaller chunks instead of all at once - for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) { - Wire.beginTransmission(devAddr); - Wire.send(regAddr); - Wire.endTransmission(); - Wire.beginTransmission(devAddr); - Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes - - bool msb = true; // starts with MSB, then LSB - for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { - if (msb) { - // first byte is bits 15-8 (MSb=15) - data[count] = Wire.receive() << 8; - } else { - // second byte is bits 7-0 (LSb=0) - data[count] |= Wire.receive(); -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(data[count], HEX); - if (count + 1 < length) Serial.print(" "); -#endif - count++; - } - msb = !msb; - } - - Wire.endTransmission(); - } -#elif (ARDUINO == 100) - // Arduino v1.0.0, Wire library - // Adds standardized write() and read() stream methods instead of send() and receive() - - // I2C/TWI subsystem uses internal buffer that breaks with large data requests - // so if user requests more than BUFFER_LENGTH bytes, we have to do it in - // smaller chunks instead of all at once - for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) { - Wire.beginTransmission(devAddr); - Wire.write(regAddr); - Wire.endTransmission(); - Wire.beginTransmission(devAddr); - Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes - - bool msb = true; // starts with MSB, then LSB - for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { - if (msb) { - // first byte is bits 15-8 (MSb=15) - data[count] = Wire.read() << 8; - } else { - // second byte is bits 7-0 (LSb=0) - data[count] |= Wire.read(); -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(data[count], HEX); - if (count + 1 < length) Serial.print(" "); -#endif - count++; - } - msb = !msb; - } - - Wire.endTransmission(); - } -#elif (ARDUINO > 100) - // Arduino v1.0.1+, Wire library - // Adds official support for repeated start condition, yay! - - // I2C/TWI subsystem uses internal buffer that breaks with large data requests - // so if user requests more than BUFFER_LENGTH bytes, we have to do it in - // smaller chunks instead of all at once - for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) { - Wire.beginTransmission(devAddr); - Wire.write(regAddr); - Wire.endTransmission(); - Wire.beginTransmission(devAddr); - Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes - - bool msb = true; // starts with MSB, then LSB - for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { - if (msb) { - // first byte is bits 15-8 (MSb=15) - data[count] = Wire.read() << 8; - } else { - // second byte is bits 7-0 (LSb=0) - data[count] |= Wire.read(); -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(data[count], HEX); - if (count + 1 < length) Serial.print(" "); -#endif - count++; - } - msb = !msb; - } - - Wire.endTransmission(); - } -#endif - -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) - - // Fastwire library - // no loop required for fastwire - uint16_t intermediate[(uint8_t)length]; - uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, (uint8_t *)intermediate, (uint8_t)(length * 2)); - if (status == 0) { - count = length; // success - for (uint8_t i = 0; i < length; i++) { - data[i] = (intermediate[2 * i] << 8) | intermediate[2 * i + 1]; - } - } else { - count = -1; // error - } - -#endif - - if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout - -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(". Done ("); - Serial.print(count, DEC); - Serial.println(" read)."); -#endif - - return count; -} - -/** write a single bit in an 8-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to write to - @param bitNum Bit position to write (0-7) - @param value New bit value to write - @return Status of operation (true = success) -*/ -bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) { - uint8_t b; - readByte(devAddr, regAddr, &b); - b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum)); - return writeByte(devAddr, regAddr, b); -} - -/** write a single bit in a 16-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to write to - @param bitNum Bit position to write (0-15) - @param value New bit value to write - @return Status of operation (true = success) -*/ -bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) { - uint16_t w; - readWord(devAddr, regAddr, &w); - w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum)); - return writeWord(devAddr, regAddr, w); -} - -/** Write multiple bits in an 8-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to write to - @param bitStart First bit position to write (0-7) - @param length Number of bits to write (not more than 8) - @param data Right-aligned value to write - @return Status of operation (true = success) -*/ -bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) { - // 010 value to write - // 76543210 bit numbers - // xxx args: bitStart=4, length=3 - // 00011100 mask byte - // 10101111 original value (sample) - // 10100011 original & ~mask - // 10101011 masked | value - uint8_t b; - if (readByte(devAddr, regAddr, &b) != 0) { - uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); - data <<= (bitStart - length + 1); // shift data into correct position - data &= mask; // zero all non-important bits in data - b &= ~(mask); // zero all important bits in existing byte - b |= data; // combine data with existing byte - return writeByte(devAddr, regAddr, b); - } else { - return false; - } -} - -/** Write multiple bits in a 16-bit device register. - @param devAddr I2C slave device address - @param regAddr Register regAddr to write to - @param bitStart First bit position to write (0-15) - @param length Number of bits to write (not more than 16) - @param data Right-aligned value to write - @return Status of operation (true = success) -*/ -bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) { - // 010 value to write - // fedcba9876543210 bit numbers - // xxx args: bitStart=12, length=3 - // 0001110000000000 mask word - // 1010111110010110 original value (sample) - // 1010001110010110 original & ~mask - // 1010101110010110 masked | value - uint16_t w; - if (readWord(devAddr, regAddr, &w) != 0) { - uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); - data <<= (bitStart - length + 1); // shift data into correct position - data &= mask; // zero all non-important bits in data - w &= ~(mask); // zero all important bits in existing word - w |= data; // combine data with existing word - return writeWord(devAddr, regAddr, w); - } else { - return false; - } -} - -/** Write single byte to an 8-bit device register. - @param devAddr I2C slave device address - @param regAddr Register address to write to - @param data New byte value to write - @return Status of operation (true = success) -*/ -bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) { - return writeBytes(devAddr, regAddr, 1, &data); -} - -/** Write single word to a 16-bit device register. - @param devAddr I2C slave device address - @param regAddr Register address to write to - @param data New word value to write - @return Status of operation (true = success) -*/ -bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) { - return writeWords(devAddr, regAddr, 1, &data); -} - -/** Write multiple bytes to an 8-bit device register. - @param devAddr I2C slave device address - @param regAddr First register address to write to - @param length Number of bytes to write - @param data Buffer to copy new data from - @return Status of operation (true = success) -*/ -bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) { -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print("I2C (0x"); - Serial.print(devAddr, HEX); - Serial.print(") writing "); - Serial.print(length, DEC); - Serial.print(" bytes to 0x"); - Serial.print(regAddr, HEX); - Serial.print("..."); -#endif - uint8_t status = 0; -#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) - Wire.beginTransmission(devAddr); - Wire.send((uint8_t) regAddr); // send address -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) - Wire.beginTransmission(devAddr); - Wire.write((uint8_t) regAddr); // send address -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) - Fastwire::beginTransmission(devAddr); - Fastwire::write(regAddr); -#endif - for (uint8_t i = 0; i < length; i++) { -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(data[i], HEX); - if (i + 1 < length) Serial.print(" "); -#endif -#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) - Wire.send((uint8_t) data[i]); -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) - Wire.write((uint8_t) data[i]); -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) - Fastwire::write((uint8_t) data[i]); -#endif - } -#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) - Wire.endTransmission(); -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) - status = Wire.endTransmission(); -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) - Fastwire::stop(); - //status = Fastwire::endTransmission(); -#endif -#ifdef I2CDEV_SERIAL_DEBUG - Serial.println(". Done."); -#endif - return status == 0; -} - -/** Write multiple words to a 16-bit device register. - @param devAddr I2C slave device address - @param regAddr First register address to write to - @param length Number of words to write - @param data Buffer to copy new data from - @return Status of operation (true = success) -*/ -bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data) { -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print("I2C (0x"); - Serial.print(devAddr, HEX); - Serial.print(") writing "); - Serial.print(length, DEC); - Serial.print(" words to 0x"); - Serial.print(regAddr, HEX); - Serial.print("..."); -#endif - uint8_t status = 0; -#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) - Wire.beginTransmission(devAddr); - Wire.send(regAddr); // send address -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) - Wire.beginTransmission(devAddr); - Wire.write(regAddr); // send address -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) - Fastwire::beginTransmission(devAddr); - Fastwire::write(regAddr); -#endif - for (uint8_t i = 0; i < length * 2; i++) { -#ifdef I2CDEV_SERIAL_DEBUG - Serial.print(data[i], HEX); - if (i + 1 < length) Serial.print(" "); -#endif -#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) - Wire.send((uint8_t)(data[i] >> 8)); // send MSB - Wire.send((uint8_t)data[i++]); // send LSB -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) - Wire.write((uint8_t)(data[i] >> 8)); // send MSB - Wire.write((uint8_t)data[i++]); // send LSB -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) - Fastwire::write((uint8_t)(data[i] >> 8)); // send MSB - status = Fastwire::write((uint8_t)data[i++]); // send LSB - if (status != 0) break; -#endif - } -#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) - Wire.endTransmission(); -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) - status = Wire.endTransmission(); -#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) - Fastwire::stop(); - //status = Fastwire::endTransmission(); -#endif -#ifdef I2CDEV_SERIAL_DEBUG - Serial.println(". Done."); -#endif - return status == 0; -} - -/** Default timeout value for read operations. - Set this to 0 to disable timeout detection. -*/ -uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT; - -#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE -// I2C library -////////////////////// -// Copyright(C) 2012 -// Francesco Ferrara -// ferrara[at]libero[point]it -////////////////////// - -/* - FastWire - - 0.24 added stop - - 0.23 added reset - - This is a library to help faster programs to read I2C devices. - Copyright(C) 2012 Francesco Ferrara - occhiobello at gmail dot com - [used by Jeff Rowberg for I2Cdevlib with permission] -*/ - -boolean Fastwire::waitInt() { - int l = 250; - while (!(TWCR & (1 << TWINT)) && l-- > 0); - return l > 0; -} - -void Fastwire::setup(int khz, boolean pullup) { - TWCR = 0; -#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) - // activate internal pull-ups for twi (PORTC bits 4 & 5) - // as per note from atmega8 manual pg167 - if (pullup) PORTC |= ((1 << 4) | (1 << 5)); - else PORTC &= ~((1 << 4) | (1 << 5)); -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) - // activate internal pull-ups for twi (PORTC bits 0 & 1) - if (pullup) PORTC |= ((1 << 0) | (1 << 1)); - else PORTC &= ~((1 << 0) | (1 << 1)); -#else - // activate internal pull-ups for twi (PORTD bits 0 & 1) - // as per note from atmega128 manual pg204 - if (pullup) PORTD |= ((1 << 0) | (1 << 1)); - else PORTD &= ~((1 << 0) | (1 << 1)); -#endif - - TWSR = 0; // no prescaler => prescaler = 1 - TWBR = ((16000L / khz) - 16) / 2; // change the I2C clock rate - TWCR = 1 << TWEN; // enable twi module, no interrupt -} - -// added by Jeff Rowberg 2013-05-07: -// Arduino Wire-style "beginTransmission" function -// (takes 7-bit device address like the Wire method, NOT 8-bit: 0x68, not 0xD0/0xD1) -byte Fastwire::beginTransmission(byte device) { - byte twst, retry; - retry = 2; - do { - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); - if (!waitInt()) return 1; - twst = TWSR & 0xF8; - if (twst != TW_START && twst != TW_REP_START) return 2; - - //Serial.print(device, HEX); - //Serial.print(" "); - TWDR = device << 1; // send device address without read bit (1) - TWCR = (1 << TWINT) | (1 << TWEN); - if (!waitInt()) return 3; - twst = TWSR & 0xF8; - } while (twst == TW_MT_SLA_NACK && retry-- > 0); - if (twst != TW_MT_SLA_ACK) return 4; - return 0; -} - -byte Fastwire::writeBuf(byte device, byte address, byte *data, byte num) { - byte twst, retry; - - retry = 2; - do { - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); - if (!waitInt()) return 1; - twst = TWSR & 0xF8; - if (twst != TW_START && twst != TW_REP_START) return 2; - - //Serial.print(device, HEX); - //Serial.print(" "); - TWDR = device & 0xFE; // send device address without read bit (1) - TWCR = (1 << TWINT) | (1 << TWEN); - if (!waitInt()) return 3; - twst = TWSR & 0xF8; - } while (twst == TW_MT_SLA_NACK && retry-- > 0); - if (twst != TW_MT_SLA_ACK) return 4; - - //Serial.print(address, HEX); - //Serial.print(" "); - TWDR = address; // send data to the previously addressed device - TWCR = (1 << TWINT) | (1 << TWEN); - if (!waitInt()) return 5; - twst = TWSR & 0xF8; - if (twst != TW_MT_DATA_ACK) return 6; - - for (byte i = 0; i < num; i++) { - //Serial.print(data[i], HEX); - //Serial.print(" "); - TWDR = data[i]; // send data to the previously addressed device - TWCR = (1 << TWINT) | (1 << TWEN); - if (!waitInt()) return 7; - twst = TWSR & 0xF8; - if (twst != TW_MT_DATA_ACK) return 8; - } - //Serial.print("\n"); - - return 0; -} - -byte Fastwire::write(byte value) { - byte twst; - //Serial.println(value, HEX); - TWDR = value; // send data - TWCR = (1 << TWINT) | (1 << TWEN); - if (!waitInt()) return 1; - twst = TWSR & 0xF8; - if (twst != TW_MT_DATA_ACK) return 2; - return 0; -} - -byte Fastwire::readBuf(byte device, byte address, byte *data, byte num) { - byte twst, retry; - - retry = 2; - do { - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); - if (!waitInt()) return 16; - twst = TWSR & 0xF8; - if (twst != TW_START && twst != TW_REP_START) return 17; - - //Serial.print(device, HEX); - //Serial.print(" "); - TWDR = device & 0xfe; // send device address to write - TWCR = (1 << TWINT) | (1 << TWEN); - if (!waitInt()) return 18; - twst = TWSR & 0xF8; - } while (twst == TW_MT_SLA_NACK && retry-- > 0); - if (twst != TW_MT_SLA_ACK) return 19; - - //Serial.print(address, HEX); - //Serial.print(" "); - TWDR = address; // send data to the previously addressed device - TWCR = (1 << TWINT) | (1 << TWEN); - if (!waitInt()) return 20; - twst = TWSR & 0xF8; - if (twst != TW_MT_DATA_ACK) return 21; - - /***/ - - retry = 2; - do { - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); - if (!waitInt()) return 22; - twst = TWSR & 0xF8; - if (twst != TW_START && twst != TW_REP_START) return 23; - - //Serial.print(device, HEX); - //Serial.print(" "); - TWDR = device | 0x01; // send device address with the read bit (1) - TWCR = (1 << TWINT) | (1 << TWEN); - if (!waitInt()) return 24; - twst = TWSR & 0xF8; - } while (twst == TW_MR_SLA_NACK && retry-- > 0); - if (twst != TW_MR_SLA_ACK) return 25; - - for (uint8_t i = 0; i < num; i++) { - if (i == num - 1) - TWCR = (1 << TWINT) | (1 << TWEN); - else - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); - if (!waitInt()) return 26; - twst = TWSR & 0xF8; - if (twst != TW_MR_DATA_ACK && twst != TW_MR_DATA_NACK) return twst; - data[i] = TWDR; - //Serial.print(data[i], HEX); - //Serial.print(" "); - } - //Serial.print("\n"); - stop(); - - return 0; -} - -void Fastwire::reset() { - TWCR = 0; -} - -byte Fastwire::stop() { - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); - if (!waitInt()) return 1; - return 0; -} -#endif - -#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE -// NBWire implementation based heavily on code by Gene Knight <Gene@Telobot.com> -// Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html -// Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html - -/* - call this version 1.0 - - Offhand, the only funky part that I can think of is in nbrequestFrom, where the buffer - length and index are set *before* the data is actually read. The problem is that these - are variables local to the TwoWire object, and by the time we actually have read the - data, and know what the length actually is, we have no simple access to the object's - variables. The actual bytes read *is* given to the callback function, though. - - The ISR code for a slave receiver is commented out. I don't have that setup, and can't - verify it at this time. Save it for 2.0! - - The handling of the read and write processes here is much like in the demo sketch code: - the process is broken down into sequential functions, where each registers the next as a - callback, essentially. - - For example, for the Read process, twi_read00 just returns if TWI is not yet in a - ready state. When there's another interrupt, and the interface *is* ready, then it - sets up the read, starts it, and registers twi_read01 as the function to call after - the *next* interrupt. twi_read01, then, just returns if the interface is still in a - "reading" state. When the reading is done, it copies the information to the buffer, - cleans up, and calls the user-requested callback function with the actual number of - bytes read. - - The writing is similar. - - Questions, comments and problems can go to Gene@Telobot.com. - - Thumbs Up! - Gene Knight - -*/ - -uint8_t TwoWire::rxBuffer[NBWIRE_BUFFER_LENGTH]; -uint8_t TwoWire::rxBufferIndex = 0; -uint8_t TwoWire::rxBufferLength = 0; - -uint8_t TwoWire::txAddress = 0; -uint8_t TwoWire::txBuffer[NBWIRE_BUFFER_LENGTH]; -uint8_t TwoWire::txBufferIndex = 0; -uint8_t TwoWire::txBufferLength = 0; - -//uint8_t TwoWire::transmitting = 0; -void (*TwoWire::user_onRequest)(void); -void (*TwoWire::user_onReceive)(int); - -static volatile uint8_t twi_transmitting; -static volatile uint8_t twi_state; -static uint8_t twi_slarw; -static volatile uint8_t twi_error; -static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_masterBufferIndex; -static uint8_t twi_masterBufferLength; -static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_rxBufferIndex; -//static volatile uint8_t twi_Interrupt_Continue_Command; -static volatile uint8_t twi_Return_Value; -static volatile uint8_t twi_Done; -void (*twi_cbendTransmissionDone)(int); -void (*twi_cbreadFromDone)(int); - -void twi_init() { - // initialize state - twi_state = TWI_READY; - - // activate internal pull-ups for twi - // as per note from atmega8 manual pg167 - sbi(PORTC, 4); - sbi(PORTC, 5); - - // initialize twi prescaler and bit rate - cbi(TWSR, TWPS0); // TWI Status Register - Prescaler bits - cbi(TWSR, TWPS1); - - /* twi bit rate formula from atmega128 manual pg 204 - SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) - note: TWBR should be 10 or higher for master mode - It is 72 for a 16mhz Wiring board with 100kHz TWI */ - - TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; // bitrate register - // enable twi module, acks, and twi interrupt - - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); - - /* TWEN - TWI Enable Bit - TWIE - TWI Interrupt Enable - TWEA - TWI Enable Acknowledge Bit - TWINT - TWI Interrupt Flag - TWSTA - TWI Start Condition - */ -} - -typedef struct { - uint8_t address; - uint8_t* data; - uint8_t length; - uint8_t wait; - uint8_t i; -} twi_Write_Vars; - -twi_Write_Vars *ptwv = 0; -static void (*fNextInterruptFunction)(void) = 0; - -void twi_Finish(byte bRetVal) { - if (ptwv) { - free(ptwv); - ptwv = 0; - } - twi_Done = 0xFF; - twi_Return_Value = bRetVal; - fNextInterruptFunction = 0; -} - -uint8_t twii_WaitForDone(uint16_t timeout) { - uint32_t endMillis = millis() + timeout; - while (!twi_Done && (timeout == 0 || millis() < endMillis)) continue; - return twi_Return_Value; -} - -void twii_SetState(uint8_t ucState) { - twi_state = ucState; -} - -void twii_SetError(uint8_t ucError) { - twi_error = ucError ; -} - -void twii_InitBuffer(uint8_t ucPos, uint8_t ucLength) { - twi_masterBufferIndex = 0; - twi_masterBufferLength = ucLength; -} - -void twii_CopyToBuf(uint8_t* pData, uint8_t ucLength) { - uint8_t i; - for (i = 0; i < ucLength; ++i) { - twi_masterBuffer[i] = pData[i]; - } -} - -void twii_CopyFromBuf(uint8_t *pData, uint8_t ucLength) { - uint8_t i; - for (i = 0; i < ucLength; ++i) { - pData[i] = twi_masterBuffer[i]; - } -} - -void twii_SetSlaRW(uint8_t ucSlaRW) { - twi_slarw = ucSlaRW; -} - -void twii_SetStart() { - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); -} - -void twi_write01() { - if (TWI_MTX == twi_state) return; // blocking test - twi_transmitting = 0 ; - if (twi_error == 0xFF) - twi_Finish (0); // success - else if (twi_error == TW_MT_SLA_NACK) - twi_Finish (2); // error: address send, nack received - else if (twi_error == TW_MT_DATA_NACK) - twi_Finish (3); // error: data send, nack received - else - twi_Finish (4); // other twi error - if (twi_cbendTransmissionDone) return twi_cbendTransmissionDone(twi_Return_Value); - return; -} - - -void twi_write00() { - if (TWI_READY != twi_state) return; // blocking test - if (TWI_BUFFER_LENGTH < ptwv -> length) { - twi_Finish(1); // end write with error 1 - return; - } - twi_Done = 0x00; // show as working - twii_SetState(TWI_MTX); // to transmitting - twii_SetError(0xFF); // to No Error - twii_InitBuffer(0, ptwv -> length); // pointer and length - twii_CopyToBuf(ptwv -> data, ptwv -> length); // get the data - twii_SetSlaRW((ptwv -> address << 1) | TW_WRITE); // write command - twii_SetStart(); // start the cycle - fNextInterruptFunction = twi_write01; // next routine - return twi_write01(); -} - -void twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) { - uint8_t i; - ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars)); - ptwv -> address = address; - ptwv -> data = data; - ptwv -> length = length; - ptwv -> wait = wait; - fNextInterruptFunction = twi_write00; - return twi_write00(); -} - -void twi_read01() { - if (TWI_MRX == twi_state) return; // blocking test - if (twi_masterBufferIndex < ptwv -> length) ptwv -> length = twi_masterBufferIndex; - twii_CopyFromBuf(ptwv -> data, ptwv -> length); - twi_Finish(ptwv -> length); - if (twi_cbreadFromDone) return twi_cbreadFromDone(twi_Return_Value); - return; -} - -void twi_read00() { - if (TWI_READY != twi_state) return; // blocking test - if (TWI_BUFFER_LENGTH < ptwv -> length) twi_Finish(0); // error return - twi_Done = 0x00; // show as working - twii_SetState(TWI_MRX); // reading - twii_SetError(0xFF); // reset error - twii_InitBuffer(0, ptwv -> length - 1); // init to one less than length - twii_SetSlaRW((ptwv -> address << 1) | TW_READ); // read command - twii_SetStart(); // start cycle - fNextInterruptFunction = twi_read01; - return twi_read01(); -} - -void twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) { - uint8_t i; - - ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars)); - ptwv -> address = address; - ptwv -> data = data; - ptwv -> length = length; - fNextInterruptFunction = twi_read00; - return twi_read00(); -} - -void twi_reply(uint8_t ack) { - // transmit master read ready signal, with or without ack - if (ack) { - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); - } else { - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); - } -} - -void twi_stop(void) { - // send stop condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); - - // wait for stop condition to be exectued on bus - // TWINT is not set after a stop condition! - while (TWCR & _BV(TWSTO)) { - continue; - } - - // update twi state - twi_state = TWI_READY; -} - -void twi_releaseBus(void) { - // release bus - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); - - // update twi state - twi_state = TWI_READY; -} - -SIGNAL(TWI_vect) { - switch (TW_STATUS) { - // All Master - case TW_START: // sent start condition - case TW_REP_START: // sent repeated start condition - // copy device address and r/w bit to output register and ack - TWDR = twi_slarw; - twi_reply(1); - break; - - // Master Transmitter - case TW_MT_SLA_ACK: // slave receiver acked address - case TW_MT_DATA_ACK: // slave receiver acked data - // if there is data to send, send it, otherwise stop - if (twi_masterBufferIndex < twi_masterBufferLength) { - // copy data to output register and ack - TWDR = twi_masterBuffer[twi_masterBufferIndex++]; - twi_reply(1); - } else { - twi_stop(); - } - break; - - case TW_MT_SLA_NACK: // address sent, nack received - twi_error = TW_MT_SLA_NACK; - twi_stop(); - break; - - case TW_MT_DATA_NACK: // data sent, nack received - twi_error = TW_MT_DATA_NACK; - twi_stop(); - break; - - case TW_MT_ARB_LOST: // lost bus arbitration - twi_error = TW_MT_ARB_LOST; - twi_releaseBus(); - break; - - // Master Receiver - case TW_MR_DATA_ACK: // data received, ack sent - // put byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - - case TW_MR_SLA_ACK: // address sent, ack received - // ack if more bytes are expected, otherwise nack - if (twi_masterBufferIndex < twi_masterBufferLength) { - twi_reply(1); - } else { - twi_reply(0); - } - break; - - case TW_MR_DATA_NACK: // data received, nack sent - // put final byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - - case TW_MR_SLA_NACK: // address sent, nack received - twi_stop(); - break; - - // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case - - // Slave Receiver (NOT IMPLEMENTED YET) - /* - case TW_SR_SLA_ACK: // addressed, returned ack - case TW_SR_GCALL_ACK: // addressed generally, returned ack - case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack - case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack - // enter slave receiver mode - twi_state = TWI_SRX; - - // indicate that rx buffer can be overwritten and ack - twi_rxBufferIndex = 0; - twi_reply(1); - break; - - case TW_SR_DATA_ACK: // data received, returned ack - case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack - // if there is still room in the rx buffer - if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) { - // put byte in buffer and ack - twi_rxBuffer[twi_rxBufferIndex++] = TWDR; - twi_reply(1); - } else { - // otherwise nack - twi_reply(0); - } - break; - - case TW_SR_STOP: // stop or repeated start condition received - // put a null char after data if there's room - if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) { - twi_rxBuffer[twi_rxBufferIndex] = 0; - } - - // sends ack and stops interface for clock stretching - twi_stop(); - - // callback to user defined callback - twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); - - // since we submit rx buffer to "wire" library, we can reset it - twi_rxBufferIndex = 0; - - // ack future responses and leave slave receiver state - twi_releaseBus(); - break; - - case TW_SR_DATA_NACK: // data received, returned nack - case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack - // nack back at master - twi_reply(0); - break; - - // Slave Transmitter - case TW_ST_SLA_ACK: // addressed, returned ack - case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack - // enter slave transmitter mode - twi_state = TWI_STX; - - // ready the tx buffer index for iteration - twi_txBufferIndex = 0; - - // set tx buffer length to be zero, to verify if user changes it - twi_txBufferLength = 0; - - // request for txBuffer to be filled and length to be set - // note: user must call twi_transmit(bytes, length) to do this - twi_onSlaveTransmit(); - - // if they didn't change buffer & length, initialize it - if (0 == twi_txBufferLength) { - twi_txBufferLength = 1; - twi_txBuffer[0] = 0x00; - } - - // transmit first byte from buffer, fall through - - case TW_ST_DATA_ACK: // byte sent, ack returned - // copy data to output register - TWDR = twi_txBuffer[twi_txBufferIndex++]; - - // if there is more to send, ack, otherwise nack - if (twi_txBufferIndex < twi_txBufferLength) { - twi_reply(1); - } else { - twi_reply(0); - } - break; - - case TW_ST_DATA_NACK: // received nack, we are done - case TW_ST_LAST_DATA: // received ack, but we are done already! - // ack future responses - twi_reply(1); - // leave slave receiver state - twi_state = TWI_READY; - break; - */ - - // all - case TW_NO_INFO: // no state information - break; - - case TW_BUS_ERROR: // bus error, illegal stop/start - twi_error = TW_BUS_ERROR; - twi_stop(); - break; - } - - if (fNextInterruptFunction) return fNextInterruptFunction(); -} - -TwoWire::TwoWire() { } - -void TwoWire::begin(void) { - rxBufferIndex = 0; - rxBufferLength = 0; - - txBufferIndex = 0; - txBufferLength = 0; - - twi_init(); -} - -void TwoWire::beginTransmission(uint8_t address) { - //beginTransmission((uint8_t)address); - - // indicate that we are transmitting - twi_transmitting = 1; - - // set address of targeted slave - txAddress = address; - - // reset tx buffer iterator vars - txBufferIndex = 0; - txBufferLength = 0; -} - -uint8_t TwoWire::endTransmission(uint16_t timeout) { - // transmit buffer (blocking) - //int8_t ret = - twi_cbendTransmissionDone = NULL; - twi_writeTo(txAddress, txBuffer, txBufferLength, 1); - int8_t ret = twii_WaitForDone(timeout); - - // reset tx buffer iterator vars - txBufferIndex = 0; - txBufferLength = 0; - - // indicate that we are done transmitting - // twi_transmitting = 0; - return ret; -} - -void TwoWire::nbendTransmission(void (*function)(int)) { - twi_cbendTransmissionDone = function; - twi_writeTo(txAddress, txBuffer, txBufferLength, 1); - return; -} - -void TwoWire::send(uint8_t data) { - if (twi_transmitting) { - // in master transmitter mode - // don't bother if buffer is full - if (txBufferLength >= NBWIRE_BUFFER_LENGTH) { - return; - } - - // put byte in tx buffer - txBuffer[txBufferIndex] = data; - ++txBufferIndex; - - // update amount in buffer - txBufferLength = txBufferIndex; - } else { - // in slave send mode - // reply to master - //twi_transmit(&data, 1); - } -} - -uint8_t TwoWire::receive(void) { - // default to returning null char - // for people using with char strings - uint8_t value = 0; - - // get each successive byte on each call - if (rxBufferIndex < rxBufferLength) { - value = rxBuffer[rxBufferIndex]; - ++rxBufferIndex; - } - - return value; -} - -uint8_t TwoWire::requestFrom(uint8_t address, int quantity, uint16_t timeout) { - // clamp to buffer length - if (quantity > NBWIRE_BUFFER_LENGTH) { - quantity = NBWIRE_BUFFER_LENGTH; - } - - // perform blocking read into buffer - twi_cbreadFromDone = NULL; - twi_readFrom(address, rxBuffer, quantity); - uint8_t read = twii_WaitForDone(timeout); - - // set rx buffer iterator vars - rxBufferIndex = 0; - rxBufferLength = read; - - return read; -} - -void TwoWire::nbrequestFrom(uint8_t address, int quantity, void (*function)(int)) { - // clamp to buffer length - if (quantity > NBWIRE_BUFFER_LENGTH) { - quantity = NBWIRE_BUFFER_LENGTH; - } - - // perform blocking read into buffer - twi_cbreadFromDone = function; - twi_readFrom(address, rxBuffer, quantity); - //uint8_t read = twii_WaitForDone(); - - // set rx buffer iterator vars - //rxBufferIndex = 0; - //rxBufferLength = read; - - rxBufferIndex = 0; - rxBufferLength = quantity; // this is a hack - - return; //read; -} - -uint8_t TwoWire::available(void) { - return rxBufferLength - rxBufferIndex; -} - -#endif diff --git a/I2Cdev/I2Cdev.h b/I2Cdev/I2Cdev.h deleted file mode 100644 index 33d4adc6bb636b62e4182504938b272a1a66eb8e..0000000000000000000000000000000000000000 --- a/I2Cdev/I2Cdev.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef _I2CDEV_H_ -#define _I2CDEV_H_ -#define I2CDEV_IMPLEMENTATION I2CDEV_ARDUINO_WIRE -#define I2CDEV_IMPLEMENTATION_WARNINGS -#define I2CDEV_ARDUINO_WIRE 1 -#define I2CDEV_BUILTIN_NBWIRE 2 -#define I2CDEV_BUILTIN_FASTWIRE 3 -#define I2CDEV_I2CMASTER_LIBRARY 4 -#ifdef ARDUINO -#if ARDUINO < 100 -#include "WProgram.h" -#else -#include "Arduino.h" -#endif -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE -#include <Wire.h> -#endif -#if I2CDEV_IMPLEMENTATION == I2CDEV_I2CMASTER_LIBRARY -#include <I2C.h> -#endif -#endif -#define I2CDEV_DEFAULT_READ_TIMEOUT 1000 -class I2Cdev { - public: - I2Cdev(); - static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout = I2Cdev::readTimeout); - static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout = I2Cdev::readTimeout); - static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout = I2Cdev::readTimeout); - static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout = I2Cdev::readTimeout); - static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout = I2Cdev::readTimeout); - static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout = I2Cdev::readTimeout); - static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout = I2Cdev::readTimeout); - static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout = I2Cdev::readTimeout); - static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data); - static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data); - static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data); - static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data); - static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); - static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data); - static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data); - static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data); - static uint16_t readTimeout; -}; -#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE -#define TW_START 0x08 -#define TW_REP_START 0x10 -#define TW_MT_SLA_ACK 0x18 -#define TW_MT_SLA_NACK 0x20 -#define TW_MT_DATA_ACK 0x28 -#define TW_MT_DATA_NACK 0x30 -#define TW_MT_ARB_LOST 0x38 -#define TW_MR_ARB_LOST 0x38 -#define TW_MR_SLA_ACK 0x40 -#define TW_MR_SLA_NACK 0x48 -#define TW_MR_DATA_ACK 0x50 -#define TW_MR_DATA_NACK 0x58 -#define TW_OK 0 -#define TW_ERROR 1 -class Fastwire { - private: - static boolean waitInt(); - public: - static void setup(int khz, boolean pullup); - static byte beginTransmission(byte device); - static byte write(byte value); - static byte writeBuf(byte device, byte address, byte *data, byte num); - static byte readBuf(byte device, byte address, byte *data, byte num); - static void reset(); - static byte stop(); -}; -#endif -#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE -#define NBWIRE_BUFFER_LENGTH 32 -class TwoWire { - private: - static uint8_t rxBuffer[]; - static uint8_t rxBufferIndex; - static uint8_t rxBufferLength; - static uint8_t txAddress; - static uint8_t txBuffer[]; - static uint8_t txBufferIndex; - static uint8_t txBufferLength; - static void (*user_onRequest)(void); - static void (*user_onReceive)(int); - static void onRequestService(void); - static void onReceiveService(uint8_t*, int); - public: - TwoWire(); - void begin(); - void begin(uint8_t); - void begin(int); - void beginTransmission(uint8_t); - uint8_t endTransmission(uint16_t timeout = 0); - void nbendTransmission(void (*function)(int)) ; - uint8_t requestFrom(uint8_t, int, uint16_t timeout = 0); - void nbrequestFrom(uint8_t, int, void (*function)(int)); - void send(uint8_t); - void send(uint8_t*, uint8_t); - void send(char*); - uint8_t available(void); - uint8_t receive(void); - void onReceive(void (*)(int)); - void onRequest(void (*)(void)); -}; -#define TWI_READY 0 -#define TWI_MRX 1 -#define TWI_MTX 2 -#define TWI_SRX 3 -#define TWI_STX 4 -#define TW_WRITE 0 -#define TW_READ 1 -#define TW_MT_SLA_NACK 0x20 -#define TW_MT_DATA_NACK 0x30 -#define CPU_FREQ 16000000L -#define TWI_FREQ 100000L -#define TWI_BUFFER_LENGTH 32 -#define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3)) -#define TW_STATUS (TWSR & TW_STATUS_MASK) -#define TW_START 0x08 -#define TW_REP_START 0x10 -#define TW_MT_SLA_ACK 0x18 -#define TW_MT_SLA_NACK 0x20 -#define TW_MT_DATA_ACK 0x28 -#define TW_MT_DATA_NACK 0x30 -#define TW_MT_ARB_LOST 0x38 -#define TW_MR_ARB_LOST 0x38 -#define TW_MR_SLA_ACK 0x40 -#define TW_MR_SLA_NACK 0x48 -#define TW_MR_DATA_ACK 0x50 -#define TW_MR_DATA_NACK 0x58 -#define TW_ST_SLA_ACK 0xA8 -#define TW_ST_ARB_LOST_SLA_ACK 0xB0 -#define TW_ST_DATA_ACK 0xB8 -#define TW_ST_DATA_NACK 0xC0 -#define TW_ST_LAST_DATA 0xC8 -#define TW_SR_SLA_ACK 0x60 -#define TW_SR_ARB_LOST_SLA_ACK 0x68 -#define TW_SR_GCALL_ACK 0x70 -#define TW_SR_ARB_LOST_GCALL_ACK 0x78 -#define TW_SR_DATA_ACK 0x80 -#define TW_SR_DATA_NACK 0x88 -#define TW_SR_GCALL_DATA_ACK 0x90 -#define TW_SR_GCALL_DATA_NACK 0x98 -#define TW_SR_STOP 0xA0 -#define TW_NO_INFO 0xF8 -#define TW_BUS_ERROR 0x00 -#ifndef sbi -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -#endif -#ifndef cbi -#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) -#endif -extern TwoWire Wire; -#endif -#endif diff --git a/IRremote/Contributing.md b/IRremote/Contributing.md deleted file mode 100644 index 4424f809c224fbd62135f2c8ece3babeff6d2ee6..0000000000000000000000000000000000000000 --- a/IRremote/Contributing.md +++ /dev/null @@ -1,47 +0,0 @@ -# Contributing -This library is the culmination of the expertise of many members of the open source community who have dedicated their time and hard work. - -If you want to contribute to this project: -- Report bugs and errors -- Ask for enhancements -- Create issues and pull requests -- Tell other people about this library -- Contribute new protocols - -## Guidelines -The following are some guidelines to observe when creating discussions / PRs: -#### Be friendly -It is important that we can all enjoy a safe space as we are all working on the same project and **it is okay for people to have different ideas**. -#### Use reasonable titles -Refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile:. -#### Use the formatting style -We use the original [C Style by Kerninghan / Ritchie](https://en.wikipedia.org/wiki/Indentation_style#K&R_style) in [variant: 1TBS (OTBS)](https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS)).<br/> -In short: 4 spaces indentation, no tabs, opening braces on the same line, braces are mandatory on all if/while/do, no hard line length limit.<br/> -To beautify your code, you may use the online formatter [here](https://www.freecodeformat.com/c-format.php). -#### Cover **all** occurences of the problem / addition you address with your PR - Do not forget the documentation like it is done for existing code. Code changes without proper documentation will be rejected! - -## Adding new protocols -To add a new protocol is quite straightforward. Best is too look at the existing protocols to find a similar one and modify it.<br/> -As a rule of thumb, it is easier to work with a description of the protocol rather than trying to entirely reverse-engineer the protocol. -Please include a link to the description in the header, if you found one.<br/> -The **durations** you receive are likely to be longer for marks and shorter for spaces than the protocol suggests, -but this depends on the receiver circuit in use. Most protocols use multiples of one time-unit for marks and spaces like e.g. [NEC](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_NEC.hpp#L62). It's easy to be off-by-one with the last bit, since the last space is not recorded by IRremote. - -Try to make use of the template functions `decodePulseDistanceData()` and `sendPulseDistanceData()`. -If your protocol supports address and code fields, try to reflect this in your api like it is done in [`sendNEC(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aIsRepeat)`](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_NEC.hpp#L96) -and [`decodeNEC()`](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_NEC.hpp#L194).<br/> - -### Integration -To integrate your protocol, you need to extend the two functions `decode()` and `getProtocolString()` in *IRreceice.hpp*, -add macros and function declarations for sending and receiving and extend the `enum decode_type_t` in *IRremote.h*.<br/> -And at least it would be wonderful if you can provide an example how to use the new protocol. -A detailed description can be found in the [ir_Template.hpp](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_Template.hpp#L11) file. - -### Creating API documentation -To generate the API documentation, Doxygen, as well as [Graphviz](http://www.graphviz.org/) should be installed. -(Note that on Windows, it is useful to specify the installer to add Graphviz to PATH or to do it manually. -With Doxygen and Graphviz installed, issue the command -`doxygen` from the command line in the main project directory, which will -generate the API documentation in HTML format. -The just generated `docs/index.html` can now be opened in a browser. \ No newline at end of file diff --git a/IRremote/Contributors.md b/IRremote/Contributors.md deleted file mode 100644 index 00dd4c8269e689e3e0c3731084e7063c318fd7f2..0000000000000000000000000000000000000000 --- a/IRremote/Contributors.md +++ /dev/null @@ -1,34 +0,0 @@ -## Contributors -These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. - -- [ArminJo](https://github.com/ArminJo) Maintainer -- [z3t0](https://github.com/z3t0) the main contributor until version 2.4.0. - * Email: zetoslab@gmail.com -- [shirriff](https://github.com/shirriff): An amazing person who worked to create this awesome library and provide unending support -- [Informatic](https://github.com/Informatic) -- [fmeschia](https://github.com/fmeschia) -- [PaulStoffregen](https://github.com/paulstroffregen) -- [crash7](https://github.com/crash7) -- [Neco777](https://github.com/neco777) -- [Lauszus](https://github.com/lauszus) -- [csBlueChip](https://github.com/csbluechip) contributed major and vital changes to the code base. -- [Sebazzz](https://github.com/sebazz) -- [lumbric](https://github.com/lumbric) -- [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy) -- [philipphenkel](https://github.com/philipphenkel) -- [MCUdude](https://github.com/MCUdude) -- [adamlhumphreys](https://github.com/adamlhumphreys) (code space improvements) -- [marcmerlin](https://github.com/marcmerlin) (ESP32 port) -- [MrBryonMiller](https://github.com/MrBryonMiller) -- [bengtmartensson](https://github.com/bengtmartensson) providing support -- [AnalysIR](https:/github.com/AnalysIR) providing support -- [eshicks4](https://github.com/eshicks4) -- [Jim-2249](https://github.com/Jim-2249) -- [pmalasp](https://github.com/pmalasp ) -- [ElectronicsArchiver}(https://github.com/ElectronicsArchiver) improving documentation -- [Stephen Humphries](https://github.com/sjahu)Fix for: Prevent long delay caused by overflow when frame duration < repeat period #1028 -- [Daniel Wallner](https://github.com/danielwallner) Bang & Olufsen protocol. -- [slott](https://stackoverflow.com/users/11680056/sklott) Seeduino print(unsigned long long...) support. -- [Joe Ostrander](https://github.com/joeostrander) Added support for attiny1614. - -Note: Please let [ArminJo](https://github.com/ArminJo) know if you have been missed. diff --git a/IRremote/Doxyfile b/IRremote/Doxyfile deleted file mode 100644 index 0ce0d4bf5c7fb8f72668db6ec0667379dc886f72..0000000000000000000000000000000000000000 --- a/IRremote/Doxyfile +++ /dev/null @@ -1,2500 +0,0 @@ -# Doxyfile 1.8.18 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the configuration -# file that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# https://www.gnu.org/software/libiconv/ for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = "IRremote" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = ..\Arduino-IRremote_gh-pages - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = YES - -# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line -# such as -# /*************** -# as being the beginning of a Javadoc-style comment "banner". If set to NO, the -# Javadoc-style will behave just like regular comments and it will not be -# interpreted by doxygen. -# The default value is: NO. - -JAVADOC_BANNER = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. -# When you need a literal { or } or , in the value part of an alias you have to -# escape them by means of a backslash (\), this can lead to conflicts with the -# commands \{ and \} for these it is advised to use the version @{ and @} or use -# a double escape (\\{ and \\}) - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice -# sources only. Doxygen will then generate output that is more tailored for that -# language. For instance, namespaces will be presented as modules, types will be -# separated into more groups, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_SLICE = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: -# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser -# tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files -# as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = ino=C++ cpp=C++ h=C++ hpp=C++ - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See https://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 0 - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual -# methods of a class will be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIV_VIRTUAL = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# declarations. If set to NO, these declarations will be included in the -# documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# (including Cygwin) ands Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = YES - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if <section_label> ... \endif and \cond <section_label> -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. If -# EXTRACT_ALL is set to YES then this flag will automatically be disabled. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = src \ - src/private \ - . - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv/) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), -# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen -# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. - -FILE_PATTERNS = *.ino *.cpp *.c *.h *.hpp *.md - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# <filter> <input-file> -# -# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = README.md - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# entity all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see https://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = NO - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = docs - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# https://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML -# documentation will contain a main index with vertical navigation menus that -# are dynamically created via JavaScript. If disabled, the navigation index will -# consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have JavaScript, -# like the Qt help browser. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_MENUS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: https://developer.apple.com/xcode/), introduced with OSX -# 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy -# genXcode/_index.html for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = YES - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg -# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see -# https://inkscape.org) to generate formulas as SVG images instead of PNGs for -# the HTML output. These images will generally look nicer at scaled resolutions. -# Possible values are: png The default and svg Looks nicer but requires the -# pdf2svg tool. -# The default value is: png. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FORMULA_FORMAT = png - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands -# to create new LaTeX commands to be used in formulas as building blocks. See -# the section "Including formulas" for details. - -FORMULA_MACROFILE = - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side JavaScript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use <access key> + S -# (what the <access key> is depends on the OS and browser, but it is typically -# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down -# key> to jump into the search results window, the results can be navigated -# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel -# the search. The filter options can be selected when the cursor is inside the -# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> -# to select a filter and <Enter> or <escape> to activate or cancel the filter -# option. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using JavaScript. There -# are two flavors of web server based searching depending on the EXTERNAL_SEARCH -# setting. When disabled, doxygen will generate a PHP script for searching and -# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing -# and searching needs to be provided by external tools. See the section -# "External Indexing and Searching" for details. -# The default value is: NO. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SERVER_BASED_SEARCH = NO - -# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP -# script for searching. Instead the search results are written to an XML file -# which needs to be processed by an external indexer. Doxygen will invoke an -# external search engine pointed to by the SEARCHENGINE_URL option to obtain the -# search results. -# -# Doxygen ships with an example indexer (doxyindexer) and search engine -# (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: https://xapian.org/). -# -# See the section "External Indexing and Searching" for details. -# The default value is: NO. -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTERNAL_SEARCH = NO - -# The SEARCHENGINE_URL should point to a search engine hosted by a web server -# which will return the search results when EXTERNAL_SEARCH is enabled. -# -# Doxygen ships with an example indexer (doxyindexer) and search engine -# (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: https://xapian.org/). See the section "External Indexing and -# Searching" for details. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SEARCHENGINE_URL = - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed -# search data is written to a file for indexing by an external tool. With the -# SEARCHDATA_FILE tag the name of this file can be specified. -# The default file is: searchdata.xml. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SEARCHDATA_FILE = searchdata.xml - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the -# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is -# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple -# projects and redirect the results back to the right project. -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTERNAL_SEARCH_ID = - -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen -# projects other than the one defined by this configuration file, but that are -# all added to the same external search index. Each project needs to have a -# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of -# to a relative location where the documentation can be found. The format is: -# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTRA_SEARCH_MAPPINGS = - -#--------------------------------------------------------------------------- -# Configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. -# The default value is: YES. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: latex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. -# -# Note that when not enabling USE_PDFLATEX the default is latex when enabling -# USE_PDFLATEX the default is pdflatex and when in the later case latex is -# chosen this is overwritten by pdflatex. For specific output languages the -# default can have been set differently, this depends on the implementation of -# the output language. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate -# index for LaTeX. -# Note: This tag is used in the Makefile / make.bat. -# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file -# (.tex). -# The default file is: makeindex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -MAKEINDEX_CMD_NAME = makeindex - -# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to -# generate index for LaTeX. In case there is no backslash (\) as first character -# it will be automatically added in the LaTeX code. -# Note: This tag is used in the generated output file (.tex). -# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. -# The default value is: makeindex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_MAKEINDEX_CMD = makeindex - -# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX -# documents. This may be useful for small projects and may help to save some -# trees in general. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used by the -# printer. -# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x -# 14 inches) and executive (7.25 x 10.5 inches). -# The default value is: a4. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names -# that should be included in the LaTeX output. The package can be specified just -# by its name or with the correct syntax as to be used with the LaTeX -# \usepackage command. To get the times font for instance you can specify : -# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} -# To use the option intlimits with the amsmath package you can specify: -# EXTRA_PACKAGES=[intlimits]{amsmath} -# If left blank no extra packages will be included. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. -# -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See -# LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_FOOTER = - -# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# LaTeX style sheets that are included after the standard style sheets created -# by doxygen. Using this option one can overrule certain style aspects. Doxygen -# will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EXTRA_STYLESHEET = - -# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the LATEX_OUTPUT output -# directory. Note that the files will be copied as-is; there are no commands or -# markers available. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EXTRA_FILES = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is -# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will -# contain links (just like the HTML output) instead of page references. This -# makes the output suitable for online browsing using a PDF viewer. -# The default value is: YES. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. -# The default value is: YES. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BATCHMODE = NO - -# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the -# index chapters (such as File Index, Compound Index, etc.) in the output. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_HIDE_INDICES = NO - -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. See -# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. -# The default value is: plain. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BIB_STYLE = plain - -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_TIMESTAMP = NO - -# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) -# path from which the emoji images will be read. If a relative path is entered, -# it will be relative to the LATEX_OUTPUT directory. If left blank the -# LATEX_OUTPUT directory will be used. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EMOJI_DIRECTORY = - -#--------------------------------------------------------------------------- -# Configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The -# RTF output is optimized for Word 97 and may not look too pretty with other RTF -# readers/editors. -# The default value is: NO. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: rtf. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF -# documents. This may be useful for small projects and may help to save some -# trees in general. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will -# contain hyperlink fields. The RTF file will contain links (just like the HTML -# output) instead of page references. This makes the output suitable for online -# browsing using Word or some other Word compatible readers that support those -# fields. -# -# Note: WordPad (write) and others do not support links. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# configuration file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. -# -# See also section "Doxygen usage" for information on how to generate the -# default style sheet that doxygen normally uses. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's configuration file. A template extensions file can be -# generated using doxygen -e rtf extensionFile. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_EXTENSIONS_FILE = - -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for -# classes and files. -# The default value is: NO. - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. A directory man3 will be created inside the directory specified by -# MAN_OUTPUT. -# The default directory is: man. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to the generated -# man pages. In case the manual section does not start with a number, the number -# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is -# optional. -# The default value is: .3. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_EXTENSION = .3 - -# The MAN_SUBDIR tag determines the name of the directory created within -# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by -# MAN_EXTENSION with the initial . removed. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_SUBDIR = - -# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it -# will generate one additional man file for each entity documented in the real -# man page(s). These additional files only source the real man page, but without -# them the man command would be unable to find the correct page. -# The default value is: NO. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that -# captures the structure of the code including all documentation. -# The default value is: NO. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: xml. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_OUTPUT = xml - -# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program -# listings (including syntax highlighting and cross-referencing information) to -# the XML output. Note that enabling this will significantly increase the size -# of the XML output. -# The default value is: YES. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_PROGRAMLISTING = YES - -# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include -# namespace members in file scope as well, matching the HTML output. -# The default value is: NO. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_NS_MEMB_FILE_SCOPE = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the DOCBOOK output -#--------------------------------------------------------------------------- - -# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files -# that can be used to generate PDF. -# The default value is: NO. - -GENERATE_DOCBOOK = NO - -# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in -# front of it. -# The default directory is: docbook. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_OUTPUT = docbook - -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - -#--------------------------------------------------------------------------- -# Configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures -# the structure of the code including all documentation. Note that this feature -# is still experimental and incomplete at the moment. -# The default value is: NO. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module -# file that captures the structure of the code including all documentation. -# -# Note that this feature is still experimental and incomplete at the moment. -# The default value is: NO. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary -# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI -# output from the Perl module output. -# The default value is: NO. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely -# formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO, the -# size of the Perl module output will be much smaller and Perl will parse it -# just the same. -# The default value is: YES. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file are -# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful -# so different doxyrules.make files included by the same Makefile don't -# overwrite each other's variables. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all -# C-preprocessor directives found in the sources and include files. -# The default value is: YES. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names -# in the source code. If set to NO, only conditional compilation will be -# performed. Macro expansion can be done in a controlled way by setting -# EXPAND_ONLY_PREDEF to YES. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then -# the macro expansion is limited to the macros specified with the PREDEFINED and -# EXPAND_AS_DEFINED tags. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES, the include files in the -# INCLUDE_PATH will be searched if a #include is found. -# The default value is: YES. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by the -# preprocessor. -# This tag requires that the tag SEARCH_INCLUDES is set to YES. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will be -# used. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that are -# defined before the preprocessor is started (similar to the -D option of e.g. -# gcc). The argument of the tag is a list of macros of the form: name or -# name=definition (no spaces). If the definition and the "=" are omitted, "=1" -# is assumed. To prevent a macro definition from being undefined via #undef or -# recursively expanded use the := operator instead of the = operator. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -PREDEFINED = ARDUINO \ - DOXYGEN - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this -# tag can be used to specify a list of macro names that should be expanded. The -# macro definition that is found in the sources will be used. Use the PREDEFINED -# tag if you want to use a different macro definition that overrules the -# definition found in the source code. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all references to function-like macros that are alone on a line, have -# an all uppercase name, and do not end with a semicolon. Such function macros -# are typically used for boiler-plate code, and will confuse the parser if not -# removed. -# The default value is: YES. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tag files. For each tag -# file the location of the external documentation should be added. The format of -# a tag file without this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where loc1 and loc2 can be relative or absolute paths or URLs. See the -# section "Linking to external documentation" for more information about the use -# of tag files. -# Note: Each tag file must have a unique name (where the name does NOT include -# the path). If a tag file is not located in the directory in which doxygen is -# run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create a -# tag file that is based on the input files it reads. See section "Linking to -# external documentation" for more information about the usage of tag files. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. -# The default value is: NO. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be -# listed. -# The default value is: YES. - -EXTERNAL_GROUPS = YES - -# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in -# the related pages index. If set to NO, only the current project's pages will -# be listed. -# The default value is: YES. - -EXTERNAL_PAGES = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - -# If set to YES the inheritance and collaboration graphs will hide inheritance -# and usage relations if the target is undocumented or is not a class. -# The default value is: YES. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent -# Bell Labs. The other options in this section have no effect if this option is -# set to NO -# The default value is: NO. - -HAVE_DOT = YES - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed -# to run in parallel. When set to 0 doxygen will base this on the number of -# processors available in the system. You can set it explicitly to a value -# larger than 0 to get control over the balance between CPU load and processing -# speed. -# Minimum value: 0, maximum value: 32, default value: 0. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_NUM_THREADS = 0 - -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTPATH = - -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a -# graph for each documented class showing the direct and indirect implementation -# dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -UML_LOOK = NO - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside the -# class node. If there are many fields or methods and many nodes the graph may -# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the -# number of items for each type to make the size more manageable. Set this to 0 -# for no limit. Note that the threshold may be exceeded by 50% before the limit -# is enforced. So when you set the threshold to 10, up to 15 fields may appear, -# but if the number exceeds 15, the total amount of fields shown is limited to -# 10. -# Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. - -UML_LIMIT_NUM_FIELDS = 10 - -# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and -# collaboration graphs will show the relations between templates and their -# instances. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -TEMPLATE_RELATIONS = NO - -# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to -# YES then doxygen will generate a graph for each documented file showing the -# direct and indirect include dependencies of the file with other documented -# files. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -INCLUDE_GRAPH = YES - -# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are -# set to YES then doxygen will generate a graph for each documented file showing -# the direct and indirect include dependencies of the file with other documented -# files. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH tag is set to YES then doxygen will generate a call -# dependency graph for every global function or class method. -# -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. Disabling a call graph can be -# accomplished by means of the command \hidecallgraph. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller -# dependency graph for every global function or class method. -# -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. Disabling a caller graph can be -# accomplished by means of the command \hidecallergraph. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical -# hierarchy of all classes instead of a textual one. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the -# dependencies a directory has on other directories in a graphical way. The -# dependency relations are determined by the #include relations between the -# files in the directories. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. For an explanation of the image formats see the section -# output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). -# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order -# to make the SVG files visible in IE 9+ (other browsers do not have this -# requirement). -# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, -# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and -# png:gdiplus:gdiplus. -# The default value is: png. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# -# Note that this requires a modern browser other than Internet Explorer. Tested -# and working are Firefox, Chrome, Safari, and Opera. -# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make -# the SVG files visible. Older versions of IE do not have SVG support. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -INTERACTIVE_SVG = NO - -# The DOT_PATH tag can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the \dotfile -# command). -# This tag requires that the tag HAVE_DOT is set to YES. - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). - -MSCFILE_DIRS = - -# The DIAFILE_DIRS tag can be used to specify one or more directories that -# contain dia files that are included in the documentation (see the \diafile -# command). - -DIAFILE_DIRS = - -# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. - -PLANTUML_JAR_PATH = - -# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a -# configuration file for plantuml. - -PLANTUML_CFG_FILE = - -# When using plantuml, the specified paths are searched for files specified by -# the !include statement in a plantuml block. - -PLANTUML_INCLUDE_PATH = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes -# that will be shown in the graph. If the number of nodes in a graph becomes -# larger than this value, doxygen will truncate the graph, which is visualized -# by representing a node as a red box. Note that doxygen if the number of direct -# children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that -# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. -# Minimum value: 0, maximum value: 10000, default value: 50. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs -# generated by dot. A depth value of 3 means that only nodes reachable from the -# root by following a path via at most 3 edges will be shown. Nodes that lay -# further from the root node will be omitted. Note that setting this option to 1 -# or 2 may greatly reduce the computation time needed for large code bases. Also -# note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. -# Minimum value: 0, maximum value: 1000, default value: 0. -# This tag requires that the tag HAVE_DOT is set to YES. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) support -# this, this feature is disabled by default. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page -# explaining the meaning of the various boxes and arrows in the dot generated -# graphs. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot -# files that are used to generate the various graphs. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_CLEANUP = YES diff --git a/IRremote/IRremote.cpp b/IRremote/IRremote.cpp deleted file mode 100644 index f41f81878fce4cefc4f469067bec14f05c2b20df..0000000000000000000000000000000000000000 --- a/IRremote/IRremote.cpp +++ /dev/null @@ -1,198 +0,0 @@ -//****************************************************************************** -// IRremote -// Version 2.0.1 June, 2015 -// Copyright 2009 Ken Shirriff -// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html -// -// Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers -// Modified by Mitra Ardron <mitra@mitra.biz> -// Added Sanyo and Mitsubishi controllers -// Modified Sony to spot the repeat codes that some Sony's send -// -// Interrupt code based on NECIRrcv by Joe Knapp -// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 -// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ -// -// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) -// LG added by Darryl Smith (based on the JVC protocol) -// Whynter A/C ARC-110WD added by Francesco Meschia -//****************************************************************************** - -// Defining IR_GLOBAL here allows us to declare the instantiation of global variables -#define IR_GLOBAL -# include "IRremote.h" -# include "IRremoteInt.h" -#undef IR_GLOBAL - -#ifdef HAS_AVR_INTERRUPT_H -#include <avr/interrupt.h> -#endif - - -//+============================================================================= -// The match functions were (apparently) originally MACROs to improve code speed -// (although this would have bloated the code) hence the names being CAPS -// A later release implemented debug output and so they needed to be converted -// to functions. -// I tried to implement a dual-compile mode (DEBUG/non-DEBUG) but for some -// reason, no matter what I did I could not get them to function as macros again. -// I have found a *lot* of bugs in the Arduino compiler over the last few weeks, -// and I am currently assuming that one of these bugs is my problem. -// I may revisit this code at a later date and look at the assembler produced -// in a hope of finding out what is going on, but for now they will remain as -// functions even in non-DEBUG mode -// -int MATCH (int measured, int desired) -{ - DBG_PRINT(F("Testing: ")); - DBG_PRINT(TICKS_LOW(desired), DEC); - DBG_PRINT(F(" <= ")); - DBG_PRINT(measured, DEC); - DBG_PRINT(F(" <= ")); - DBG_PRINT(TICKS_HIGH(desired), DEC); - - bool passed = ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); - if (passed) - DBG_PRINTLN(F("?; passed")); - else - DBG_PRINTLN(F("?; FAILED")); - return passed; -} - -//+======================================================== -// Due to sensor lag, when received, Marks tend to be 100us too long -// -int MATCH_MARK (int measured_ticks, int desired_us) -{ - DBG_PRINT(F("Testing mark (actual vs desired): ")); - DBG_PRINT(measured_ticks * USECPERTICK, DEC); - DBG_PRINT(F("us vs ")); - DBG_PRINT(desired_us, DEC); - DBG_PRINT("us"); - DBG_PRINT(": "); - DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS) * USECPERTICK, DEC); - DBG_PRINT(F(" <= ")); - DBG_PRINT(measured_ticks * USECPERTICK, DEC); - DBG_PRINT(F(" <= ")); - DBG_PRINT(TICKS_HIGH(desired_us + MARK_EXCESS) * USECPERTICK, DEC); - - bool passed = ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) - && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); - if (passed) - DBG_PRINTLN(F("?; passed")); - else - DBG_PRINTLN(F("?; FAILED")); - return passed; -} - -//+======================================================== -// Due to sensor lag, when received, Spaces tend to be 100us too short -// -int MATCH_SPACE (int measured_ticks, int desired_us) -{ - DBG_PRINT(F("Testing space (actual vs desired): ")); - DBG_PRINT(measured_ticks * USECPERTICK, DEC); - DBG_PRINT(F("us vs ")); - DBG_PRINT(desired_us, DEC); - DBG_PRINT("us"); - DBG_PRINT(": "); - DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS) * USECPERTICK, DEC); - DBG_PRINT(F(" <= ")); - DBG_PRINT(measured_ticks * USECPERTICK, DEC); - DBG_PRINT(F(" <= ")); - DBG_PRINT(TICKS_HIGH(desired_us - MARK_EXCESS) * USECPERTICK, DEC); - - bool passed = ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) - && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); - if (passed) - DBG_PRINTLN(F("?; passed")); - else - DBG_PRINTLN(F("?; FAILED")); - return passed; -} - -//+============================================================================= -// Interrupt Service Routine - Fires every 50uS -// TIMER2 interrupt code to collect raw data. -// Widths of alternating SPACE, MARK are recorded in rawbuf. -// Recorded in ticks of 50uS [microseconds, 0.000050 seconds] -// 'rawlen' counts the number of entries recorded so far. -// First entry is the SPACE between transmissions. -// As soon as a the first [SPACE] entry gets long: -// Ready is set; State switches to IDLE; Timing of SPACE continues. -// As soon as first MARK arrives: -// Gap width is recorded; Ready is cleared; New logging starts -// -ISR (TIMER_INTR_NAME) -{ - TIMER_RESET; - - // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] - // digitalRead() is very slow. Optimisation is possible, but makes the code unportable - uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); - - irparams.timer++; // One more 50uS tick - if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // Buffer overflow - - switch(irparams.rcvstate) { - //...................................................................... - case STATE_IDLE: // In the middle of a gap - if (irdata == MARK) { - if (irparams.timer < GAP_TICKS) { // Not big enough to be a gap. - irparams.timer = 0; - - } else { - // Gap just ended; Record duration; Start recording transmission - irparams.overflow = false; - irparams.rawlen = 0; - irparams.rawbuf[irparams.rawlen++] = irparams.timer; - irparams.timer = 0; - irparams.rcvstate = STATE_MARK; - } - } - break; - //...................................................................... - case STATE_MARK: // Timing Mark - if (irdata == SPACE) { // Mark ended; Record time - irparams.rawbuf[irparams.rawlen++] = irparams.timer; - irparams.timer = 0; - irparams.rcvstate = STATE_SPACE; - } - break; - //...................................................................... - case STATE_SPACE: // Timing Space - if (irdata == MARK) { // Space just ended; Record time - irparams.rawbuf[irparams.rawlen++] = irparams.timer; - irparams.timer = 0; - irparams.rcvstate = STATE_MARK; - - } else if (irparams.timer > GAP_TICKS) { // Space - // A long Space, indicates gap between codes - // Flag the current code as ready for processing - // Switch to STOP - // Don't reset timer; keep counting Space width - irparams.rcvstate = STATE_STOP; - } - break; - //...................................................................... - case STATE_STOP: // Waiting; Measuring Gap - if (irdata == MARK) irparams.timer = 0 ; // Reset gap timer - break; - //...................................................................... - case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine - irparams.overflow = true; - irparams.rcvstate = STATE_STOP; - break; - } - -#ifdef BLINKLED - // If requested, flash LED while receiving IR data - if (irparams.blinkflag) { - if (irdata == MARK) - if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on - else BLINKLED_ON() ; // if no user defined LED pin, turn default LED pin for the hardware on - else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on - else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on - } -#endif // BLINKLED -} diff --git a/IRremote/IRremote.h b/IRremote/IRremote.h deleted file mode 100644 index 928284361a209910122b6bde0b0cec1565af64d8..0000000000000000000000000000000000000000 --- a/IRremote/IRremote.h +++ /dev/null @@ -1,369 +0,0 @@ - -//****************************************************************************** -// IRremote -// Version 2.0.1 June, 2015 -// Copyright 2009 Ken Shirriff -// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html -// Edited by Mitra to add new controller SANYO -// -// Interrupt code based on NECIRrcv by Joe Knapp -// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 -// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ -// -// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) -// LG added by Darryl Smith (based on the JVC protocol) -// Whynter A/C ARC-110WD added by Francesco Meschia -//****************************************************************************** - -#ifndef IRremote_h -#define IRremote_h - -//------------------------------------------------------------------------------ -// The ISR header contains several useful macros the user may wish to use -// -#include "IRremoteInt.h" - -//------------------------------------------------------------------------------ -// Supported IR protocols -// Each protocol you include costs memory and, during decode, costs time -// Disable (set to 0) all the protocols you do not need/want! -// -#define DECODE_RC5 1 -#define SEND_RC5 1 - -#define DECODE_RC6 1 -#define SEND_RC6 1 - -#define DECODE_NEC 1 -#define SEND_NEC 1 - -#define DECODE_SONY 1 -#define SEND_SONY 1 - -#define DECODE_PANASONIC 1 -#define SEND_PANASONIC 1 - -#define DECODE_JVC 1 -#define SEND_JVC 1 - -#define DECODE_SAMSUNG 1 -#define SEND_SAMSUNG 1 - -#define DECODE_WHYNTER 1 -#define SEND_WHYNTER 1 - -#define DECODE_AIWA_RC_T501 1 -#define SEND_AIWA_RC_T501 1 - -#define DECODE_LG 1 -#define SEND_LG 1 - -#define DECODE_SANYO 1 -#define SEND_SANYO 0 // NOT WRITTEN - -#define DECODE_MITSUBISHI 1 -#define SEND_MITSUBISHI 0 // NOT WRITTEN - -#define DECODE_DISH 0 // NOT WRITTEN -#define SEND_DISH 1 - -#define DECODE_SHARP 0 // NOT WRITTEN -#define SEND_SHARP 1 - -#define DECODE_DENON 1 -#define SEND_DENON 1 - -#define DECODE_PRONTO 0 // This function doe not logically make sense -#define SEND_PRONTO 1 - -#define DECODE_LEGO_PF 0 // NOT WRITTEN -#define SEND_LEGO_PF 1 - -//------------------------------------------------------------------------------ -// When sending a Pronto code we request to send either the "once" code -// or the "repeat" code -// If the code requested does not exist we can request to fallback on the -// other code (the one we did not explicitly request) -// -// I would suggest that "fallback" will be the standard calling method -// The last paragraph on this page discusses the rationale of this idea: -// http://www.remotecentral.com/features/irdisp2.htm -// -#define PRONTO_ONCE false -#define PRONTO_REPEAT true -#define PRONTO_FALLBACK true -#define PRONTO_NOFALLBACK false - -//------------------------------------------------------------------------------ -// An enumerated list of all supported formats -// You do NOT need to remove entries from this list when disabling protocols! -// -typedef - enum { - UNKNOWN = -1, - UNUSED = 0, - RC5, - RC6, - NEC, - SONY, - PANASONIC, - JVC, - SAMSUNG, - WHYNTER, - AIWA_RC_T501, - LG, - SANYO, - MITSUBISHI, - DISH, - SHARP, - DENON, - PRONTO, - LEGO_PF, - } -decode_type_t; - -//------------------------------------------------------------------------------ -// Set DEBUG to 1 for lots of lovely debug output -// -#define DEBUG 0 - -//------------------------------------------------------------------------------ -// Debug directives -// -#if DEBUG -# define DBG_PRINT(...) Serial.print(__VA_ARGS__) -# define DBG_PRINTLN(...) Serial.println(__VA_ARGS__) -#else -# define DBG_PRINT(...) -# define DBG_PRINTLN(...) -#endif - -//------------------------------------------------------------------------------ -// Mark & Space matching functions -// -int MATCH (int measured, int desired) ; -int MATCH_MARK (int measured_ticks, int desired_us) ; -int MATCH_SPACE (int measured_ticks, int desired_us) ; - -//------------------------------------------------------------------------------ -// Results returned from the decoder -// -class decode_results -{ - public: - decode_type_t decode_type; // UNKNOWN, NEC, SONY, RC5, ... - unsigned int address; // Used by Panasonic & Sharp [16-bits] - unsigned long value; // Decoded value [max 32-bits] - int bits; // Number of bits in decoded value - volatile unsigned int *rawbuf; // Raw intervals in 50uS ticks - int rawlen; // Number of records in rawbuf - int overflow; // true iff IR raw code too long -}; - -//------------------------------------------------------------------------------ -// Decoded value for NEC when a repeat code is received -// -#define REPEAT 0xFFFFFFFF - -//------------------------------------------------------------------------------ -// Main class for receiving IR -// -class IRrecv -{ - public: - IRrecv (int recvpin) ; - IRrecv (int recvpin, int blinkpin); - - void blink13 (int blinkflag) ; - int decode (decode_results *results) ; - void enableIRIn ( ) ; - bool isIdle ( ) ; - void resume ( ) ; - - private: - long decodeHash (decode_results *results) ; - int compare (unsigned int oldval, unsigned int newval) ; - - //...................................................................... -# if (DECODE_RC5 || DECODE_RC6) - // This helper function is shared by RC5 and RC6 - int getRClevel (decode_results *results, int *offset, int *used, int t1) ; -# endif -# if DECODE_RC5 - bool decodeRC5 (decode_results *results) ; -# endif -# if DECODE_RC6 - bool decodeRC6 (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_NEC - bool decodeNEC (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_SONY - bool decodeSony (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_PANASONIC - bool decodePanasonic (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_JVC - bool decodeJVC (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_SAMSUNG - bool decodeSAMSUNG (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_WHYNTER - bool decodeWhynter (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_AIWA_RC_T501 - bool decodeAiwaRCT501 (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_LG - bool decodeLG (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_SANYO - bool decodeSanyo (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_MITSUBISHI - bool decodeMitsubishi (decode_results *results) ; -# endif - //...................................................................... -# if DECODE_DISH - bool decodeDish (decode_results *results) ; // NOT WRITTEN -# endif - //...................................................................... -# if DECODE_SHARP - bool decodeSharp (decode_results *results) ; // NOT WRITTEN -# endif - //...................................................................... -# if DECODE_DENON - bool decodeDenon (decode_results *results) ; -# endif -//...................................................................... -# if DECODE_LEGO_PF - bool decodeLegoPowerFunctions (decode_results *results) ; -# endif -} ; - -//------------------------------------------------------------------------------ -// Main class for sending IR -// -class IRsend -{ - public: -#ifdef USE_SOFT_CARRIER - - IRsend(int pin = SEND_PIN) - { - sendPin = pin; - } -#else - - IRsend() - { - } -#endif - - void custom_delay_usec (unsigned long uSecs); - void enableIROut (int khz) ; - void mark (unsigned int usec) ; - void space (unsigned int usec) ; - void sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz) ; - - //...................................................................... -# if SEND_RC5 - void sendRC5 (unsigned long data, int nbits) ; -# endif -# if SEND_RC6 - void sendRC6 (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_NEC - void sendNEC (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_SONY - void sendSony (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_PANASONIC - void sendPanasonic (unsigned int address, unsigned long data) ; -# endif - //...................................................................... -# if SEND_JVC - // JVC does NOT repeat by sending a separate code (like NEC does). - // The JVC protocol repeats by skipping the header. - // To send a JVC repeat signal, send the original code value - // and set 'repeat' to true - void sendJVC (unsigned long data, int nbits, bool repeat) ; -# endif - //...................................................................... -# if SEND_SAMSUNG - void sendSAMSUNG (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_WHYNTER - void sendWhynter (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_AIWA_RC_T501 - void sendAiwaRCT501 (int code) ; -# endif - //...................................................................... -# if SEND_LG - void sendLG (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_SANYO - void sendSanyo ( ) ; // NOT WRITTEN -# endif - //...................................................................... -# if SEND_MISUBISHI - void sendMitsubishi ( ) ; // NOT WRITTEN -# endif - //...................................................................... -# if SEND_DISH - void sendDISH (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_SHARP - void sendSharpRaw (unsigned long data, int nbits) ; - void sendSharp (unsigned int address, unsigned int command) ; -# endif - //...................................................................... -# if SEND_DENON - void sendDenon (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_PRONTO - void sendPronto (char* code, bool repeat, bool fallback) ; -# endif -//...................................................................... -# if SEND_LEGO_PF - void sendLegoPowerFunctions (uint16_t data, bool repeat = true) ; -# endif - -#ifdef USE_SOFT_CARRIER - private: - int sendPin; - - unsigned int periodTime; - unsigned int periodOnTime; - - void sleepMicros(unsigned long us); - void sleepUntilMicros(unsigned long targetTime); - -#else - const int sendPin = SEND_PIN; -#endif -} ; - -#endif diff --git a/IRremote/IRremoteInt.h b/IRremote/IRremoteInt.h deleted file mode 100644 index 1c319acbff56630c2ba003e8e607c9ed0b5b308a..0000000000000000000000000000000000000000 --- a/IRremote/IRremoteInt.h +++ /dev/null @@ -1,113 +0,0 @@ -//****************************************************************************** -// IRremote -// Version 2.0.1 June, 2015 -// Copyright 2009 Ken Shirriff -// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html -// -// Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers -// -// Interrupt code based on NECIRrcv by Joe Knapp -// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 -// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ -// -// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) -// Whynter A/C ARC-110WD added by Francesco Meschia -//****************************************************************************** - -#ifndef IRremoteint_h -#define IRremoteint_h - -//------------------------------------------------------------------------------ -// Include the right Arduino header -// -#if defined(ARDUINO) && (ARDUINO >= 100) -# include <Arduino.h> -#else -# if !defined(IRPRONTO) -# include <WProgram.h> -# endif -#endif - -//------------------------------------------------------------------------------ -// This handles definition and access to global variables -// -#ifdef IR_GLOBAL -# define EXTERN -#else -# define EXTERN extern -#endif - -//------------------------------------------------------------------------------ -// Information for the Interrupt Service Routine -// -#define RAWBUF 101 // Maximum length of raw duration buffer - -typedef - struct { - // The fields are ordered to reduce memory over caused by struct-padding - uint8_t rcvstate; // State Machine state - uint8_t recvpin; // Pin connected to IR data from detector - uint8_t blinkpin; - uint8_t blinkflag; // true -> enable blinking of pin on IR processing - uint8_t rawlen; // counter of entries in rawbuf - unsigned int timer; // State timer, counts 50uS ticks. - unsigned int rawbuf[RAWBUF]; // raw data - uint8_t overflow; // Raw buffer overflow occurred - } -irparams_t; - -// ISR State-Machine : Receiver States -#define STATE_IDLE 2 -#define STATE_MARK 3 -#define STATE_SPACE 4 -#define STATE_STOP 5 -#define STATE_OVERFLOW 6 - -// Allow all parts of the code access to the ISR data -// NB. The data can be changed by the ISR at any time, even mid-function -// Therefore we declare it as "volatile" to stop the compiler/CPU caching it -EXTERN volatile irparams_t irparams; - -//------------------------------------------------------------------------------ -// Defines for setting and clearing register bits -// -#ifndef cbi -# define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) -#endif - -#ifndef sbi -# define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -#endif - -//------------------------------------------------------------------------------ -// Pulse parms are ((X*50)-100) for the Mark and ((X*50)+100) for the Space. -// First MARK is the one after the long gap -// Pulse parameters in uSec -// - -// Due to sensor lag, when received, Marks tend to be 100us too long and -// Spaces tend to be 100us too short -#define MARK_EXCESS 100 - -// Upper and Lower percentage tolerances in measurements -#define TOLERANCE 25 -#define LTOL (1.0 - (TOLERANCE/100.)) -#define UTOL (1.0 + (TOLERANCE/100.)) - -// Minimum gap between IR transmissions -#define _GAP 5000 -#define GAP_TICKS (_GAP/USECPERTICK) - -#define TICKS_LOW(us) ((int)(((us)*LTOL/USECPERTICK))) -#define TICKS_HIGH(us) ((int)(((us)*UTOL/USECPERTICK + 1))) - -//------------------------------------------------------------------------------ -// IR detector output is active low -// -#define MARK 0 -#define SPACE 1 - -// All board specific stuff has been moved to its own file, included here. -#include "boarddefs.h" - -#endif diff --git a/IRremote/ISSUE_TEMPLATE.md b/IRremote/ISSUE_TEMPLATE.md deleted file mode 100644 index 98358d0e4194b4ca6e911d0a263b16be06a93f73..0000000000000000000000000000000000000000 --- a/IRremote/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,25 +0,0 @@ -**Board:** ARDUINO UNO -**Library Version:** 2.1.0 -**Protocol:** Sony (if any) - -**Code Block:** -```c - -#include <IRremote.h> - -..... - -``` - -Use [a gist](gist.github.com) if the code exceeds 30 lines - -**checklist:** -- [] I have **read** the README.md file thoroughly -- [] I have searched existing issues to see if there is anything I have missed. -- [] The latest [release](https://github.com/z3t0/Arduino-IRremote/releases/latest) is used -- [] Any code referenced is provided and if over 30 lines a gist is linked INSTEAD of it being pasted in here -- [] The title of the issue is helpful and relevant - -** We will start to close issues that do not follow these guidelines as it doesn't help the contributors who spend time trying to solve issues if the community ignores guidelines!** - -The above is a short template allowing you to make detailed issues! diff --git a/IRremote/LICENSE b/IRremote/LICENSE deleted file mode 100644 index 184ff748a8fcb042d7898ada766dab670aca040e..0000000000000000000000000000000000000000 --- a/IRremote/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -MIT License - -(c) Copyright 2009 Ken Shirriff http://www.righto.com -(c) Copyright 2016 Rafi Khan -(c) Copyright 2020-2022 Armin Joachimsmeyer et al. - - http://www.opensource.org/licenses/mit-license.php - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/IRremote/LICENSE.txt b/IRremote/LICENSE.txt deleted file mode 100644 index 77cec6dd195dfa3b7e6fb0cc660c6f2a99fd0cbc..0000000000000000000000000000000000000000 --- a/IRremote/LICENSE.txt +++ /dev/null @@ -1,458 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - diff --git a/IRremote/README.md b/IRremote/README.md deleted file mode 100644 index 5d186af5f2a27908c53c60d5e51ac53a03af6bd5..0000000000000000000000000000000000000000 --- a/IRremote/README.md +++ /dev/null @@ -1,916 +0,0 @@ -<div align = center> - -# Arduino IRremote -A library enabling the sending & receiving of infra-red signals. - -[](https://opensource.org/licenses/MIT) - -[](https://github.com/Arduino-IRremote/Arduino-IRremote/releases/latest) - -[](https://github.com/Arduino-IRremote/Arduino-IRremote/commits/master) - -[](https://github.com/Arduino-IRremote/Arduino-IRremote/actions) -<br/> -<br/> -[](https://stand-with-ukraine.pp.ua) - -Available as [Arduino library "IRremote"](https://www.arduinolibraries.info/libraries/i-rremote). - -[](https://www.ardu-badge.com/IRremote) - -[](https://arduino-irremote.github.io/Arduino-IRremote/classIRrecv.html) - -[](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/changelog.md) - -[](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/Contributing.md) - -</div> - -# Overview -- [Supported IR Protocols](https://github.com/Arduino-IRremote/Arduino-IRremote#supported-ir-protocols) -- [Features](https://github.com/Arduino-IRremote/Arduino-IRremote#features) - * [New features with version 4.x](https://github.com/Arduino-IRremote/Arduino-IRremote#new-features-with-version-4x) - * [New features with version 3.x](https://github.com/Arduino-IRremote/Arduino-IRremote#new-features-with-version-3x) -- [Converting your 2.x program to the 4.x version](https://github.com/Arduino-IRremote/Arduino-IRremote#converting-your-2x-program-to-the-4x-version) - * [How to convert old MSB first 32 bit IR data codes to new LSB first 32 bit IR data codes](https://github.com/Arduino-IRremote/Arduino-IRremote#how-to-convert-old-msb-first-32-bit-ir-data-codes-to-new-lsb-first-32-bit-ir-data-codes) -- [Errors with using the 3.x versions for old tutorials](https://github.com/Arduino-IRremote/Arduino-IRremote#errors-with-using-the-3x-versions-for-old-tutorials) - * [Staying on 2.x](https://github.com/Arduino-IRremote/Arduino-IRremote#staying-on-2x) -- [Why *.hpp instead of *.cpp](https://github.com/Arduino-IRremote/Arduino-IRremote#why-hpp-instead-of-cpp) -- [Using the new *.hpp files](https://github.com/Arduino-IRremote/Arduino-IRremote#using-the-new-hpp-files) -- [Receiving IR codes](https://github.com/Arduino-IRremote/Arduino-IRremote#receiving-ir-codes) - * [Data format](https://github.com/Arduino-IRremote/Arduino-IRremote#data-format) - * [Ambiguous protocols](https://github.com/Arduino-IRremote/Arduino-IRremote#ambiguous-protocols) -- [Sending IR codes](https://github.com/Arduino-IRremote/Arduino-IRremote#sending-ir-codes) - * [Send pin](https://github.com/Arduino-IRremote/Arduino-IRremote#send-pin) - + [List of public IR code databases](https://github.com/Arduino-IRremote/Arduino-IRremote#list-of-public-ir-code-databases) -- [Tiny NEC receiver and sender](https://github.com/Arduino-IRremote/Arduino-IRremote#tiny-nec-receiver-and-sender) -- [The FAST protocol](https://github.com/Arduino-IRremote/Arduino-IRremote#the-fast-protocol) -- [FAQ and hints](https://github.com/Arduino-IRremote/Arduino-IRremote#faq-and-hints) - * [Problems with Neopixels, FastLed etc.](https://github.com/Arduino-IRremote/Arduino-IRremote#problems-with-neopixels-fastled-etc) - * [Does not work/compile with another library](https://github.com/Arduino-IRremote/Arduino-IRremote#does-not-workcompile-with-another-library) - * [Multiple IR receiver](https://github.com/Arduino-IRremote/Arduino-IRremote#multiple-ir-receiver) - * [Increase strength of sent output signal](https://github.com/Arduino-IRremote/Arduino-IRremote#increase-strength-of-sent-output-signal) - * [Minimal CPU clock frequency](https://github.com/Arduino-IRremote/Arduino-IRremote#minimal-cpu-clock-frequency) - * [Bang & Olufsen protocol](https://github.com/Arduino-IRremote/Arduino-IRremote#bang--olufsen-protocol) -- [Handling unknown Protocols](https://github.com/Arduino-IRremote/Arduino-IRremote#handling-unknown-protocols) - * [Disclaimer](https://github.com/Arduino-IRremote/Arduino-IRremote#disclaimer) - * [Protocol=PULSE_DISTANCE](https://github.com/Arduino-IRremote/Arduino-IRremote#protocolpulse_distance) - * [Protocol=UNKNOWN](https://github.com/Arduino-IRremote/Arduino-IRremote#protocolunknown) - * [How to deal with protocols not supported by IRremote](https://github.com/Arduino-IRremote/Arduino-IRremote#how-to-deal-with-protocols-not-supported-by-irremote) -- [Examples for this library](https://github.com/Arduino-IRremote/Arduino-IRremote#examples-for-this-library) -- [WOKWI online examples](https://github.com/Arduino-IRremote/Arduino-IRremote#wokwi-online-examples) -- [Issues and discussions](https://github.com/Arduino-IRremote/Arduino-IRremote#issues-and-discussions) -- [Compile options / macros for this library](https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library) - + [Changing include (*.h) files with Arduino IDE](https://github.com/Arduino-IRremote/Arduino-IRremote#changing-include-h-files-with-arduino-ide) - + [Modifying compile options with Sloeber IDE](https://github.com/Arduino-IRremote/Arduino-IRremote#modifying-compile-options--macros-with-sloeber-ide) -- [Supported Boards](https://github.com/Arduino-IRremote/Arduino-IRremote#supported-boards) -- [Timer and pin usage](https://github.com/Arduino-IRremote/Arduino-IRremote#timer-and-pin-usage) - * [Incompatibilities to other libraries and Arduino commands like tone() and analogWrite()](https://github.com/Arduino-IRremote/Arduino-IRremote#incompatibilities-to-other-libraries-and-arduino-commands-like-tone-and-analogwrite) - * [Hardware-PWM signal generation for sending](https://github.com/Arduino-IRremote/Arduino-IRremote#hardware-pwm-signal-generation-for-sending) - * [Why do we use 30% duty cycle for sending](https://github.com/Arduino-IRremote/Arduino-IRremote#why-do-we-use-30-duty-cycle-for-sending) -- [How we decode signals](https://github.com/Arduino-IRremote/Arduino-IRremote#how-we-decode-signals) -- [NEC encoding diagrams](https://github.com/Arduino-IRremote/Arduino-IRremote#nec-encoding-diagrams) -- [Quick comparison of 5 Arduino IR receiving libraries](https://github.com/Arduino-IRremote/Arduino-IRremote#quick-comparison-of-5-arduino-ir-receiving-libraries) -- [Useful links](https://github.com/Arduino-IRremote/Arduino-IRremote#useful-links) -- [Contributors](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/Contributors.md) -- [License](https://github.com/Arduino-IRremote/Arduino-IRremote#license) -- [Copyright](https://github.com/Arduino-IRremote/Arduino-IRremote#copyright) - -<br/> - -# Supported IR Protocols -` NEC / Onkyo / Apple ` ` Denon / Sharp ` ` Panasonic / Kaseikyo ` - -` JVC ` ` LG ` ` RC5 ` ` RC6 ` ` Samsung ` ` Sony ` - -` Universal Pulse Distance ` ` Universal Pulse Width ` ` Hash ` ` Pronto ` - -` BoseWave ` ` Bang & Olufsen ` ` Lego ` ` FAST ` ` Whynter ` ` MagiQuest ` - -Protocols can be switched off and on by defining macros before the line `#include <IRremote.hpp>` like [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/SimpleReceiver/SimpleReceiver.ino#L33): - -```c++ -#define DECODE_NEC -//#define DECODE_DENON -#include <IRremote.hpp> -``` -<br/> - -# Features -- Lots of tutorials and examples. -- Actively maintained. -- Allows receiving and sending of **raw timing data**. - -## New features with version 4.x -- New universal **Pulse Distance / Pulse Width decoder** added, which covers many previous unknown protocols. -- Printout of code how to send received command by `IrReceiver.printIRSendUsage(&Serial)`. -- RawData type is now 64 bit for 32 bit platforms and therefore `decodedIRData.decodedRawData` can contain complete frame information for more protocols than with 32 bit as before. -- Callback after receiving a command - It calls your code as soon as a message was received. -- Improved handling of `PULSE_DISTANCE` + `PULSE_WIDTH` protocols. -- New FAST protocol. - -#### Converting your 3.x program to the 4.x version -- You must replace `#define DECODE_DISTANCE` by `#define DECODE_DISTANCE_WIDTH` (only if you explicitly enabled this decoder). -- The parameter `bool hasStopBit` is not longer required and removed e.g. for function `sendPulseDistanceWidth()`. - -## New features with version 3.x -- **Any pin** can be used for sending -if `SEND_PWM_BY_TIMER` is not defined- and receiving. -- Feedback LED can be activated for sending / receiving. -- An 8/16 bit ****command** value as well as an 16 bit **address** and a protocol number is provided for decoding (instead of the old 32 bit value). -- Protocol values comply to **protocol standards**.<br/> - NEC, Panasonic, Sony, Samsung and JVC decode & send LSB first. -- Supports **Universal Distance protocol**, which covers a lot of previous unknown protocols. -- Compatible with **tone()** library. See the [ReceiveDemo](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/21b5747a58e9d47c9e3f1beb056d58c875a92b47/examples/ReceiveDemo/ReceiveDemo.ino#L159-L169) example. -- Simultaneous sending and receiving. See the [SendAndReceive](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/SendAndReceive/SendAndReceive.ino#L167-L170) example. -- Supports **more platforms**. -- Allows for the generation of non PWM signal to just **simulate an active low receiver signal** for direct connect to existent receiving devices without using IR. -- Easy protocol configuration, **directly in your [source code](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/SimpleReceiver/SimpleReceiver.ino#L33-L57)**.<br/> - Reduces memory footprint and decreases decoding time. -- Contains a [very small NEC only decoder](https://github.com/Arduino-IRremote/Arduino-IRremote#minimal-nec-receiver), which **does not require any timer resource**. - -[-> Feature comparison of 5 Arduino IR libraries](https://github.com/Arduino-IRremote/Arduino-IRremote#quick-comparison-of-5-arduino-ir-receiving-libraries). - -<br/> - -# Converting your 2.x program to the 4.x version -Starting with the 3.1 version, **the generation of PWM for sending is done by software**, thus saving the hardware timer and **enabling arbitrary output pins for sending**.<br/> -If you use an (old) Arduino core that does not use the `-flto` flag for compile, you can activate the line `#define SUPPRESS_ERROR_MESSAGE_FOR_BEGIN` in IRRemote.h, if you get false error messages regarding begin() during compilation. - -- **IRreceiver** and **IRsender** object have been added and can be used without defining them, like the well known Arduino **Serial** object. -- Just remove the line `IRrecv IrReceiver(IR_RECEIVE_PIN);` and/or `IRsend IrSender;` in your program, and replace all occurrences of `IRrecv.` or `irrecv.` with `IrReceiver` and replace all `IRsend` or `irsend` with `IrSender`. -- Since the decoded values are now in `IrReceiver.decodedIRData` and not in `results` any more, remove the line `decode_results results` or similar. -- Like for the Serial object, call [`IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK)`](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/ReceiveDemo/ReceiveDemo.ino#L106) - or `IrReceiver.begin(IR_RECEIVE_PIN, DISABLE_LED_FEEDBACK)` instead of the `IrReceiver.enableIRIn()` or `irrecv.enableIRIn()` in setup().<br/> -For sending, call `IrSender.begin(ENABLE_LED_FEEDBACK);` or `IrSender.begin(DISABLE_LED_FEEDBACK);` in setup().<br/> -If IR_SEND_PIN is not defined you must use e.g. `IrSender.begin(3, ENABLE_LED_FEEDBACK, USE_DEFAULT_FEEDBACK_LED_PIN);` -- Old `decode(decode_results *aResults)` function is replaced by simple `decode()`. So if you have a statement `if(irrecv.decode(&results))` replace it with `if (IrReceiver.decode())`. -- The decoded result is now in in `IrReceiver.decodedIRData` and not in `results` any more, therefore replace any occurrences of `results.value` and `results.decode_type` (and similar) to - `IrReceiver.decodedIRData.decodedRawData` and `IrReceiver.decodedIRData.protocol`. -- Overflow, Repeat and other flags are now in [`IrReceiver.receivedIRData.flags`](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRProtocol.h#L90-L101). -- Seldom used: `results.rawbuf` and `results.rawlen` must be replaced by `IrReceiver.decodedIRData.rawDataPtr->rawbuf` and `IrReceiver.decodedIRData.rawDataPtr->rawlen`. - -- The 5 protocols **NEC, Panasonic, Sony, Samsung and JVC** have been converted to LSB first. Send functions for sending old MSB data for **NEC** and **JVC** were renamed to `sendNECMSB`, and `sendJVCMSB()`. The old `sendSAMSUNG()` and `sendSony()` MSB functions are still available. The old MSB version of `sendPanasonic()` function was deleted, since it had bugs nobody recognized.<br/> -For converting MSB codes to LSB see [below](https://github.com/Arduino-IRremote/Arduino-IRremote#how-to-convert-old-msb-first-32-bit-ir-data-codes-to-new-lsb-first-32-bit-ir-data-codes). - -### Example -#### Old 2.x program: - -```c++ -#include <IRremote.h> - -IRrecv irrecv(RECV_PIN); -decode_results results; - -void setup() -{ -... - irrecv.enableIRIn(); // Start the receiver -} - -void loop() { - if (irrecv.decode(&results)) { - Serial.println(results.value, HEX); - ... - irrecv.resume(); // Receive the next value - } - ... -} -``` - -#### New 4.x program: - -```c++ -#include <IRremote.hpp> - -void setup() -{ -... - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the receiver -} - -void loop() { - if (IrReceiver.decode()) { - Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // Print "old" raw data - // USE NEW 3.x FUNCTIONS - IrReceiver.printIRResultShort(&Serial); // Print complete received data in one line - IrReceiver.printIRSendUsage(&Serial); // Print the statement required to send this data - ... - IrReceiver.resume(); // Enable receiving of the next value - } - ... -} -``` - -## How to convert old MSB first 32 bit IR data codes to new LSB first 32 bit IR data codes -For the new decoders for **NEC, Panasonic, Sony, Samsung and JVC**, the result `IrReceiver.decodedIRData.decodedRawData` is now **LSB-first**, as the definition of these protocols suggests!<br/> -<br/> -To convert one into the other, you must reverse the byte/nibble positions and then reverse all bit positions of each byte/nibble or write it as one binary string and reverse/mirror it.<br/><br/> -Example: -`0xCB 34 01 02`<br/> -`0x20 10 43 BC` after nibble reverse<br/> -`0x40 80 2C D3` after bit reverse of each nibble<br/><br/> -### Nibble reverse map: -``` - 0->0 1->8 2->4 3->C - 4->2 5->A 6->6 7->E - 8->1 9->9 A->5 B->D - C->3 D->B E->7 F->F -``` -`0xCB340102` is binary `1100 1011 0011 0100 0000 0001 0000 0010`.<br/> -`0x40802CD3` is binary `0100 0000 1000 0000 0010 1100 1101 0011`.<br/> -If you **read the first binary sequence backwards** (right to left), you get the second sequence. - -<br/> - -# Errors with using the 4.x versions for old tutorials -If you suffer from errors with old tutorial code including `IRremote.h` instead of `IRremote.hpp`, just try to rollback to [Version 2.4.0](https://github.com/Arduino-IRremote/Arduino-IRremote/releases/tag/v2.4.0).<br/> -Most likely your code will run and you will not miss the new features... - -<br/> - -## Staying on 2.x -Consider using the [original 2.4 release form 2017](https://github.com/Arduino-IRremote/Arduino-IRremote/releases/tag/v2.4.0) -or the last backwards compatible [2.8 version](https://github.com/Arduino-IRremote/Arduino-IRremote/releases/tag/2.8.0) for you project.<br/> -It may be sufficient and deals flawlessly with 32 bit IR codes.<br/> -If this doesn't fit your case, be assured that 3.x is at least trying to be backwards compatible, so your old examples should still work fine. - -### Drawbacks -- Only the following decoders are available:<br/> - ` NEC ` ` Denon ` ` Panasonic ` ` JVC ` ` LG `<br/> - ` RC5 ` ` RC6 ` ` Samsung ` ` Sony ` -- The call of `irrecv.decode(&results)` uses the old MSB first decoders like in 2.x and sets the 32 bit codes in `results.value`. -- The old functions `sendNEC()` and `sendJVC()` are renamed to `sendNECMSB()` and `sendJVCMSB()`.<br/> - Use them to send your **old MSB-first 32 bit IR data codes**. -- No decoding by a (constant) 8/16 bit address and an 8 bit command. - -<br/> - -# Why *.hpp instead of *.cpp? -**Every \*.cpp file is compiled separately** by a call of the compiler exclusively for this cpp file. These calls are managed by the IDE / make system. -In the Arduino IDE the calls are executed when you click on *Verify* or *Upload*. - -And now our problem with Arduino is:<br/> -**How to set [compile options](#compile-options--macros-for-this-library) for all *.cpp files, especially for libraries used?**<br/> -IDE's like [Sloeber](https://github.com/ArminJo/ServoEasing#modifying-compile-options--macros-with-sloeber-ide) or [PlatformIO](https://github.com/ArminJo/ServoEasing#modifying-compile-options--macros-with-platformio) support this by allowing to specify a set of options per project. -They add these options at each compiler call e.g. `-DTRACE`. - -But Arduino lacks this feature. -So the **workaround** is not to compile all sources separately, but to concatenate them to one huge source file by including them in your source.<br/> -This is done by e.g. `#include "IRremote.hpp"`. - -But why not `#include "IRremote.cpp"`?<br/> -Try it and you will see tons of errors, because each function of the *.cpp file is now compiled twice, -first by compiling the huge file and second by compiling the *.cpp file separately, like described above.<br/> -So using the extension *cpp* is not longer possible, and one solution is to use *hpp* as extension, to show that it is an included *.cpp file.<br/> -Every other extension e.g. *cinclude* would do, but *hpp* seems to be common sense. - -# Using the new *.hpp files -In order to support [compile options](#compile-options--macros-for-this-library) more easily, -you must use the statement `#include <IRremote.hpp>` instead of `#include <IRremote.h>` in your main program (aka *.ino file with setup() and loop()). - -In **all other files** you must use the following, to **prevent `multiple definitions` linker errors**: - -```c++ -#define USE_IRREMOTE_HPP_AS_PLAIN_INCLUDE -#include <IRremote.hpp> -``` - -**Ensure that all macros in your main program are defined before any** `#include <IRremote.hpp>`.<br/> -The following macros will definitely be overridden with default values otherwise: -- `RAW_BUFFER_LENGTH` -- `IR_SEND_PIN` -- `SEND_PWM_BY_TIMER` - -<br/> - -# Receiving IR codes -Check for **received data** with:<br/> -`if (IrReceiver.decode()) {}`<br/> -This also decodes the received data. - -## Data format -After successful decoding, the IR data is contained in the IRData structure, available as `IrReceiver.decodedIRData`. - -```c++ -struct IRData { - decode_type_t protocol; // UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ... - uint16_t address; // Decoded address - uint16_t command; // Decoded command - uint16_t extra; // Used for Kaseikyo unknown vendor ID. Ticks used for decoding Distance protocol. - uint16_t numberOfBits; // Number of bits received for data (address + command + parity) - to determine protocol length if different length are possible. - uint8_t flags; // IRDATA_FLAGS_IS_REPEAT, IRDATA_FLAGS_WAS_OVERFLOW etc. See IRDATA_FLAGS_* definitions - IRRawDataType decodedRawData; // Up to 32 (64 bit for 32 bit CPU architectures) bit decoded raw data, used for sendRaw functions. - uint32_t decodedRawDataArray[RAW_DATA_ARRAY_SIZE]; // 32 bit decoded raw data, to be used for send function. - irparams_struct *rawDataPtr; // Pointer of the raw timing data to be decoded. Mainly the data buffer filled by receiving ISR. -}; -``` -#### Flags -This is the [list of flags](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRProtocol.h#L88) contained in the flags field.<br/> -Check it with e.g. `if(IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)`. - -| Flag name | Description | -|:---|----| -| IRDATA_FLAGS_IS_REPEAT | The gap between the preceding frame is as smaller than the maximum gap expected for a repeat. !!!We do not check for changed command or address, because it is almost not possible to press 2 different buttons on the remote within around 100 ms!!! -| IRDATA_FLAGS_IS_AUTO_REPEAT | The current repeat frame is a repeat, that is always sent after a regular frame and cannot be avoided. Only specified for protocols DENON, and LEGO. | -| IRDATA_FLAGS_PARITY_FAILED | The current (autorepeat) frame violated parity check. | -| IRDATA_FLAGS_TOGGLE_BIT | Is set if RC5 or RC6 toggle bit is set. | -| IRDATA_FLAGS_EXTRA_INFO | There is extra info not contained in address and data (e.g. Kaseikyo unknown vendor ID, or in decodedRawDataArray). | -| IRDATA_FLAGS_WAS_OVERFLOW | irparams.rawlen is set to 0 in this case to avoid endless OverflowFlag. | -| IRDATA_FLAGS_IS_MSB_FIRST | This value is mainly determined by the (known) protocol. | - -#### To access the **RAW data**, use: -```c++ -auto myRawdata= IrReceiver.decodedIRData.decodedRawData; -``` - -The definitions for the `IrReceiver.decodedIRData.flags` are described [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRremoteInt.h#L128-L140). - -#### Print all fields: -```c++ -IrReceiver.printIRResultShort(&Serial); -``` - -#### Print the raw timing data received: -```c++ -IrReceiver.printIRResultRawFormatted(&Serial, true);` -``` -The raw data depends on the internal state of the Arduino timer in relation to the received signal and might therefore be slightly different each time. (resolution problem). The decoded values are the interpreted ones which are tolerant to such slight differences! - -#### Print how to send the received data: -```c++ -IrReceiver.printIRSendUsage(&Serial); -``` - -## Ambiguous protocols -### NEC, Extended NEC, ONKYO -The **NEC protocol** is defined as 8 bit address and 8 bit command. But the physical address and data fields are each 16 bit wide. -The additional 8 bits are used to send the inverted address or command for parity checking.<br/> -The **extended NEC protocol** uses the additional 8 parity bit of address for a 16 bit address, thus disabling the parity check for address.<br/> -The **ONKYO protocol** in turn uses the additional 8 parity bit of address and command for a 16 bit address and command. - -The decoder reduces the 16 bit values to 8 bit ones if the parity is correct. -If the parity is not correct, it assumes no parity error, but takes the values as 16 bit values without parity assuming extended NEC or extended NEC protocol protocol. - -But now we have a problem when we want to receive e.g. the **16 bit** address 0x00FF or 0x32CD! -The decoder interprets this as a NEC 8 bit address 0x00 / 0x32 with correct parity of 0xFF / 0xCD and reduces it to 0x00 / 0x32. - -One way to handle this, is to force the library to **always** use the ONKYO protocol interpretation by using `#define DECODE_ONKYO`. -Another way is to check if `IrReceiver.decodedIRData.protocol` is NEC and not ONKYO and to revert the parity reducing manually. - -### NEC, NEC2 -On a long press, the **NEC protocol** does not repeat its frame, it sends a special short repeat frame. -This enables an easy distinction between long presses and repeated presses and saves a bit of battery energy. -This behavior is quite unique for NEC and its derived protocols like LG. - -So there are of course also remote control systems, which uses the NEC protocol but on a long press just repeat the first frame instead of sending the special short repeat frame. We named this the **NEC2** protocol and it is sent with `sendNEC2()`.<br/> -But be careful, the NEC2 protocol can only be detected by the NEC library decoder **after** the first frame and if you do a long press! - -<br/> - -# Sending IR codes -If you have a device at hand which can generate the IR codes you want to work with (aka IR remote), **it is recommended** to receive the codes with the [ReceiveDemo example](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/ReceiveDemo/ReceiveDemo.ino), which will tell you on the serial output how to send them. - -``` -Protocol=LG Address=0x2 Command=0x3434 Raw-Data=0x23434E 28 bits MSB first -Send with: IrSender.sendLG(0x2, 0x3434, <numberOfRepeats>); -``` -You will discover that **the address is a constant** and the commands sometimes are sensibly grouped.<br/> -If you are uncertain about the numbers of repeats to use for sending, **3** is a good starting point. If this works, you can check lower values afterwards. - -The codes found in the [irdb database](https://github.com/probonopd/irdb/tree/master/codes) specify a **device**, a **subdevice** and a **function**. Most of the times, *device* and *subdevice* can be taken as upper and lower byte of the **address parameter** and *function* is the **command parameter** for the **new structured functions** with address, command and repeat-count parameters like e.g. `IrSender.sendNEC((device << 8) | subdevice, 0x19, 2)`.<br/> -An **exact mapping** can be found in the [IRP definition files for IR protocols](https://github.com/probonopd/MakeHex/tree/master/protocols). "D" and "S" denotes device and subdevice and "F" denotes the function. - -**All sending functions support the sending of repeats** if sensible. -Repeat frames are sent at a fixed period determined by the protocol. e.g. 110 ms from start to start for NEC.<br/> -Keep in mind, that **there is no delay after the last sent mark**. -If you handle the sending of repeat frames by your own, you must insert sensible delays before the repeat frames to enable correct decoding. - -The old send*Raw() functions for sending like e.g. `IrSender.sendNECRaw(0xE61957A8,2)` are kept for backward compatibility to **(old)** tutorials and unsupported as well as error prone. - -## Send pin -Any pin can be choosen as send pin, because the PWM signal is generated by default with software bit banging, since `SEND_PWM_BY_TIMER` is not active. -If `IR_SEND_PIN` is specified (as constant), it reduces program size and improves send timing for AVR. If you want to use a variable to specify send pin e.g. with `setSendPin(uint8_t aSendPinNumber)`, you must disable this macro. Then you can change send pin at any time before sending an IR frame. See also [Compile options / macros for this library](https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library). - -### List of public IR code databases -http://www.harctoolbox.org/IR-resources.html - -<br/> - - -# Tiny NEC receiver and sender -For applications only requiring NEC or FAST -see below- protocol, there is a special receiver / sender included,<br/> -which has very **small code size of 500 bytes and does NOT require any timer**. - -Check out the [TinyReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote#tinyreceiver--tinysender) and [IRDispatcherDemo](https://github.com/Arduino-IRremote/Arduino-IRremote#irdispatcherdemo) examples.<br/> -Take care to include `TinyIRReceiver.hpp` or `TinyIRSender.hpp` instead of `IRremote.hpp`. - -### TinyIRReceiver usage -```c++ -//#define USE_ONKYO_PROTOCOL // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. -//#define USE_FAST_PROTOCOL // Use FAST protocol instead of NEC / ONKYO -#include "TinyIRReceiver.hpp" - -void setup() { - initPCIInterruptForTinyReceiver(); // Enables the interrupt generation on change of IR input signal -} - -void loop() {} - -// This is the function, which is called if a complete command was received -// It runs in an ISR context with interrupts enabled, so functions like delay() etc. should work here -void handleReceivedTinyIRData(uint8_t aAddress, uint8_t aCommand, uint8_t aFlags) { - printTinyReceiverResultMinimal(&Serial, aAddress, aCommand, aFlags); -} -``` - -### TinyIRSender usage -```c++ -#include "TinyIRSender.hpp" - -void setup() { - sendNECMinimal(3, 0, 11, 2); // Send address 0 and command 11 on pin 3 with 2 repeats. -} - -void loop() {} -``` - -Another tiny receiver and sender **supporting more protocols** can be found [here](https://github.com/LuisMiCa/IRsmallDecoder). - -# The FAST protocol -The FAST protocol is a proprietary modified JVC protocol **without address, with parity and with a shorter header**. -It is meant to have a quick response to the event which sent the protocol frame on another board. -FAST takes **21 ms for sending** and is sent at a **50 ms period**. -It has full 8 bit parity for error detection. - -### FAST protocol characteristics: -- Bit timing is like JVC -- The header is shorter, 3156 µs vs. 12500 µs -- No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command, leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms. -- Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance. - -### Sending FAST protocol with IRremote -```c++ -#define IR_SEND_PIN 3 -#include <IRremote.hpp> - -void setup() { - sendFAST(11, 2); // Send command 11 on pin 3 with 2 repeats. -} - -void loop() {} -``` - -### Sending FAST protocol with TinyIRSender -```c++ -#define USE_FAST_PROTOCOL // Use FAST protocol. No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command -#include "TinyIRSender.hpp" - -void setup() { - sendFAST(3, 11, 2); // Send command 11 on pin 3 with 2 repeats. -} - -void loop() {} -``` -<br/> - -The FAST protocol can be received by IRremote and TinyIRReceiver. - -# FAQ and hints - -## Problems with Neopixels, FastLed etc. -IRremote will not work right when you use **Neopixels** (aka WS2811/WS2812/WS2812B) or other libraries blocking interrupts for a longer time (> 50 µs).<br/> -Whether you use the Adafruit Neopixel lib, or FastLED, interrupts get disabled on many lower end CPUs like the basic Arduinos for longer than 50 µs. -In turn, this stops the IR interrupt handler from running when it needs to. See also this [video](https://www.youtube.com/watch?v=62-nEJtm070). - -One **workaround** is to wait for the IR receiver to be idle before you send the Neopixel data with `if (IrReceiver.isIdle()) { strip.show();}`.<br/> -This **prevents at least breaking a running IR transmission** and -depending of the update rate of the Neopixel- may work quite well.<br/> -There are some other solutions to this on more powerful processors, -[see this page from Marc MERLIN](http://marc.merlins.org/perso/arduino/post_2017-04-03_Arduino-328P-Uno-Teensy3_1-ESP8266-ESP32-IR-and-Neopixels.html) - -## Does not work/compile with another library -**Another library is only working/compiling** if you deactivate the line `IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);`.<br/> -This is often due to **timer resource conflicts** with the other library. Please see [below](https://github.com/Arduino-IRremote/Arduino-IRremote#timer-and-pin-usage). - -## Multiple IR receivers -IRreceiver consists of one timer triggered function reading the digital IR signal value from one pin every 50 µs.<br/> -So **multiple IR receivers** can only be used by connecting the output pins of several IR receivers together. -The IR receivers use an NPN transistor as output device with just a 30k resistor to VCC. -This is almost "open collector" and allows connecting of several output pins to one Arduino input pin.<br/> -But keep in mind, that any weak / disturbed signal from one of the receivers will in turn also disturb a good signal from another one. - -## Increase strength of sent output signal -**The best way to increase the IR power for free** is to use 2 or 3 IR diodes in series. One diode requires 1.2 volt at 20 mA or 1.5 volt at 100 mA so you can supply up to 3 diodes with a 5 volt output.<br/> -To power **2 diodes** with 1.2 V and 20 mA and a 5 V supply, set the resistor to: (5 V - 2.4 V) -> 2.6 V / 20 mA = **130 Ω**.<br/> -For **3 diodes** it requires 1.4 V / 20 mA = **70 Ω**.<br/> -The actual current might be lower since of **loss at the AVR pin**. E.g. 0.3 V at 20 mA.<br/> -If you do not require more current than 20 mA, there is no need to use an external transistor (at least for AVR chips). - -On my Arduino Nanos, I always use a 100 Ω series resistor and one IR LED :grinning:. - -## Minimal CPU clock frequency -For receiving, the **minimal CPU clock frequency is 4 MHz**, since the 50 µs timer ISR (Interrupt Service Routine) takes around 12 µs on a 16 MHz ATmega.<br/> -The TinyReceiver, which reqires no polling, runs with 1 MHz.<br/> -For sending, the **default software generated PWM has problems on AVR running with 8 MHz**. The PWM frequency is around 30 instead of 38 kHz and RC6 is not reliable. You can switch to timer PWM generation by `#define SEND_PWM_BY_TIMER`. - -## Bang & Olufsen protocol -The Bang & Olufsen protocol decoder is not enabled by default, i.e if no protocol is enabled explicitly by #define `DECODE_<XYZ>`. It must always be enabled explicitly by `#define DECODE_BEO`. -This is because it has an **IR transmit frequency of 455 kHz** and therefore requires a different receiver hardware (TSOP7000).<br/> -And because **generating a 455 kHz PWM signal is currently only implemented for `SEND_PWM_BY_TIMER`**, sending only works if `SEND_PWM_BY_TIMER` or `USE_NO_SEND_PWM` is defined.<br/> -For more info, see [ir_BangOlufsen.hpp](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_BangOlufsen.hpp#L44). - -# Handling unknown Protocols -## Disclaimer -**This library was designed to fit inside MCUs with relatively low levels of resources and was intended to work as a library together with other applications which also require some resources of the MCU to operate.** - -For **air conditioners** [see this fork](https://github.com/crankyoldgit/IRremoteESP8266), which supports an impressive set of protocols and a lot of air conditioners. - -For **long signals** see the blog entry: ["Recording long Infrared Remote control signals with Arduino"](https://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino). - - -## Protocol=PULSE_DISTANCE -If you get something like this: -``` -PULSE_DISTANCE: HeaderMarkMicros=8900 HeaderSpaceMicros=4450 MarkMicros=550 OneSpaceMicros=1700 ZeroSpaceMicros=600 NumberOfBits=56 0x43D8613C 0x3BC3BC -``` -then you have a code consisting of **56 bits**, which is probably from an air conditioner remote.<br/> -You can send it with sendPulseDistance(). -```c++ -uint32_t tRawData[] = { 0xB02002, 0xA010 }; -IrSender.sendPulseDistance(38, 3450, 1700, 450, 1250, 450, 400, &tRawData[0], 48, false, 0, 0); -``` -You can send it with calling sendPulseDistanceWidthData() twice, once for the first 32 bit and next for the remaining 24 bits.<br/> -**The PulseDistance or PulseWidth decoders just decode a timing steam to a bit stream**. -They can not put any semantics like address, command or checksum on this bitstream, since it is no known protocol. -But the bitstream is way more readable, than a timing stream. This bitstream is read **LSB first by default**. -If this does not suit you for further research, you can change it [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_DistanceProtocol.hpp#L48). - -## Protocol=UNKNOWN -If you see something like `Protocol=UNKNOWN Hash=0x13BD886C 35 bits received` as output of e.g. the ReceiveDemo example, you either have a problem with decoding a protocol, or an unsupported protocol. - -- If you have an **odd number of bits** received, your receiver circuit probably has problems. Maybe because the IR signal is too weak. -- If you see timings like `+ 600,- 600 + 550,- 150 + 200,- 100 + 750,- 550` then one 450 µs space was split into two 150 and 100 µs spaces with a spike / error signal of 200 µs between. Maybe because of a defective receiver or a weak signal in conjunction with another light emitting source nearby. -- If you see timings like `+ 500,- 550 + 450,- 550 + 500,- 500 + 500,-1550`, then marks are generally shorter than spaces and therefore `MARK_EXCESS_MICROS` (specified in your ino file) should be **negative** to compensate for this at decoding. -- If you see `Protocol=UNKNOWN Hash=0x0 1 bits received` it may be that the space after the initial mark is longer than [`RECORD_GAP_MICROS`](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRremote.h#L124). - This was observed for some LG air conditioner protocols. Try again with a line e.g. `#define RECORD_GAP_MICROS 12000` before the line `#include <IRremote.hpp>` in your .ino file. -- To see more info supporting you to find the reason for your UNKNOWN protocol, you must enable the line `//#define DEBUG` in IRremoteInt.h. - -## How to deal with protocols not supported by IRremote -If you do not know which protocol your IR transmitter uses, you have several choices. -- Use the [IRreceiveDump example](examples/ReceiveDump) to dump out the IR timing. - You can then reproduce/send this timing with the [SendRawDemo example](examples/SendRawDemo). - For **long codes** with more than 48 bits like from air conditioners, you can **change the length of the input buffer** in [IRremote.h](src/IRremoteInt.h#L36). -- The [IRMP AllProtocol example](https://github.com/IRMP-org/IRMP#allprotocol-example) prints the protocol and data for one of the **40 supported protocols**. - The same library can be used to send this codes. -- If you have a bigger Arduino board at hand (> 100 kByte program memory) you can try the - [IRremoteDecode example](https://github.com/bengtmartensson/Arduino-DecodeIR/blob/master/examples/IRremoteDecode/IRremoteDecode.ino) of the Arduino library [DecodeIR](https://github.com/bengtmartensson/Arduino-DecodeIR). -- Use [IrScrutinizer](http://www.harctoolbox.org/IrScrutinizer.html). - It can automatically generate a send sketch for your protocol by exporting as "Arduino Raw". It supports IRremote, - the old [IRLib](https://github.com/cyborg5/IRLib) and [Infrared4Arduino](https://github.com/bengtmartensson/Infrared4Arduino). - -<br/> - -# Examples for this library -The examples are available at File > Examples > Examples from Custom Libraries / IRremote.<br/> - In order to fit the examples to the 8K flash of ATtiny85 and ATtiny88, the [Arduino library ATtinySerialOut](https://github.com/ArminJo/ATtinySerialOut) is required for this CPU's. - -#### SimpleReceiver + SimpleSender -The **[SimpleReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/SimpleReceiver/SimpleReceiver.ino)** and **[SimpleSender](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/SimpleSender/SimpleSender.ino)** examples are a good starting point. -A simple example can be tested online with [WOKWI](https://wokwi.com/projects/338611596994544210). - -#### TinyReceiver + TinySender -If **code size** or **timer usage** matters, look at these examples.<br/> -The **[TinyReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/TinyReceiver/TinyReceiver.ino)** example uses the **TinyIRReceiver** library which can **only receive NEC, ONKYO and FAST protocols, but does not require any timer**. They use pin change interrupt for on the fly decoding, which is the reason for the restricted protocol choice.<br/> -TinyReceiver can be tested online with [WOKWI](https://wokwi.com/arduino/projects/339264565653013075). - -The **[TinySender](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/TinySender/TinySender.ino)** example uses the **TinyIRSender** library which can **only send NEC, ONKYO and FAST protocols**.<br/> -It sends NEC protocol codes in standard format with 8 bit address and 8 bit command as in SimpleSender example. -Saves 780 bytes program memory and 26 bytes RAM compared to SimpleSender, which does the same, but uses the IRRemote library (and is therefore much more flexible). - -#### SmallReceiver -If the protocol is not NEC and code size matters, look at this [example](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/SmallReceiver/SmallReceiver.ino).<br/> - -#### ReceiveDemo + AllProtocolsOnLCD -[ReceiveDemo](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/ReceiveDemo/ReceiveDemo.ino) receives all protocols and **generates a beep with the Arduino tone() function** on each packet received.<br/> -Long press of one IR button (receiving of multiple repeats for one command) is detected.<br/> -[AllProtocolsOnLCD](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/AllProtocolsOnLCD/AllProtocolsOnLCD.ino) additionally **displays the short result on a 1602 LCD**. The LCD can be connected parallel or serial (I2C).<br/> -By connecting debug pin to ground, you can force printing of the raw values for each frame. The pin number of the debug pin is printed during setup, because it depends on board and LCD connection type.<br/> -This example also serves as an **example how to use IRremote and tone() together**. - -#### ReceiveDump -Receives all protocols and dumps the received signal in different flavors including Pronto format. Since the printing takes much time, repeat signals may be skipped or interpreted as UNKNOWN. - -#### SendDemo -Sends all available protocols at least once. - -#### SendAndReceive -Demonstrates **receiving while sending**. - -#### ReceiveAndSend -Record and **play back last received IR signal** at button press. IR frames of known protocols are sent by the approriate protocol encoder. `UNKNOWN` protocol frames are stored as raw data and sent with `sendRaw()`. - -#### ReceiveAndSendDistanceWidth -Try to decode each IR frame with the *universal* **DistanceWidth decoder**, store the data and send it on button press with `sendPulseDistanceWidthFromArray()`.<br/> -Storing data for distance width protocol requires 17 bytes. -The ReceiveAndSend example requires 16 bytes for known protocol data and 37 bytes for raw data of e.g.NEC protocol. - -#### ReceiveOneAndSendMultiple -Serves as a IR **remote macro expander**. Receives Samsung32 protocol and on receiving a specified input frame, it sends multiple Samsung32 frames with appropriate delays in between. -This serves as a **Netflix-key emulation** for my old Samsung H5273 TV. - -#### IRDispatcherDemo -Framework for **calling different functions of your program** for different IR codes. - -#### IRrelay -**Control a relay** (connected to an output pin) with your remote. - -#### IRremoteExtensionTest -[Example](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/IRremoteExtensionTest/IRremoteExtensionTest.ino) for a user defined class, which itself uses the IRrecv class from IRremote. - -#### SendLGAirConditionerDemo -[Example](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/SendLGAirConditionerDemo/SendLGAirConditionerDemo.ino) for sending LG air conditioner IR codes controlled by Serial input.<br/> -By just using the function `bool Aircondition_LG::sendCommandAndParameter(char aCommand, int aParameter)` you can control the air conditioner by any other command source.<br/> -The file *acLG.h* contains the command documentation of the LG air conditioner IR protocol. Based on reverse engineering of the LG AKB73315611 remote. -<br/> -IReceiverTimingAnalysis can be tested online with [WOKWI](https://wokwi.com/projects/299033930562011656) -Click on the receiver while simulation is running to specify individual IR codes. - -#### ReceiverTimingAnalysis -This [example](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/ReceiverTimingAnalysis/ReceiverTimingAnalysis.ino) analyzes the signal delivered by your IR receiver module. -Values can be used to determine the stability of the received signal as well as a hint for determining the protocol.<br/> -It also computes the `MARK_EXCESS_MICROS` value, which is the extension of the mark (pulse) duration introduced by the IR receiver module.<br/> -It can be tested online with [WOKWI](https://wokwi.com/arduino/projects/299033930562011656). -Click on the receiver while simulation is running to specify individual NEC IR codes. - -#### UnitTest -ReceiveDemo + SendDemo in one program. Demonstrates **receiving while sending**. - -# WOKWI online examples -- [Simple receiver](https://wokwi.com/projects/338611596994544210) -- [Simple toggle by IR key 5](https://wokwi.com/projects/338611596994544210) -- [TinyReceiver](https://wokwi.com/arduino/projects/339264565653013075) -- [ReceiverTimingAnalysis](https://wokwi.com/projects/299033930562011656) -- [Receiver with LCD output and switch statement](https://wokwi.com/projects/298934082074575369) - -<br/> - -# Issues and discussions -- Do not open an issue without first testing some of the examples! -- If you have a problem, please post the MCVE (Minimal Complete Verifiable Example) showing this problem. My experience is, that most of the times you will find the problem while creating this MCVE :smile:. -- [Use code blocks](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code); **it helps us help you when we can read your code!** - -<br/> - -# Compile options / macros for this library -To customize the library to different requirements, there are some compile options / macros available.<br/> -These macros must be defined in your program **before** the line `#include <IRremote.hpp>` to take effect.<br/> -Modify them by enabling / disabling them, or change the values if applicable. - -| Name | Default value | Description | -|:---|---:|----| -| `RAW_BUFFER_LENGTH` | 100 | Buffer size of raw input buffer. Must be even! 100 is sufficient for *regular* protocols of up to 48 bits, but for most air conditioner protocols a value of up to 750 is required. Use the ReceiveDump example to find smallest value for your requirements. | -| `EXCLUDE_UNIVERSAL_PROTOCOLS` | disabled | Excludes the universal decoder for pulse distance protocols and decodeHash (special decoder for all protocols) from `decode()`. Saves up to 1000 bytes program memory. | -| `DECODE_<Protocol name>` | all | Selection of individual protocol(s) to be decoded. You can specify multiple protocols. See [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRremote.hpp#L98-L121) | -| `DECODE_STRICT_CHECKS` | disabled | Check for additional characteristics of protocol timing like length of mark for a constant mark protocol, where space length determines the bit value. Requires up to 194 additional bytes of program memory. | -| `IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK` | disabled | Saves up to 60 bytes of program memory and 2 bytes RAM. | -| `MARK_EXCESS_MICROS` | 20 | MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, to compensate for the signal forming of different IR receiver modules. | -| `RECORD_GAP_MICROS` | 5000 | Minimum gap between IR transmissions, to detect the end of a protocol.<br/>Must be greater than any space of a protocol e.g. the NEC header space of 4500 µs.<br/>Must be smaller than any gap between a command and a repeat; e.g. the retransmission gap for Sony is around 24 ms.<br/>Keep in mind, that this is the delay between the end of the received command and the start of decoding. | -| `IR_INPUT_IS_ACTIVE_HIGH` | disabled | Enable it if you use a RF receiver, which has an active HIGH output signal. | -| `IR_SEND_PIN` | disabled | If specified (as constant), it reduces program size and improves send timing for AVR. If you want to use a variable to specify send pin e.g. with `setSendPin(uint8_t aSendPinNumber)`, you must not use / disable this macro in your source. | -| `SEND_PWM_BY_TIMER` | disabled | Disables carrier PWM generation in software and use hardware PWM (by timer). Has the advantage of more exact PWM generation, especially the duty cycle (which is not very relevant for most IR receiver circuits), and the disadvantage of using a hardware timer, which in turn is not available for other libraries and to fix the send pin (but not the receive pin) at the [dedicated timer output pin(s)](https://github.com/Arduino-IRremote/Arduino-IRremote#timer-and-pin-usage). Is enabled for ESP32 and RP2040 in all examples, since they support PWM gereration for each pin without using a shared resource (timer). | -| `USE_NO_SEND_PWM` | disabled | Uses no carrier PWM, just simulate an **active low** receiver signal. Used for transferring signal by cable instead of IR. Overrides `SEND_PWM_BY_TIMER` definition. | -| `IR_SEND_DUTY_CYCLE_PERCENT` | 30 | Duty cycle of IR send signal. | -| `USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN` | disabled | Uses or simulates open drain output mode at send pin. **Attention, active state of open drain is LOW**, so connect the send LED between positive supply and send pin! | -| `DISABLE_CODE_FOR_RECEIVER` | disabled | Saves up to 450 bytes program memory and 269 bytes RAM if receiving functionality is not required. | -| `EXCLUDE_EXOTIC_PROTOCOLS` | disabled | Excludes BANG_OLUFSEN, BOSEWAVE, WHYNTER, FAST and LEGO_PF from `decode()` and from sending with `IrSender.write()`. Saves up to 650 bytes program memory. | -| `FEEDBACK_LED_IS_ACTIVE_LOW` | disabled | Required on some boards (like my BluePill and my ESP8266 board), where the feedback LED is active low. | -| `NO_LED_FEEDBACK_CODE` | disabled | Disables the LED feedback code for send and receive. Saves around 100 bytes program memory for receiving, around 500 bytes for sending and halving the receiver ISR (Interrupt Service Routine) processing time. | -| `MICROS_PER_TICK` | 50 | Resolution of the raw input buffer data. Corresponds to 2 pulses of each 26.3 µs at 38 kHz. | -| `TOLERANCE_FOR_DECODERS_MARK_OR_SPACE_MATCHING` | 25 | Relative tolerance (in percent) for matchTicks(), matchMark() and matchSpace() functions used for protocol decoding. | -| `DEBUG` | disabled | Enables lots of lovely debug output. | -| `IR_USE_AVR_TIMER*` | | Selection of timer to be used for generating IR receiving sample interval. | - -These next macros for **TinyIRReceiver** must be defined in your program before the line `#include <TinyIRReceiver.hpp>` to take effect. -| Name | Default value | Description | -|:---|---:|----| -| `IR_RECEIVE_PIN` | 2 | The pin number for TinyIRReceiver IR input, which gets compiled in. | -| `IR_FEEDBACK_LED_PIN` | `LED_BUILTIN` | The pin number for TinyIRReceiver feedback LED, which gets compiled in. | -| `NO_LED_FEEDBACK_CODE` | disabled | Disables the feedback LED function. Saves 14 bytes program memory. | -| `DISABLE_PARITY_CHECKS` | disabled | Disables the addres and command parity checks. Saves 48 bytes program memory. | -| `USE_ONKYO_PROTOCOL` | disabled | Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. | -| `USE_FAST_PROTOCOL` | disabled | Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC. | -| `ENABLE_NEC2_REPEATS` | disabled | Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. | - -The next macro for **IRCommandDispatcher** must be defined in your program before the line `#include <IRCommandDispatcher.hpp>` to take effect. -| `IR_COMMAND_HAS_MORE_THAN_8_BIT` | disabled | Enables mapping and dispatching of IR commands consisting of more than 8 bits. Saves up to 160 bytes program memory and 4 bytes RAM + 1 byte RAM per mapping entry. | - -### Changing include (*.h) files with Arduino IDE -First, use *Sketch > Show Sketch Folder (Ctrl+K)*.<br/> -If you have not yet saved the example as your own sketch, then you are instantly in the right library folder.<br/> -Otherwise you have to navigate to the parallel `libraries` folder and select the library you want to access.<br/> -In both cases the library source and include files are located in the libraries `src` directory.<br/> -The modification must be renewed for each new library version! - -### Modifying compile options / macros with PlatformIO -If you are using PlatformIO, you can define the macros in the *[platformio.ini](https://docs.platformio.org/en/latest/projectconf/section_env_build.html)* file with `build_flags = -D MACRO_NAME` or `build_flags = -D MACRO_NAME=macroValue`. - -### Modifying compile options / macros with Sloeber IDE -If you are using [Sloeber](https://eclipse.baeyens.it) as your IDE, you can easily define global symbols with *Properties > Arduino > CompileOptions*.<br/> - - -<br/> - -# Supported Boards -**Issues and discussions with the content "Is it possible to use this library with the ATTinyXYZ? / board XYZ" without any reasonable explanations will be immediately closed without further notice.**<br/> -<br/> -ATtiny and Digispark boards are only tested with the recommended [ATTinyCore](https://github.com/SpenceKonde/ATTinyCore) using `New Style` pin mapping for the pro board. -- Arduino Uno / Mega / Leonardo / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano etc. -- Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / 3.2 / Teensy-LC - but [limited support](https://forum.pjrc.com/threads/65912-Enable-Continuous-Integration-with-arduino-cli-for-3-party-libraries); Credits: PaulStoffregen (Teensy Team) -- Sanguino -- ATmega8, 48, 88, 168, 328 -- ATmega8535, 16, 32, 164, 324, 644, 1284, -- ATmega64, 128 -- ATmega4809 (Nano every) -- ATtiny3217 (Tiny Core 32 Dev Board) -- ATtiny84, 85, 167 (Digispark + Digispark Pro) -- SAMD21 (Zero, MKR*, **but not SAMD51 and not DUE, the latter is SAM architecture**) -- ESP8266 -- ESP32 (ESP32 C3 since board package 2.0.2 from Espressif) -- Sparkfun Pro Micro -- Nano Every, Uno WiFi Rev2, nRF5 BBC MicroBit, Nano33_BLE -- BluePill with STM32 -- RP2040 based boards (Raspberry Pi Pico, Nano RP2040 Connect etc.) - -For ESP8266/ESP32, [this library](https://github.com/crankyoldgit/IRremoteESP8266) supports an [impressive set of protocols and a lot of air conditioners](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md) - -We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side.<br/> -If you can provide **examples of using a periodic timer for interrupts** for the new board, and the board name for selection in the Arduino IDE, then you have way better chances to get your board supported by IRremote. - -<br/> - -# Timer and pin usage -The **receiver sample interval of 50 µs is generated by a timer**. On many boards this must be a hardware timer. On some boards where a software timer is available, the software timer is used.<br/> -Every pin can be used for receiving. - -The TinyReceiver example uses the **TinyReceiver** library, which can **only receive NEC codes, but does not require any timer** and runs even on a 1 MHz ATtiny85. - -The code for the timer and the **timer selection** is located in [private/IRTimer.hpp](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/private/IRTimer.hpp). It can be adjusted here.<br/> -**Be aware that the hardware timer used for receiving should not be used for analogWrite()!**.<br/> - -| Board/CPU | Receive<br/>& PWM Timers| Hardware-PWM Pin | analogWrite()<br/>pins occupied by timer | -|--------------------------------------------------------------------------|-------------------|---------------------|-----------------------| -| [ATtiny84](https://github.com/SpenceKonde/ATTinyCore) | **1** | **6** | -| [ATtiny85 > 4 MHz](https://github.com/SpenceKonde/ATTinyCore) | **0**, 1 | **0**, 4 | **0**, 1 & 4 | -| [ATtiny88 > 4 MHz](https://github.com/SpenceKonde/ATTinyCore) | **1** | **PB1 / 8** | **PB1 / 8 & PB2 / 9** | -| [ATtiny167 > 4 MHz](https://github.com/SpenceKonde/ATTinyCore) | **1** | **9**, 8 - 15 | **8 - 15** | -| [ATtiny1604](https://github.com/SpenceKonde/megaTinyCore) | **TCB0** | **PA05** | -| [ATtiny1614, ATtiny816](https://github.com/SpenceKonde/megaTinyCore) | **TCA0** | **PA3** | -| [ATtiny3217](https://github.com/SpenceKonde/megaTinyCore) | **TCA0**, TCD | % | -| [ATmega8](https://github.com/MCUdude/MiniCore) | **1** | **9** | -| ATmega168, **ATmega328** | 1, **2** | 9, **3** | 9 & 10, **3 & 11** | -| [ATmega1284](https://github.com/MCUdude/MightyCore) | 1, **2**, 3 | 13, 14, 6 | -| [ATmega164, ATmega324, ATmega644](https://github.com/MCUdude/MightyCore) | 1, **2** | 13, **14** | -| [ATmega8535 ATmega16, ATmega32](https://github.com/MCUdude/MightyCore) | **1** | **13** | -| [ATmega64, ATmega128, ATmega1281, ATmega2561](https://github.com/MCUdude/MegaCore) | **1** | **13** | -| [ATmega8515, ATmega162](https://github.com/MCUdude/MajorCore) | **1** | **13** | -| ATmega1280, ATmega2560 | 1, **2**, 3, 4, 5 | 5, 6, **9**, 11, 46 | -| ATmega4809 | **TCB0** | **A4** | -| Leonardo (Atmega32u4) | 1, 3, **4_HS** | 5, **9**, 13 | -| Zero (SAMD) | **TC3** | \*, **9** | -| [ESP32](http://esp32.net/) | **Ledc chan. 0** | All pins | -| [Sparkfun Pro Micro](https://www.sparkfun.com/products/12640) | 1, **3** | **5**, 9 | -| [Teensy 1.0](https://www.pjrc.com/teensy/pinout.html) | **1** | **17** | 15, 18 | -| [Teensy 2.0](https://www.pjrc.com/teensy/pinout.html) | 1, 3, **4_HS** | 9, **10**, 14 | 12 | -| [Teensy++ 1.0 / 2.0](https://www.pjrc.com/teensy/pinout.html) | 1, **2**, 3 | **1**, 16, 25 | 0 | -| [Teensy-LC](https://www.pjrc.com/teensy/pinout.html) | **TPM1** | **16** | 17 | -| [Teensy 3.0 - 3.6](https://www.pjrc.com/teensy/pinout.html) | **CMT** | **5** | -| [Teensy 4.0 - 4.1](https://www.pjrc.com/teensy/pinout.html) | **FlexPWM1.3** | **8** | 7, 25 | -| [BluePill / STM32F103C8T6](https://github.com/stm32duino/Arduino_Core_STM32) | **3** | % | **PA6 & PA7 & PB0 & PB1** | -| [BluePill / STM32F103C8T6](https://stm32-base.org/boards/STM32F103C8T6-Blue-Pill) | **TIM4** | % | **PB6 & PB7 & PB8 & PB9** | -| [RP2040 / Pi Pico](https://github.com/earlephilhower/arduino-pico) | [default alarm pool](https://raspberrypi.github.io/pico-sdk-doxygen/group__repeating__timer.html) | All pins | No pin | -| [RP2040 / Mbed based](https://github.com/arduino/ArduinoCore-mbed) | Mbed Ticker | All pins | No pin | - -### No timer required for sending -The **send PWM signal** is by default generated by software. **Therefore every pin can be used for sending**. -The PWM pulse length is guaranteed to be constant by using `delayMicroseconds()`. -Take care not to generate interrupts during sending with software generated PWM, otherwise you will get jitter in the generated PWM. -E.g. wait for a former `Serial.print()` statement to be finished by `Serial.flush()`. -Since the Arduino `micros()` function has a resolution of 4 µs at 16 MHz, we always see a small jitter in the signal, which seems to be OK for the receivers. - -| Software generated PWM showing small jitter because of the limited resolution of 4 µs of the Arduino core `micros()` function for an ATmega328 | Detail (ATmega328 generated) showing 30% duty cycle | -|-|-| -|  |  | - -## Incompatibilities to other libraries and Arduino commands like tone() and analogWrite() -If you use a library which requires the same timer as IRremote, you have a problem, since **the timer resource cannot be shared simultaneously** by both libraries. - -### Change timer -The best approach is to change the timer used for IRremote, which can be accomplished by specifying the timer before `#include <IRremote.hpp>`.<br/> -The timer specifications available for your board can be found in [private/IRTimer.hpp](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/private/IRTimer.hpp).<br/> - -```c++ -// Arduino Mega -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4) && !defined(IR_USE_AVR_TIMER5) -//#define IR_USE_AVR_TIMER1 // send pin = pin 11 -#define IR_USE_AVR_TIMER2 // send pin = pin 9 -//#define IR_USE_AVR_TIMER3 // send pin = pin 5 -//#define IR_USE_AVR_TIMER4 // send pin = pin 6 -//#define IR_USE_AVR_TIMER5 // send pin = pin 46 -# endif -``` -Here you see the Arduino Mega board and the available specifications are `IR_USE_AVR_TIMER[1,2,3,4,5]`.<br/> -You **just have to include a line** e.g. `#define IR_USE_AVR_TIMER3` before `#include <IRremote.hpp>` to enable timer 3. - -But be aware that the new timer in turn might be incompatible with other libraries or commands.<br/> -For other boards/platforms you must look for the appropriate section guarded by e.g. `#elif defined(ESP32)`. - -### Stop and start timer -Another approach can be to share the timer **sequentially** if their functionality is used only for a short period of time like for the **Arduino tone() command**. -An example can be seen [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/21b5747a58e9d47c9e3f1beb056d58c875a92b47/examples/ReceiveDemo/ReceiveDemo.ino#L159-L169), where the timer settings for IR receive are restored after the tone has stopped. -For this we must call `IrReceiver.start()` or better `IrReceiver.start(microsecondsOfToneDuration)`.<br/> -This only works since each call to` tone()` completely initializes the timer 2 used by the `tone()` command. - -## Hardware-PWM signal generation for sending -If you define `SEND_PWM_BY_TIMER`, the send PWM signal is forced to be generated by a hardware timer on most platforms.<br/> -By default, the same timer as for the receiver is used.<br/> -Since each hardware timer has its dedicated output pin(s), you must change timer or timer sub-specifications to change PWM output pin. See [private/IRTimer.hpp](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/private/IRTimer.hpp)<br/> -**Exeptions** are currently [ESP32, ARDUINO_ARCH_RP2040, PARTICLE and ARDUINO_ARCH_MBED](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/39bdf8d7bf5b90dc221f8ae9fb3efed9f0a8a1db/examples/SimpleSender/PinDefinitionsAndMore.h#L273), where **PWM generation does not require a timer**. - -## Why do we use 30% duty cycle for sending -We do it according to the statement in the [Vishay datasheet](https://www.vishay.com/docs/80069/circuit.pdf): -- Carrier duty cycle 50 %, peak current of emitter IF = 200 mA, the resulting transmission distance is 25 m. -- Carrier duty cycle 10 %, peak current of emitter IF = 800 mA, the resulting transmission distance is 29 m. - Factor 1.16 -The reason is, that it is not the pure energy of the fundamental which is responsible for the receiver to detect a signal. -Due to automatic gain control and other bias effects, high intensity of the 38 kHz pulse counts more than medium intensity (e.g. 50% duty cycle) at the same total energy. - -<br/> - -# How we decode signals -The IR signal is sampled at a **50 µs interval**. For a constant 525 µs pulse or pause we therefore get 10 or 11 samples, each with 50% probability.<br/> -And believe me, if you send a 525 µs signal, your receiver will output something between around 400 and 700 µs!<br/> -Therefore **we decode by default with a +/- 25% margin** using the formulas [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRremoteInt.h#L376-L399).<br/> -E.g. for the NEC protocol with its 560 µs unit length, we have TICKS_LOW = 8.358 and TICKS_HIGH = 15.0. This means, we accept any value between 8 ticks / 400 µs and 15 ticks / 750 µs (inclusive) as a mark or as a zero space. For a one space we have TICKS_LOW = 25.07 and TICKS_HIGH = 45.0.<br/> -And since the receivers generated marks are longer or shorter than the spaces, we have introduced the [`MARK_EXCESS_MICROS` value]/https://github.com/Arduino-IRremote/Arduino-IRremote#protocolunknown) -to compensate for this receiver (and signal strength as well as ambient light dependent :disappointed: ) specific deviation.<br/> -Welcome to the world of **real world signal processing**. - -<br/> - -# NEC encoding diagrams -Created with sigrok PulseView with IR_NEC decoder by DjordjeMandic.<br/> -8 bit address NEC code - -16 bit address NEC code - - -<br/> - -# Quick comparison of 5 Arduino IR receiving libraries -[Here](https://github.com/crankyoldgit/IRremoteESP8266) you find an **ESP8266/ESP32** version of IRremote with an **[impressive list of supported protocols](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md)**. - -**This is a short comparison and may not be complete or correct.** - -I created this comparison matrix for [myself](https://github.com/ArminJo) in order to choose a small IR lib for my project and to have a quick overview, when to choose which library.<br/> -It is dated from **24.06.2022**. If you have complains about the data or request for extensions, please send a PM or open a discussion. - -| Subject | [IRMP](https://github.com/IRMP-org/IRMP) | [IRLremote](https://github.com/NicoHood/IRLremote) | [IRLib2](https://github.com/cyborg5/IRLib2)<br/>**mostly unmaintained** | [IRremote](https://github.com/Arduino-IRremote/Arduino-IRremote) | [Minimal NEC](https://github.com/Arduino-IRremote/Arduino-IRremote/tree/master/examples/TinyReceiver) | [IRsmallDecoder](https://github.com/LuisMiCa/IRsmallDecoder) -|---------|------|-----------|--------|----------|----------|----------| -| Number of protocols | **50** | Nec + Panasonic + Hash \* | 12 + Hash \* | 17 + PulseDistance + Hash \* | NEC | NEC + RC5 + Sony + Samsung | -| Timing method receive | Timer2 or interrupt for pin 2 or 3 | **Interrupt** | Timer2 or interrupt for pin 2 or 3 | Timer2 | **Interrupt** | **Interrupt** | -| Timing method send | PWM and timing with Timer2 interrupts | Timer2 interrupts | Timer2 and blocking wait | PWM with Timer2 and/or blocking wait with delay<br/>Microseconds() | blocking wait with delay<br/>Microseconds() | % | -| Send pins| All | All | All ? | Timer dependent | All | % | -| Decode method | OnTheFly | OnTheFly | RAM | RAM | OnTheFly | OnTheFly | -| Encode method | OnTheFly | OnTheFly | OnTheFly | OnTheFly or RAM | OnTheFly | % | -| Callback support | x | % | % | x | x | % | -| Repeat handling | Receive + Send (partially) | % | ? | Receive + Send | Receive + Send | Receive | -| LED feedback | x | % | x | x | Receive | % | -| FLASH usage (simple NEC example with 5 prints) | 1820<br/>(4300 for 15 main / 8000 for all 40 protocols)<br/>(+200 for callback)<br/>(+80 for interrupt at pin 2+3)| 1270<br/>(1400 for pin 2+3) | 4830 | 1770 | **900** | ?1100? | -| RAM usage | 52<br/>(73 / 100 for 15 (main) / 40 protocols) | 62 | 334 | 227 | **19** | 29 | -| Supported platforms | **avr, megaavr, attiny, Digispark (Pro), esp8266, ESP32, STM32, SAMD 21, Apollo3<br/>(plus arm and pic for non Arduino IDE)** | avr, esp8266 | avr, SAMD 21, SAMD 51 | avr, attiny, [esp8266](https://github.com/crankyoldgit/IRremoteESP8266), esp32, SAM, SAMD | **All platforms with attach<br/>Interrupt()** | **All platforms with attach<br/>Interrupt()** | -| Last library update | 6/2022 | 4/2018 | 3/2022 | 6/2022 | 6/2022 | 2/2022 | -| Remarks | Decodes 40 protocols concurrently.<br/>39 Protocols to send.<br/>Work in progress. | Only one protocol at a time. | Consists of 5 libraries. **Project containing bugs - 45 issues, no reaction for at least one year.** | Universal decoder and encoder.<br/>Supports **Pronto** codes and sending of raw timing values. | Requires no timer. | Requires no timer. | - -\* The Hash protocol gives you a hash as code, which may be sufficient to distinguish your keys on the remote, but may not work with some protocols like Mitsubishi - -<br/> - -# Useful links -- [List of public IR code databases](http://www.harctoolbox.org/IR-resources.html) -- [LIRC database](http://lirc-remotes.sourceforge.net/remotes-table.html) -- [IRMP list of IR protocols](https://www.mikrocontroller.net/articles/IRMP_-_english#IR_Protocols) -- [IRDB database for IR codes](https://github.com/probonopd/irdb/tree/master/codes) -- [IRP definition files for IR protocols](https://github.com/probonopd/MakeHex/tree/master/protocols) -- [IR Remote Control Theory and some protocols (upper right hamburger icon)](https://www.sbprojects.net/knowledge/ir/) -- [Interpreting Decoded IR Signals (v2.45)](http://www.hifi-remote.com/johnsfine/DecodeIR.html) -- ["Recording long Infrared Remote control signals with Arduino"](https://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino) -- The original blog post of Ken Shirriff [A Multi-Protocol Infrared Remote Library for the Arduino](http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html) -- [Vishay datasheet](https://www.vishay.com/docs/80069/circuit.pdf) - -# License -Up to the version 2.7.0, the License is GPLv2. -From the version 2.8.0, the license is the MIT license. - -# Copyright -Initially coded 2009 Ken Shirriff http://www.righto.com<br/> -Copyright (c) 2016-2017 Rafi Khan<br/> -Copyright (c) 2020-2023 [Armin Joachimsmeyer](https://github.com/ArminJo) diff --git a/IRremote/arduino-irremote.sublime-workspace b/IRremote/arduino-irremote.sublime-workspace deleted file mode 100644 index f536803d06d9cbfcc5989ee754332b7e81a03ded..0000000000000000000000000000000000000000 --- a/IRremote/arduino-irremote.sublime-workspace +++ /dev/null @@ -1,240 +0,0 @@ -{ - "auto_complete": - { - "selected_items": - [ - [ - "vb", - "vboMatrix" - ] - ] - }, - "buffers": - [ - ], - "build_system": "", - "build_system_choices": - [ - ], - "build_varint": "", - "command_palette": - { - "height": 275.0, - "last_filter": "blame", - "selected_items": - [ - [ - "blame", - "Git: Blame" - ], - [ - "install", - "Package Control: Install Package" - ], - [ - "diff", - "Git: Diff Current File" - ], - [ - "js", - "Set Syntax: JavaScript" - ], - [ - "i", - "Package Control: Install Package" - ], - [ - "instal", - "Package Control: Install Package" - ] - ], - "width": 510.0 - }, - "console": - { - "height": 126.0, - "history": - [ - "import urllib.request,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa1548d1514676163dafc88'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)" - ] - }, - "distraction_free": - { - "menu_visible": true, - "show_minimap": false, - "show_open_files": false, - "show_tabs": false, - "side_bar_visible": false, - "status_bar_visible": false - }, - "expanded_folders": - [ - "/C/Users/Rafi Khan/Documents/Arduino/libraries/Arduino-IRremote" - ], - "file_history": - [ - "/C/Users/Rafi Khan/Documents/Arduino/libraries/Arduino-IRremote/changelog.md", - "/C/Users/Rafi Khan/Documents/Development/Arduino-IRremote/arduino-irremote.sublime-project", - "/C/Users/Rafi Khan/Documents/Development/Arduino-IRremote/.gitignore", - "/C/Users/Rafi Khan/Documents/Development/magic/README.md", - "/C/Users/Rafi Khan/Documents/Development/magic/shader.frag", - "/C/Users/Rafi Khan/Documents/Development/magic/package.json", - "/C/Users/Rafi Khan/Documents/Development/magic/block.js", - "/C/Users/Rafi Khan/Documents/Development/magic/chunker.js", - "/C/Users/Rafi Khan/Documents/Development/magic/index.js", - "/C/Users/Rafi Khan/Documents/Development/magic/blocks", - "/C/Users/Rafi Khan/AppData/Roaming/Sublime Text 3/Packages/User/Preferences.sublime-settings", - "/C/Users/Rafi Khan/Documents/Development/magic/shader.vert", - "/C/Users/Rafi Khan/Documents/Development/magic/magic.sublime-project", - "/C/Users/Rafi Khan/Documents/Development/magic/node_modules/browserify/node_modules/syntax-error/node_modules/acorn/.tern-project", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/supermarket.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/takingavacation.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/TipCalculator.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/battleship.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/exam.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/pyglatin.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/student.py" - ], - "find": - { - "height": 28.0 - }, - "find_in_files": - { - "height": 0.0, - "where_history": - [ - ] - }, - "find_state": - { - "case_sensitive": false, - "find_history": - [ - "i", - "Direction", - ";", - ";\n", - "north", - "cubeMatrix", - ")\n", - "vec3.set", - "f", - ";", - "();\n", - "render", - "this", - "y" - ], - "highlight": true, - "in_selection": false, - "preserve_case": false, - "regex": false, - "replace_history": - [ - ], - "reverse": false, - "show_context": true, - "use_buffer2": true, - "whole_word": false, - "wrap": true - }, - "groups": - [ - { - "sheets": - [ - ] - } - ], - "incremental_find": - { - "height": 28.0 - }, - "input": - { - "height": 66.0 - }, - "layout": - { - "cells": - [ - [ - 0, - 0, - 1, - 1 - ] - ], - "cols": - [ - 0.0, - 1.0 - ], - "rows": - [ - 0.0, - 1.0 - ] - }, - "menu_visible": true, - "output.find_results": - { - "height": 0.0 - }, - "pinned_build_system": "", - "project": "arduino-irremote.sublime-project", - "replace": - { - "height": 52.0 - }, - "save_all_on_build": true, - "select_file": - { - "height": 0.0, - "last_filter": "", - "selected_items": - [ - [ - "json", - "package.json" - ], - [ - "inde", - "index.js" - ] - ], - "width": 0.0 - }, - "select_project": - { - "height": 0.0, - "last_filter": "", - "selected_items": - [ - ], - "width": 0.0 - }, - "select_symbol": - { - "height": 0.0, - "last_filter": "", - "selected_items": - [ - ], - "width": 0.0 - }, - "selected_group": 0, - "settings": - { - }, - "show_minimap": true, - "show_open_files": false, - "show_tabs": true, - "side_bar_visible": true, - "side_bar_width": 150.0, - "status_bar_visible": true, - "template_settings": - { - } -} diff --git a/IRremote/boarddefs.h b/IRremote/boarddefs.h deleted file mode 100644 index 5c49465ef52bb3b6a933c6fc5e28907ca53888e0..0000000000000000000000000000000000000000 --- a/IRremote/boarddefs.h +++ /dev/null @@ -1,653 +0,0 @@ -//****************************************************************************** -// IRremote -// Version 2.0.1 June, 2015 -// Copyright 2009 Ken Shirriff -// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html - -// This file contains all board specific information. It was previously contained within -// IRremoteInt.h - -// Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers -// -// Interrupt code based on NECIRrcv by Joe Knapp -// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 -// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ -// -// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) -// Whynter A/C ARC-110WD added by Francesco Meschia -//****************************************************************************** - -#ifndef boarddefs_h -#define boarddefs_h - -// Define some defaults, that some boards may like to override -// (This is to avoid negative logic, ! DONT_... is just awkward.) - -// This board has/needs the avr/interrupt.h -#define HAS_AVR_INTERRUPT_H - -// Define if sending is supported -#define SENDING_SUPPORTED - -// If defined, a standard enableIRIn function will be define. -// Undefine for boards supplying their own. -#define USE_DEFAULT_ENABLE_IR_IN - -// Duty cycle in percent for sent signals. Presently takes effect only with USE_SOFT_CARRIER -#define DUTY_CYCLE 50 - -// If USE_SOFT_CARRIER, this amount (in micro seconds) is subtracted from the -// on-time of the pulses. -#define PULSE_CORRECTION 3 - -// digitalWrite is supposed to be slow. If this is an issue, define faster, -// board-dependent versions of these macros SENDPIN_ON(pin) and SENDPIN_OFF(pin). -// Portable, possibly slow, default definitions are given at the end of this file. -// If defining new versions, feel free to ignore the pin argument if it -// is not configurable on the current board. - -//------------------------------------------------------------------------------ -// Defines for blinking the LED -// - -#if defined(CORE_LED0_PIN) -# define BLINKLED CORE_LED0_PIN -# define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH)) -# define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW)) - -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define BLINKLED 13 -# define BLINKLED_ON() (PORTB |= B10000000) -# define BLINKLED_OFF() (PORTB &= B01111111) - -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -# define BLINKLED 0 -# define BLINKLED_ON() (PORTD |= B00000001) -# define BLINKLED_OFF() (PORTD &= B11111110) - -#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) -# define BLINKLED LED_BUILTIN -# define BLINKLED_ON() (digitalWrite(LED_BUILTIN, HIGH)) -# define BLINKLED_OFF() (digitalWrite(LED_BUILTIN, LOW)) - -# define USE_SOFT_CARRIER - // Define to use spin wait instead of delayMicros() -//# define USE_SPIN_WAIT -# undef USE_DEFAULT_ENABLE_IR_IN - - // The default pin used used for sending. -# define SEND_PIN 9 - -#elif defined(ESP32) - // No system LED on ESP32, disable blinking by NOT defining BLINKLED - - // avr/interrupt.h is not present -# undef HAS_AVR_INTERRUPT_H - - // Sending not implemented -# undef SENDING_SUPPORTED# - - // Supply own enbleIRIn -# undef USE_DEFAULT_ENABLE_IR_IN - -#else -# define BLINKLED 13 -# define BLINKLED_ON() (PORTB |= B00100000) -# define BLINKLED_OFF() (PORTB &= B11011111) -#endif - -//------------------------------------------------------------------------------ -// CPU Frequency -// -#ifdef F_CPU -# define SYSCLOCK F_CPU // main Arduino clock -#else -# define SYSCLOCK 16000000 // main Arduino clock -#endif - -// microseconds per clock interrupt tick -#define USECPERTICK 50 - -//------------------------------------------------------------------------------ -// Define which timer to use -// -// Uncomment the timer you wish to use on your board. -// If you are using another library which uses timer2, you have options to -// switch IRremote to use a different timer. -// - -// Arduino Mega -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - //#define IR_USE_TIMER1 // tx = pin 11 - #define IR_USE_TIMER2 // tx = pin 9 - //#define IR_USE_TIMER3 // tx = pin 5 - //#define IR_USE_TIMER4 // tx = pin 6 - //#define IR_USE_TIMER5 // tx = pin 46 - -// Teensy 1.0 -#elif defined(__AVR_AT90USB162__) - #define IR_USE_TIMER1 // tx = pin 17 - -// Teensy 2.0 -#elif defined(__AVR_ATmega32U4__) - //#define IR_USE_TIMER1 // tx = pin 14 - //#define IR_USE_TIMER3 // tx = pin 9 - #define IR_USE_TIMER4_HS // tx = pin 10 - -// Teensy 3.0 / Teensy 3.1 -#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) - #define IR_USE_TIMER_CMT // tx = pin 5 - -// Teensy-LC -#elif defined(__MKL26Z64__) - #define IR_USE_TIMER_TPM1 // tx = pin 16 - -// Teensy++ 1.0 & 2.0 -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) - //#define IR_USE_TIMER1 // tx = pin 25 - #define IR_USE_TIMER2 // tx = pin 1 - //#define IR_USE_TIMER3 // tx = pin 16 - -// MightyCore - ATmega1284 -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) - //#define IR_USE_TIMER1 // tx = pin 13 - #define IR_USE_TIMER2 // tx = pin 14 - //#define IR_USE_TIMER3 // tx = pin 6 - -// MightyCore - ATmega164, ATmega324, ATmega644 -#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) - //#define IR_USE_TIMER1 // tx = pin 13 - #define IR_USE_TIMER2 // tx = pin 14 - -//MegaCore - ATmega64, ATmega128 -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) - #define IR_USE_TIMER1 // tx = pin 13 - -// MightyCore - ATmega8535, ATmega16, ATmega32 -#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) - #define IR_USE_TIMER1 // tx = pin 13 - -// Atmega8 -#elif defined(__AVR_ATmega8__) - #define IR_USE_TIMER1 // tx = pin 9 - -// ATtiny84 -#elif defined(__AVR_ATtiny84__) - #define IR_USE_TIMER1 // tx = pin 6 - -//ATtiny85 -#elif defined(__AVR_ATtiny85__) - #define IR_USE_TIMER_TINY0 // tx = pin 1 - -#elif defined(ESP32) - #define IR_TIMER_USE_ESP32 - -#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) - #define TIMER_PRESCALER_DIV 64 - -#else -// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc -// ATmega48, ATmega88, ATmega168, ATmega328 - //#define IR_USE_TIMER1 // tx = pin 9 - #define IR_USE_TIMER2 // tx = pin 3 - -#endif - -//------------------------------------------------------------------------------ -// Defines for Timer - -//--------------------------------------------------------- -// Timer2 (8 bits) -// -#if defined(IR_USE_TIMER2) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) -#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) -#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) -#define TIMER_DISABLE_INTR (TIMSK2 = 0) -#define TIMER_INTR_NAME TIMER2_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR2A = _BV(WGM20); \ - TCCR2B = _BV(WGM22) | _BV(CS20); \ - OCR2A = pwmval; \ - OCR2B = pwmval / 3; \ -}) - -#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) - -//----------------- -#if (TIMER_COUNT_TOP < 256) -# define TIMER_CONFIG_NORMAL() ({ \ - TCCR2A = _BV(WGM21); \ - TCCR2B = _BV(CS20); \ - OCR2A = TIMER_COUNT_TOP; \ - TCNT2 = 0; \ - }) -#else -# define TIMER_CONFIG_NORMAL() ({ \ - TCCR2A = _BV(WGM21); \ - TCCR2B = _BV(CS21); \ - OCR2A = TIMER_COUNT_TOP / 8; \ - TCNT2 = 0; \ - }) -#endif - -//----------------- -#if defined(CORE_OC2B_PIN) -# define SEND_PIN CORE_OC2B_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define SEND_PIN 9 // Arduino Mega -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) -# define SEND_PIN 14 // MightyCore -#else -# define SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc -#endif // ATmega48, ATmega88, ATmega168, ATmega328 - -//--------------------------------------------------------- -// Timer1 (16 bits) -// -#elif defined(IR_USE_TIMER1) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) -#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) - -//----------------- -#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) -# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) -# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) -#else -# define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) -# define TIMER_DISABLE_INTR (TIMSK1 = 0) -#endif - -//----------------- -#define TIMER_INTR_NAME TIMER1_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR1A = _BV(WGM11); \ - TCCR1B = _BV(WGM13) | _BV(CS10); \ - ICR1 = pwmval; \ - OCR1A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR1A = 0; \ - TCCR1B = _BV(WGM12) | _BV(CS10); \ - OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT1 = 0; \ -}) - -//----------------- -#if defined(CORE_OC1A_PIN) -# define SEND_PIN CORE_OC1A_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define SEND_PIN 11 // Arduino Mega -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) -# define SEND_PIN 13 // MegaCore -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) -# define SEND_PIN 13 // MightyCore -#elif defined(__AVR_ATtiny84__) -# define SEND_PIN 6 -#else -# define SEND_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc -#endif // ATmega48, ATmega88, ATmega168, ATmega328 - -//--------------------------------------------------------- -// Timer3 (16 bits) -// -#elif defined(IR_USE_TIMER3) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) -#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) -#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) -#define TIMER_DISABLE_INTR (TIMSK3 = 0) -#define TIMER_INTR_NAME TIMER3_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR3A = _BV(WGM31); \ - TCCR3B = _BV(WGM33) | _BV(CS30); \ - ICR3 = pwmval; \ - OCR3A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR3A = 0; \ - TCCR3B = _BV(WGM32) | _BV(CS30); \ - OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT3 = 0; \ -}) - -//----------------- -#if defined(CORE_OC3A_PIN) -# define SEND_PIN CORE_OC3A_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define SEND_PIN 5 // Arduino Mega -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) -# define SEND_PIN 6 // MightyCore -#else -# error "Please add OC3A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer4 (10 bits, high speed option) -// -#elif defined(IR_USE_TIMER4_HS) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) -#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) -#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) -#define TIMER_DISABLE_INTR (TIMSK4 = 0) -#define TIMER_INTR_NAME TIMER4_OVF_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR4A = (1<<PWM4A); \ - TCCR4B = _BV(CS40); \ - TCCR4C = 0; \ - TCCR4D = (1<<WGM40); \ - TCCR4E = 0; \ - TC4H = pwmval >> 8; \ - OCR4C = pwmval; \ - TC4H = (pwmval / 3) >> 8; \ - OCR4A = (pwmval / 3) & 255; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR4A = 0; \ - TCCR4B = _BV(CS40); \ - TCCR4C = 0; \ - TCCR4D = 0; \ - TCCR4E = 0; \ - TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ - OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ - TC4H = 0; \ - TCNT4 = 0; \ -}) - -//----------------- -#if defined(CORE_OC4A_PIN) -# define SEND_PIN CORE_OC4A_PIN // Teensy -#elif defined(__AVR_ATmega32U4__) -# define SEND_PIN 13 // Leonardo -#else -# error "Please add OC4A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer4 (16 bits) -// -#elif defined(IR_USE_TIMER4) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) -#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) -#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) -#define TIMER_DISABLE_INTR (TIMSK4 = 0) -#define TIMER_INTR_NAME TIMER4_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR4A = _BV(WGM41); \ - TCCR4B = _BV(WGM43) | _BV(CS40); \ - ICR4 = pwmval; \ - OCR4A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR4A = 0; \ - TCCR4B = _BV(WGM42) | _BV(CS40); \ - OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT4 = 0; \ -}) - -//----------------- -#if defined(CORE_OC4A_PIN) -# define SEND_PIN CORE_OC4A_PIN -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define SEND_PIN 6 // Arduino Mega -#else -# error "Please add OC4A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer5 (16 bits) -// -#elif defined(IR_USE_TIMER5) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) -#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) -#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) -#define TIMER_DISABLE_INTR (TIMSK5 = 0) -#define TIMER_INTR_NAME TIMER5_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR5A = _BV(WGM51); \ - TCCR5B = _BV(WGM53) | _BV(CS50); \ - ICR5 = pwmval; \ - OCR5A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR5A = 0; \ - TCCR5B = _BV(WGM52) | _BV(CS50); \ - OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT5 = 0; \ -}) - -//----------------- -#if defined(CORE_OC5A_PIN) -# define SEND_PIN CORE_OC5A_PIN -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define SEND_PIN 46 // Arduino Mega -#else -# error "Please add OC5A pin number here\n" -#endif - -//--------------------------------------------------------- -// Special carrier modulator timer -// -#elif defined(IR_USE_TIMER_CMT) - -#define TIMER_RESET ({ \ - uint8_t tmp __attribute__((unused)) = CMT_MSC; \ - CMT_CMD2 = 30; \ -}) - -#define TIMER_ENABLE_PWM do { \ - CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \ -} while(0) - -#define TIMER_DISABLE_PWM do { \ - CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \ -} while(0) - -#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) -#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) -#define TIMER_INTR_NAME cmt_isr - -//----------------- -#ifdef ISR -# undef ISR -#endif -#define ISR(f) void f(void) - -//----------------- -#define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000) -#if F_BUS < 8000000 -#error IRremote requires at least 8 MHz on Teensy 3.x -#endif - -//----------------- -#define TIMER_CONFIG_KHZ(val) ({ \ - SIM_SCGC4 |= SIM_SCGC4_CMT; \ - SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ - CMT_PPS = CMT_PPS_DIV - 1; \ - CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \ - CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \ - CMT_CMD1 = 0; \ - CMT_CMD2 = 30; \ - CMT_CMD3 = 0; \ - CMT_CMD4 = 0; \ - CMT_OC = 0x60; \ - CMT_MSC = 0x01; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - SIM_SCGC4 |= SIM_SCGC4_CMT; \ - CMT_PPS = CMT_PPS_DIV - 1; \ - CMT_CGH1 = 1; \ - CMT_CGL1 = 1; \ - CMT_CMD1 = 0; \ - CMT_CMD2 = 30; \ - CMT_CMD3 = 0; \ - CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \ - CMT_OC = 0; \ - CMT_MSC = 0x03; \ -}) - -#define SEND_PIN 5 - -// defines for TPM1 timer on Teensy-LC -#elif defined(IR_USE_TIMER_TPM1) -#define TIMER_RESET FTM1_SC |= FTM_SC_TOF; -#define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE -#define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE -#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1) -#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1) -#define TIMER_INTR_NAME ftm1_isr -#ifdef ISR -#undef ISR -#endif -#define ISR(f) void f(void) -#define TIMER_CONFIG_KHZ(val) ({ \ - SIM_SCGC6 |= SIM_SCGC6_TPM1; \ - FTM1_SC = 0; \ - FTM1_CNT = 0; \ - FTM1_MOD = (F_PLL/2000) / val - 1; \ - FTM1_C0V = (F_PLL/6000) / val - 1; \ - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \ -}) -#define TIMER_CONFIG_NORMAL() ({ \ - SIM_SCGC6 |= SIM_SCGC6_TPM1; \ - FTM1_SC = 0; \ - FTM1_CNT = 0; \ - FTM1_MOD = (F_PLL/40000) - 1; \ - FTM1_C0V = 0; \ - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \ -}) -#define SEND_PIN 16 - -// defines for timer_tiny0 (8 bits) -#elif defined(IR_USE_TIMER_TINY0) -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1)) -#define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1))) -#define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A)) -#define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A))) -#define TIMER_INTR_NAME TIMER0_COMPA_vect -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR0A = _BV(WGM00); \ - TCCR0B = _BV(WGM02) | _BV(CS00); \ - OCR0A = pwmval; \ - OCR0B = pwmval / 3; \ -}) -#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) -#if (TIMER_COUNT_TOP < 256) -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR0A = _BV(WGM01); \ - TCCR0B = _BV(CS00); \ - OCR0A = TIMER_COUNT_TOP; \ - TCNT0 = 0; \ -}) -#else -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR0A = _BV(WGM01); \ - TCCR0B = _BV(CS01); \ - OCR0A = TIMER_COUNT_TOP / 8; \ - TCNT0 = 0; \ -}) -#endif - -#define SEND_PIN 1 /* ATtiny85 */ - -//--------------------------------------------------------- -// ESP32 (ESP8266 should likely be added here too) -// - -// ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing -// them out in the common code, they are defined to no-op. This allows the code to compile -// (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written -// for that -- merlin -// As a warning, sending timing specific code from an ESP32 can be challenging if you need 100% -// reliability because the arduino code may be interrupted and cause your sent waveform to be the -// wrong length. This is specifically an issue for neopixels which require 800Khz resolution. -// IR may just work as is with the common code since it's lower frequency, but if not, the other -// way to do this on ESP32 is using the RMT built in driver like in this incomplete library below -// https://github.com/ExploreEmbedded/ESP32_RMT -#elif defined(IR_TIMER_USE_ESP32) - -#define TIMER_RESET - -#ifdef ISR -# undef ISR -#endif -#define ISR(f) void IRTimer() - -#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) -// use timer 3 hardcoded at this time - -#define TIMER_RESET -#define TIMER_ENABLE_PWM // Not presently used -#define TIMER_DISABLE_PWM -#define TIMER_ENABLE_INTR NVIC_EnableIRQ(TC3_IRQn) // Not presently used -#define TIMER_DISABLE_INTR NVIC_DisableIRQ(TC3_IRQn) -#define TIMER_INTR_NAME TC3_Handler // Not presently used -#define TIMER_CONFIG_KHZ(f) - -#ifdef ISR -# undef ISR -#endif -#define ISR(f) void irs() - -//--------------------------------------------------------- -// Unknown Timer -// -#else -# error "Internal code configuration error, no known IR_USE_TIMER# defined\n" -#endif - -// Provide default definitions, portable but possibly slower than necessary. -#ifndef SENDPIN_ON -#define SENDPIN_ON(pin) digitalWrite(pin, HIGH) -#endif - -#ifndef SENDPIN_OFF -#define SENDPIN_OFF(pin) digitalWrite(pin, LOW) -#endif - -#endif // ! boarddefs_h diff --git a/IRremote/changelog.md b/IRremote/changelog.md deleted file mode 100644 index c1bbb52bfc22522a808ed0b792f226c3c4cf89e1..0000000000000000000000000000000000000000 --- a/IRremote/changelog.md +++ /dev/null @@ -1,354 +0,0 @@ -# Changelog -The latest version may not be released! -See also the commit log at github: https://github.com/Arduino-IRremote/Arduino-IRremote/commits/master - -# 4.2.0 -- The old decode function is renamed to decode_old(decode_results *aResults). decode (decode_results *aResults) is only available in IRremote.h and prints a message. -- Added DECODE_ONKYO, to force 16 bit command and data decoding. -- Enable Bang&Olufsen 455 kHz if SEND_PWM_BY_TIMER is defined. -- Fixed bug: TinyReceiver throwing ISR not in IRAM on ESP8266. -- Usage of ATTinyCore pin numbering scheme e.g. PIN_PB2. -- Added ARDUINO_ARCH_NRF52 to support Seeed XIAO nRF52840 Sense. -- First untested support of Uno R4. -- Extraced version macros to IRVersion.h. - -## 4.1.2 -- Workaround for ESP32 RTOS delay() timing bug influencing the mark() function. - -## 4.1.1 -- SAMD51 use timer3 if timer5 not available. -- Disabled #define LOCAL_DEBUG in IRReceive.hpp, which was accidently enabled at 4.1.0. - -## 4.1.0 -- Fixed bug in printing durations > 64535 in printIRResultRawFormatted(). -- Narrowed constraints for RC5 RC6 number of bits. -- Changed the first parameter of printTinyReceiverResultMinimal() to &Serial. -- Removed 3 Serial prints for deprecation warnings to fix #1094. -- Version 1.2.0 of TinyIR. Now FAST protocol with 40 ms period and shorter header space. -- Removed field "bool hasStopBit" and parameter "bool aSendStopBit" from PulseDistanceWidthProtocolConstants structure and related functions. -- Changed a lot of "unsigned int" types to "uint16_t" types. -- Improved overflow handling. -- Improved software PWM generation. -- Added FAST protocol. -- Improved handling of PULSE_DISTANCE + PULSE_WIDTH protocols. -- New example ReceiveAndSendDistanceWidth. -- Removed the automatic restarting of the receiver timer after sending with SEND_PWM_BY_TIMER enabled. -- Split ISR into ISR and function IRPinChangeInterruptHandler(). -- Added functions addTicksToInternalTickCounter() and addMicrosToInternalTickCounter(). - -## 4.0.0 -- Added decoding of PulseDistanceWidth protocols and therefore changed function decodeDistance() to decodeDistanceWidth() and filename ir_DistanceProtocol.hpp to ir_DistanceWidthProtocol.hpp. -- Removed static function printIRSendUsage(), but kept class function printIRSendUsage(). -- Changed type of decodedRawData and decodedRawDataArray which is now 64 bit for 32 bit platforms. -- Added receiver callback functionality and registerReceiveCompleteCallback() function. -- Introduced common structure PulseDistanceWidthProtocolConstants. -- Where possible, changed all send and decode functions to use PulseDistanceWidthProtocolConstants. -- Improved MSB/LSB handling -- New convenience fuctions bitreverse32Bit() and bitreverseOneByte(). -- Improved Magiquest protocol. -- Fix for #1028 - Prevent long delay caused by overflow when frame duration < repeat period - Thanks to Stephen Humphries! -- Support for ATtiny816 - Thanks to elockman. -- Added Bang&Olufsen protocol. #1030. -- Third parameter of function "void begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin)" is not optional anymore and this function is now only available if IR_SEND_PIN is not defined. #1033. -- Fixed bug in sendSony() for command parameter > 0x7F; -- Fixed bug with swapped LG2 header mark and space. -- Disabled strict checks while decoding. They can be enabled by defining DECODE_STRICT_CHECKS. -- Merged the 2 decode pulse width and distance functions. -- Changed macro names _REPEAT_SPACE to _REPEAT_DISTANCE. -- Improved TinyIRReceiver,added FAST protocol for it and added TinyIRSender.hpp and TinySender example, renamed TinyReceiver.h to TinyIR.h. -- Added DISABLE_CODE_FOR_RECEIVER to save program memory and RAM if receiving functionality is not required. -- Extracted protocol functions used by receive and send to IRProtocol.hpp. -- Analyzed Denon code table and therefore changed Denon from MSB to LSB first. -- Renamed sendRC6(aRawData...) to sendRC6Raw( aRawData...). -- Support for seeduino which lacks the print(unsigned long long...) method. Thanks to sklott https://stackoverflow.com/users/11680056/sklott -- Added support for attiny1614 by Joe Ostrander. -- Fixed SEND_PWM_BY_TIMER for ATtiny167 thanks to freskpe. -- Improved SHARP repeat decoding. -- Replaced macros TIMER_EN/DISABLE_RECEIVE_INTR and EN/DISABLE_SEND_PWM_BY_TIMER by functions. -- Added SAMSUNG48 protocol and sendSamsung48() function. - -## 3.9.0 -- Improved documentation with the help of [ElectronicsArchiver}(https://github.com/ElectronicsArchiver). -- Added NEC2 protocol. -- Improved Magiquest protocol. -- Renamed sendSamsungRepeat() to sendSamsungLGRepeat(). -- Added function sendPulseDistanceWidth(). -- Improved repeat detection for some protocols. - -## 3.8.0 -- Changed Samsung repeat handling. Old handling is available as SamsungLG. -- Added function printIRSendUsage(). -- Reduced output size and improved format of printIRResultRawFormatted() to fasten up output (and getting repeats properly decoded). -- Fixed Bug in sendDenonRaw() and improved decodeDenon(). -- Fixed potential bug in SendBiphase data for 1 bit. -- Fixed bug in send for RP4020. -- Fixed pin mapping problems especially for Teensy 2.0. -- Added support for decoding of "special" NEC repeats. -- Added SAMD51 support. -- Improved pin mapping for TinyReceiver. - -## 3.7.1 -- SendRaw now supports bufferlenght > 255. -- Improved DistanceProtocol decoder output. -- Fixed ESP32 send bug for 2.x ESP32 cores. - -## 3.7.0 -- Changed TOLERANCE to TOLERANCE_FOR_DECODERS_MARK_OR_SPACE_MATCHING and documented it. -- Changed last uint8_t to uint_fast8_t and uint16_t to unsigned integer. -- Improved MagiQuest protocol. -- Improved prints and documentation. -- Added IrReceiver.restartAfterSend() and inserted it in every send(). Closes #989 -- Use IRAM_ATTR instead of deprecated ICACHE_RAM_ATTR for ESP8266. -- Removed pulse width decoding from ir_DistanceProtocol. - -## 3.6.1 -- Switched Bose internal protocol timing for 0 and 1 -> old 1 timing is now 0 and vice versa. - -## 3.6.0 -- Separated enable flag of send and receive feedback LED. Inspired by PR#970 from luvaihassanali. -- RP2040 support added. -- Refactored IRTimer.hpp. -- Refactored IR_SEND_PIN and IrSender.sendPin handling. -- Renamed IR_SEND_DUTY_CYCLE to IR_SEND_DUTY_CYCLE_PERCENT. -- Fixed bugs for SEND_PWM_BY_TIMER active. - -## 3.5.2 -- Improved support for Teensy boards by Paul Stoffregen. - -## 3.5.1 -- Renamed INFO_PRINT to IR_INFO_PRINT as well as for DEBUG and TRACE. -- Fixed error with DEBUG in TinyIRReceiver.hpp. -- Support for ATmega88 see issue #923. Thanks to Dolmant. -- NO_LED_FEEDBACK_CODE replaces and extends DISABLE_LED_FEEDBACK_FOR_RECEIVE. -- Removed NO_LEGACY_COMPATIBILITY macro, it was useless now. -- Fix ESP32 send bug see issue #927. - -## 3.5.0 -- Improved ir_DistanceProtocol. -- Tone for ESP32. -- last phase renamed *.cpp.h to .hpp. -- No deprecation print for ATtinies. -- Renamed ac_LG.cpp to ac_LG.hpp. -- Maintained MagiQuest by E. Stuart Hicks. -- Improved print Pronto by Asuki Kono. -- Added printActiveIRProtocols() function. -- Used IR_SEND_PIN to reduce code size and improved send timing for AVR. - -## 3.4.0 -- Added LG2 protocol. -- Added ATtiny167 (Digispark Pro) support. -- Renamed *.cpp.h to .hpp. -- organized carrier frequencies. -- Compiler switch USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN added. -- Moved blink13() back to IRrecv class. -- Added Kaseikyo convenience functions like sendKaseikyo_Denon(). -- Improved / adjusted LG protocol and added class Aircondition_LG based on real hardware supplied by makerspace 201 (https://wiki.hackerspaces.org/ZwoNullEins) from Cologne. -- Improved universal decoder for pulse distance protocols to support more than 32 bits. -- Added mbed support. - -## 3.3.0 -- Fix errors if LED_BUILTIN is not defined. -- Fixed error for AVR timer1. Thanks to alexbarcelo. -- New example IRremoteExtensionTest. -- Enabled megaAVR 0-series devices. -- Added universal decoder for pulse distance protocols. - -## 3.2.0 -- Fix for ESP32 send Error, removed `USE_SOFT_SEND_PWM` macro. -- Added Onkyo protocol. -- Support for old 2.x code by backwards compatible `decode(decode_results *aResults)` function. -- Removed USE_OLD_DECODE macro and added NO_LEGACY_COMPATIBILITY macro. -- Added ATtiny1604 support. -- New SendAndReceive example. -- Added ESP8266 support. -- Extended DEBUG output. - -## 3.1.0 -- Generation of PWM by software is active by default. -- Removed decode_results results. -- Renamed most irparams_struct values. -- Fixed LG send bug and added unit test. -- Replaced `#define DECODE_NEC 1/0` by defining/not defining. -- Use LED_BUILTIN instead of FEEDBACK_LED if FeedbackLEDPin is 0. -- Use F_CPU instead of SYSCLOCK. -- Removed SENDPIN_ON and SENDPIN_OFF macros. - -- Refactored board specific code for timer and feedback LED. -- Extracted common LED feedback functions and implemented feedback for send. -- MATCH_MARK() etc. now available as matchMark(). -- Added STM32F1 by (by Roger Clark) support. -- Added stm32 (by ST) support. Thanks to Paolo Malaspina. -- Added ATtiny88 support. - -## 3.0.2 -- Bug fix for USE_OLD_DECODE. -- Increase RECORD_GAP_MICROS to 11000. -- Fix overflow message. (#793). -- Improved handling for HASH decoder. -- Tested for ATtiny85. -- Added `printIRResultMinimal()`. -- Added missing IRAM_ATTR for ESP32. -- Adapted to TinyCore 0.0.7. -- Fixed decodeSony 20 bit bug #811. -- Replaced delayMicroseconds with customDelayMicroseconds and removed NoInterrupt() for send functions, removed SPIN_WAIT macro, sleepMicros() and sleepUntilMicros(). -- Fixed LG checksum error. -- Fixed JVC repeat error. - -## 3.0.0 + 3.0.1 2021/02 -- New LSB first decoders are default. -- Added SendRaw with byte data. -- Fixed resume bug if irparams.rawlen >= RAW_BUFFER_LENGTH. Thanks to Iosif Peterfi -- Added `dumpPronto(String *aString, unsigned int frequency)` with String object as argument. Thanks to Iosif Peterfi -- Removed Test2 example. -- Fixed swapped cases in `getProtocolString()`. Thanks to Jim-2249 -- Added compile option `IR_INPUT_IS_ACTIVE_HIGH`. Thanks to Jim-2249 -- Corrected template. Thanks to Jim-2249 -- Introduced standard decode and send functions. -- Added compatibility with tone for AVR's. -- New TinyIRreceiver does not require a timer. -- New MinimalReceiver and IRDispatcherDemo examples. -- Added TinyCore 32 / ATtiny3217 support. -- Added Apple protocol. - -## 2.8.1 2020/10 -- Fixed bug in Sony decode introduced in 2.8.0. - -## 2.8.0 2020/10 -- Changed License to MIT see https://github.com/Arduino-IRremote/Arduino-IRremote/issues/397. -- Added ATtiny timer 1 support. -- Changed wrong return code signature of decodePulseDistanceData() and its handling. -- Removed Mitsubishi protocol, since the implementation is in contradiction with all documentation I found and therefore supposed to be wrong. -- Removed AIWA implementation, since it is only for 1 device and at least the sending was implemented wrong. -- Added Lego_PF decode. -- Changed internal usage of custom_delay_usec. -- Moved dump/print functions from example to irReceiver. -- irPronto.cpp: Using Print instead of Stream saves 1020 bytes program memory. Changed from & to * parameter type to be more transparent and consistent with other code of IRremote. - -## 2.7.0 2020/09 -- Added ATmega328PB support. -- Renamed hardware specific macro and function names. -- Renamed `USE_SOFT_CARRIER`, `USE_NO_CARRIER`, `DUTY_CYCLE` macros to `USE_SOFT_SEND_PWM`, `USE_NO_SEND_PWM`, `IR_SEND_DUTY_CYCLE`. -- Removed blocking wait for ATmega32U4 Serial in examples. -- Deactivated default debug output. -- Optimized types in sendRC5ext and sendSharpAlt. -- Added `DECODE_NEC_STANDARD` and `SEND_NEC_STANDARD`. -- Renamed all IRrecv* examples to IRreceive*. -- Added functions `printIRResultShort(&Serial)` and `getProtocolString(decode_type_t aDecodeType)`. -- Added flag `decodedIRData.isRepeat`. -- Updated examples. - -## 2.6.1 2020/08 -- Adjusted JVC and LG timing. -- Fixed 4809 bug. - -## 2.6.0 2020/08 -- Added support for MagiQuest IR wands. -- Corrected Samsung timing. -- NEC repeat implementation. -- Formatting and changing `TIMER_CONFIG_KHZ` and `TIMER_CONFIG_NORMAL` macros to static functions. -- Added `IRAM_ATTR` for ESP32 ISR. -- Removed `#define HAS_AVR_INTERRUPT_H`. -- Changed Receiver States. Now starting with 0. -- Changed switch to if / else if in IRRemote.cpp because of ESP32 compiler bug. -- Changed `DEBUG` handling since compiler warns about empty "IF" or "ELSE" statements in IRRemote.cpp. - -## 2.5.0 2020/06 -- Corrected keywords.txt. -- BoseWave protocol added PR #690. -- Formatting comply to the new stylesheet. -- Renamed "boarddefs.h" [ISSUE #375](https://github.com/Arduino-IRremote/Arduino-IRremote/issues/375). -- Renamed `SEND_PIN` to `IR_SEND_PIN`. -- Renamed state macros. -- Enabled `DUTY_CYCLE` for send signal. -- Added sending for ESP32. -- Changed rawlen from uint8_t to unsigned int allowing bigger receive buffer and renamed `RAWBUF` to `RAW_BUFFER_LENGTH`. -- Introduced `USE_NO_CARRIER` for simulating an IR receiver. -Changes from #283 by bengtmartensson -- Added function sendRaw_P() for sending data from flash. -Changes from #268 by adamlhumphreys -- Optimized by reducing floating point operations as suggested by madmalkav (#193). -- Optimized with macros when using default `MICROS_PER_TICK` and `TOLERANCE`. -- Made decodeHash as a settable protocol defined by `DECODE_HASH`. -- Added Philips Extended RC-5 protocol support [PR #522] (https://github.com/Arduino-IRremote/Arduino-IRremote/pull/522) - -## 2.4.0 - 2017/08/10 - - Cleanup of hardware dependencies. Merge in SAM support [PR #437](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/437) - -## 2.3.3 - 2017/03/31 -- Added ESP32 IR receive support [PR #427](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/425) - -## 2.2.3 - 2017/03/27 -- Fix calculation of pause length in LEGO PF protocol [PR #427](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/427) - -## 2.2.2 - 2017/01/20 -- Fixed naming bug [PR #398](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/398) - -## 2.2.1 - 2016/07/27 -- Added tests for Lego Power Functions Protocol [PR #336](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/336) - -## 2.2.0 - 2016/06/28 -- Added support for ATmega8535 -- Added support for ATmega16 -- Added support for ATmega32 -- Added support for ATmega164 -- Added support for ATmega324 -- Added support for ATmega644 -- Added support for ATmega1284 -- Added support for ATmega64 -- Added support for ATmega128 - -[PR](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/324) - -## 2.1.1 - 2016/05/04 -- Added Lego Power Functions Protocol [PR #309](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/309) - -## 2.1.0 - 2016/02/20 -- Improved Debugging [PR #258](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/258) -- Display TIME instead of TICKS [PR #258](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/258) - -## 2.0.4 - 2016/02/20 -- Add Panasonic and JVC to IRrecord example [PR](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/54) - -## 2.0.3 - 2016/02/20 -- Change IRSend Raw parameter to const [PR](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/227) - -## 2.0.2 - 2015/12/02 -- Added IRremoteInfo Sketch - [PR](https://github.com/Arduino-IRremote/Arduino-IRremote/pull/241) -- Enforcing changelog.md - -## 2.0.1 - 2015/07/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA) -### Changes -- Updated README -- Updated Contributors -- Fixed #110 Mess -- Created Gitter Room -- Added Gitter Badge -- Standardised Code Base -- Clean Debug Output -- Optimized Send Loops -- Modularized Design -- Optimized and Updated Examples -- Improved Documentation -- Fixed and Improved many coding errors -- Fixed Aiwa RC-T501 Decoding -- Fixed Interrupt on ATmega8 -- Switched to Stable Release of PlatformIO - -### Additions -- Added Aiwa RC-T501 Protocol -- Added Denon Protocol -- Added Pronto Support -- Added compile options -- Added Template For New Protocols -- Added this changelog -- Added Teensy LC Support -- Added ATtiny84 Support -- Added ATtiny85 Support -- Added isIdle method - -### Deletions -- Removed (Fixed) #110 -- Broke Teensy 3 / 3.1 Support - -### Not Working -- Teensy 3 / 3.1 Support is in Development diff --git a/IRremote/esp32.cpp b/IRremote/esp32.cpp deleted file mode 100644 index ef4d794769dd3c2782e999cf187db857b1e6bab3..0000000000000000000000000000000000000000 --- a/IRremote/esp32.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef ESP32 - -// This file contains functions specific to the ESP32. - -#include "IRremote.h" -#include "IRremoteInt.h" - -// "Idiot check" -#ifdef USE_DEFAULT_ENABLE_IR_IN -#error Must undef USE_DEFAULT_ENABLE_IR_IN -#endif - -hw_timer_t *timer; -void IRTimer(); // defined in IRremote.cpp, masqueraded as ISR(TIMER_INTR_NAME) - -//+============================================================================= -// initialization -// -void IRrecv::enableIRIn ( ) -{ -// Interrupt Service Routine - Fires every 50uS - // ESP32 has a proper API to setup timers, no weird chip macros needed - // simply call the readable API versions :) - // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up - timer = timerBegin(1, 80, 1); - timerAttachInterrupt(timer, &IRTimer, 1); - // every 50ns, autoreload = true - timerAlarmWrite(timer, 50, true); - timerAlarmEnable(timer); - - // Initialize state machine variables - irparams.rcvstate = STATE_IDLE; - irparams.rawlen = 0; - - // Set pin modes - pinMode(irparams.recvpin, INPUT); -} - -#endif // ESP32 diff --git a/IRremote/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino b/IRremote/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino deleted file mode 100644 index 5a9862bf355fc742f26a2be1160a8a5422d3f1eb..0000000000000000000000000000000000000000 --- a/IRremote/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino +++ /dev/null @@ -1,26 +0,0 @@ -/* - * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend - * An IR LED must be connected to Arduino PWM pin 3. - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - */ - -#include "IRremote.h" - -#define POWER 0x7F80 -#define AIWA_RC_T501 - -IRsend irsend; - -void setup() { - Serial.begin(9600); - Serial.println("Arduino Ready"); -} - -void loop() { - if (Serial.read() != -1) { - irsend.sendAiwaRCT501(POWER); - delay(60); // Optional - } -} diff --git a/IRremote/examples/AllProtocolsOnLCD/ADCUtils.h b/IRremote/examples/AllProtocolsOnLCD/ADCUtils.h deleted file mode 100644 index cc7e629d04a5c5b3f21d16c9b0ed24812e21d19b..0000000000000000000000000000000000000000 --- a/IRremote/examples/AllProtocolsOnLCD/ADCUtils.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * ADCUtils.h - * - * Copyright (C) 2016-2022 Armin Joachimsmeyer - * Email: armin.joachimsmeyer@gmail.com - * - * This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils. - * - * ArduinoUtils is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -#ifndef _ADC_UTILS_H -#define _ADC_UTILS_H - -#include <Arduino.h> - -#if defined(__AVR__) && defined(ADCSRA) && defined(ADATE) && (!defined(__AVR_ATmega4809__)) -#define ADC_UTILS_ARE_AVAILABLE - -// PRESCALE4 => 13 * 4 = 52 microseconds per ADC conversion at 1 MHz Clock => 19,2 kHz -#define ADC_PRESCALE2 1 // 26 microseconds per ADC conversion at 1 MHz -#define ADC_PRESCALE4 2 // 52 microseconds per ADC conversion at 1 MHz -// PRESCALE8 => 13 * 8 = 104 microseconds per ADC sample at 1 MHz Clock => 9,6 kHz -#define ADC_PRESCALE8 3 // 104 microseconds per ADC conversion at 1 MHz -#define ADC_PRESCALE16 4 // 13/208 microseconds per ADC conversion at 16/1 MHz - degradations in linearity at 16 MHz -#define ADC_PRESCALE32 5 // 26/416 microseconds per ADC conversion at 16/1 MHz - very good linearity at 16 MHz -#define ADC_PRESCALE64 6 // 52 microseconds per ADC conversion at 16 MHz -#define ADC_PRESCALE128 7 // 104 microseconds per ADC conversion at 16 MHz --- Arduino default - -// definitions for 0.1 ms conversion time -#if (F_CPU == 1000000) -#define ADC_PRESCALE ADC_PRESCALE8 -#elif (F_CPU == 8000000) -#define ADC_PRESCALE ADC_PRESCALE64 -#elif (F_CPU == 16000000) -#define ADC_PRESCALE ADC_PRESCALE128 -#endif - -/* - * Reference shift values are complicated for ATtinyX5 since we have the extra register bit REFS2 - * in ATTinyCore, this bit is handled programmatical and therefore the defines are different. - * To keep my library small, I use the changed defines. - * After including this file you can not call the ATTinyCore readAnalog functions reliable, if you specify references other than default! - */ -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) -// defines are for ADCUtils.cpp, they can be used WITHOUT bit reordering -#undef DEFAULT -#undef EXTERNAL -#undef INTERNAL1V1 -#undef INTERNAL -#undef INTERNAL2V56 -#undef INTERNAL2V56_EXTCAP - -#define DEFAULT 0 -#define EXTERNAL 4 -#define INTERNAL1V1 8 -#define INTERNAL INTERNAL1V1 -#define INTERNAL2V56 9 -#define INTERNAL2V56_EXTCAP 13 - -#define SHIFT_VALUE_FOR_REFERENCE REFS2 -#define MASK_FOR_ADC_REFERENCE (_BV(REFS0) | _BV(REFS1) | _BV(REFS2)) -#define MASK_FOR_ADC_CHANNELS (_BV(MUX0) | _BV(MUX1) | _BV(MUX2) | _BV(MUX3)) -#else // AVR_ATtiny85 - -#define SHIFT_VALUE_FOR_REFERENCE REFS0 -#define MASK_FOR_ADC_REFERENCE (_BV(REFS0) | _BV(REFS1)) -#define MASK_FOR_ADC_CHANNELS (_BV(MUX0) | _BV(MUX1) | _BV(MUX2) | _BV(MUX3)) -#endif - -// Temperature channel definitions - 1 LSB / 1 degree Celsius -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) -#define ADC_TEMPERATURE_CHANNEL_MUX 15 -#define ADC_1_1_VOLT_CHANNEL_MUX 12 -#define ADC_GND_CHANNEL_MUX 13 - -#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -#define ADC_ISCR_CHANNEL_MUX 3 -#define ADC_TEMPERATURE_CHANNEL_MUX 11 -#define ADC_1_1_VOLT_CHANNEL_MUX 12 -#define ADC_GND_CHANNEL_MUX 14 -#define ADC_VCC_4TH_CHANNEL_MUX 13 - -#elif defined(__AVR_ATmega328P__) -#define ADC_TEMPERATURE_CHANNEL_MUX 8 -#define ADC_1_1_VOLT_CHANNEL_MUX 14 -#define ADC_GND_CHANNEL_MUX 15 - -#elif defined(__AVR_ATmega32U4__) -#define ADC_TEMPERATURE_CHANNEL_MUX 0x27 -#define ADC_1_1_VOLT_CHANNEL_MUX 0x1E -#define ADC_GND_CHANNEL_MUX 0x1F - -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) -#define ADC_1_1_VOLT_CHANNEL_MUX 0x1E -#define ADC_GND_CHANNEL_MUX 0x1F -#define INTERNAL INTERNAL1V1 - -#else -#error "No temperature channel definitions specified for this AVR CPU" -#endif - -extern float sVCCVoltage; -extern uint16_t sVCCVoltageMillivolt; - -extern long sLastVCCCheckMillis; -extern uint8_t sVCCTooLowCounter; - -uint16_t readADCChannel(uint8_t aChannelNumber); -uint16_t readADCChannelWithReference(uint8_t aChannelNumber, uint8_t aReference); -uint16_t waitAndReadADCChannelWithReference(uint8_t aChannelNumber, uint8_t aReference); -uint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUXAndReference(uint8_t aChannelNumber, uint8_t aReference); -uint16_t readADCChannelWithOversample(uint8_t aChannelNumber, uint8_t aOversampleExponent); -void setADCMultiplexerAndReferenceForNextConversion(uint8_t aChannelNumber, uint8_t aReference); -uint16_t readADCChannelWithReferenceOversample(uint8_t aChannelNumber, uint8_t aReference, uint8_t aOversampleExponent); -uint16_t readADCChannelWithReferenceOversampleFast(uint8_t aChannelNumber, uint8_t aReference, uint8_t aOversampleExponent); -uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples); -uint16_t readADCChannelWithReferenceMax(uint8_t aChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples); -uint16_t readADCChannelWithReferenceMaxMicros(uint8_t aChannelNumber, uint8_t aReference, uint16_t aMicrosecondsToAquire); -uint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aChannelNumber, uint8_t aDelay, uint8_t aAllowedDifference, - uint8_t aMaxRetries); - -uint8_t checkAndWaitForReferenceAndChannelToSwitch(uint8_t aChannelNumber, uint8_t aReference); - -/* - * readVCC*() functions store the result in sVCCVoltageMillivolt or sVCCVoltage - */ -float getVCCVoltageSimple(void); -void readVCCVoltageSimple(void); -uint16_t getVCCVoltageMillivoltSimple(void); -void readVCCVoltageMillivoltSimple(void); -float getVCCVoltage(void); -void readVCCVoltage(void); -uint16_t getVCCVoltageMillivolt(void); -void readVCCVoltageMillivolt(void); -uint16_t getVCCVoltageReadingFor1_1VoltReference(void); -uint16_t printVCCVoltageMillivolt(Print *aSerial); -void readAndPrintVCCVoltageMillivolt(Print *aSerial); - -uint16_t getVoltageMillivolt(uint16_t aVCCVoltageMillivolt, uint8_t aADCChannelForVoltageMeasurement); -uint16_t getVoltageMillivolt(uint8_t aADCChannelForVoltageMeasurement); -uint16_t getVoltageMillivoltWith_1_1VoltReference(uint8_t aADCChannelForVoltageMeasurement); -float getTemperatureSimple(void); -float getTemperature(void); - -bool isVCCTooLowMultipleTimes(); -void resetVCCTooLowMultipleTimes(); -bool isVCCTooLow(); -bool isVCCTooHigh(); -bool isVCCTooHighSimple(); - -#endif // defined(__AVR__) ... -#endif // _ADC_UTILS_H diff --git a/IRremote/examples/AllProtocolsOnLCD/ADCUtils.hpp b/IRremote/examples/AllProtocolsOnLCD/ADCUtils.hpp deleted file mode 100644 index 752175c4589cb74505426d65e158e17bbd6b9d09..0000000000000000000000000000000000000000 --- a/IRremote/examples/AllProtocolsOnLCD/ADCUtils.hpp +++ /dev/null @@ -1,645 +0,0 @@ -/* - * ADCUtils.hpp - * - * ADC utility functions. Conversion time is defined as 0.104 milliseconds for 16 MHz Arduinos in ADCUtils.h. - * - * Copyright (C) 2016-2022 Armin Joachimsmeyer - * Email: armin.joachimsmeyer@gmail.com - * - * This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils. - * - * ArduinoUtils is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - */ - -#ifndef _ADC_UTILS_HPP -#define _ADC_UTILS_HPP - -#include "ADCUtils.h" -#if defined(ADC_UTILS_ARE_AVAILABLE) - -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif - -/* - * By replacing this value with the voltage you measured a the AREF pin after a conversion - * with INTERNAL you can calibrate your ADC readout. For my Nanos I measured e.g. 1060 mV and 1093 mV. - */ -#if !defined(ADC_INTERNAL_REFERENCE_MILLIVOLT) -#define ADC_INTERNAL_REFERENCE_MILLIVOLT 1100L // Change to value measured at the AREF pin. If value > real AREF voltage, measured values are > real values -#endif - -// Union to speed up the combination of low and high bytes to a word -// it is not optimal since the compiler still generates 2 unnecessary moves -// but using -- value = (high << 8) | low -- gives 5 unnecessary instructions -union WordUnionForADCUtils { - struct { - uint8_t LowByte; - uint8_t HighByte; - } UByte; - uint16_t UWord; - int16_t Word; - uint8_t *BytePointer; -}; - -/* - * Persistent storage for VCC value - */ -float sVCCVoltage; -uint16_t sVCCVoltageMillivolt; - -// for isVCCTooLowMultipleTimes() -long sLastVCCCheckMillis; -uint8_t sVCCTooLowCounter = 0; - -/* - * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h. - */ -uint16_t readADCChannel(uint8_t aChannelNumber) { - WordUnionForADCUtils tUValue; - ADMUX = aChannelNumber | (DEFAULT << SHIFT_VALUE_FOR_REFERENCE); - - // ADCSRB = 0; // Only active if ADATE is set to 1. - // ADSC-StartConversion ADIF-Reset Interrupt Flag - NOT free running mode - ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADIF) | ADC_PRESCALE); - - // wait for single conversion to finish - loop_until_bit_is_clear(ADCSRA, ADSC); - - // Get value - tUValue.UByte.LowByte = ADCL; - tUValue.UByte.HighByte = ADCH; - return tUValue.UWord; - // return ADCL | (ADCH <<8); // needs 4 bytes more -} - -/* - * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h. - */ -uint16_t readADCChannelWithReference(uint8_t aChannelNumber, uint8_t aReference) { - WordUnionForADCUtils tUValue; - ADMUX = aChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE); - - // ADCSRB = 0; // Only active if ADATE is set to 1. - // ADSC-StartConversion ADIF-Reset Interrupt Flag - NOT free running mode - ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADIF) | ADC_PRESCALE); - - // wait for single conversion to finish - loop_until_bit_is_clear(ADCSRA, ADSC); - - // Get value - tUValue.UByte.LowByte = ADCL; - tUValue.UByte.HighByte = ADCH; - return tUValue.UWord; -} - -/* - * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h. - * Does NOT restore ADMUX after reading - */ -uint16_t waitAndReadADCChannelWithReference(uint8_t aChannelNumber, uint8_t aReference) { - checkAndWaitForReferenceAndChannelToSwitch(aChannelNumber, aReference); - return readADCChannelWithReference(aChannelNumber, aReference); -} - -/* - * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h. - * Restores ADMUX after reading - */ -uint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUXAndReference(uint8_t aChannelNumber, uint8_t aReference) { - uint8_t tOldADMUX = checkAndWaitForReferenceAndChannelToSwitch(aChannelNumber, aReference); - uint16_t tResult = readADCChannelWithReference(aChannelNumber, aReference); - checkAndWaitForReferenceAndChannelToSwitch(tOldADMUX & MASK_FOR_ADC_CHANNELS, tOldADMUX >> SHIFT_VALUE_FOR_REFERENCE); - return tResult; -} - -/* - * To prepare reference and ADMUX for next measurement - */ -void setADCMultiplexerAndReferenceForNextConversion(uint8_t aChannelNumber, uint8_t aReference) { - ADMUX = aChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE); -} - -/* - * @return original ADMUX register content for optional later restoring values - * All experimental values are acquired by using the ADCSwitchingTest example from this library - */ -uint8_t checkAndWaitForReferenceAndChannelToSwitch(uint8_t aChannelNumber, uint8_t aReference) { - uint8_t tOldADMUX = ADMUX; - /* - * Must wait >= 7 us if reference has to be switched from 1.1 volt/INTERNAL to VCC/DEFAULT (seen on oscilloscope) - * This is done after the 2 ADC clock cycles required for Sample & Hold :-) - * - * Must wait >= 7600 us for Nano board >= 6200 for Uno board if reference has to be switched from VCC/DEFAULT to 1.1 volt/INTERNAL - * Must wait >= 200 us if channel has to be switched to 1.1 volt internal channel if S&H was at 5 Volt - */ - uint8_t tNewReference = (aReference << SHIFT_VALUE_FOR_REFERENCE); - ADMUX = aChannelNumber | tNewReference; -#if defined(INTERNAL2V56) - if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && (aReference == INTERNAL || aReference == INTERNAL2V56)) { -#else - if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && aReference == INTERNAL) { -#endif - /* - * Switch reference from DEFAULT to INTERNAL - */ - delayMicroseconds(8000); // experimental value is >= 7600 us for Nano board and 6200 for Uno board - } else if ((tOldADMUX & 0x0F) != aChannelNumber) { - if (aChannelNumber == ADC_1_1_VOLT_CHANNEL_MUX) { - /* - * Internal 1.1 Volt channel requires <= 200 us for Nano board - */ - delayMicroseconds(350); // 350 was ok and 300 was too less for UltimateBatteryTester - result was 226 instead of 225 - } else { - /* - * 100 kOhm requires < 100 us, 1 MOhm requires 120 us S&H switching time - */ - delayMicroseconds(120); // experimental value is <= 1100 us for Nano board - } - } - return tOldADMUX; -} - -/* - * Oversample and multiple samples only makes sense if you expect a noisy input signal - * It does NOT increase the precision of the measurement, since the ADC has insignificant noise - */ -uint16_t readADCChannelWithOversample(uint8_t aChannelNumber, uint8_t aOversampleExponent) { - return readADCChannelWithReferenceOversample(aChannelNumber, DEFAULT, aOversampleExponent); -} - -/* - * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h. - */ -uint16_t readADCChannelWithReferenceOversample(uint8_t aChannelNumber, uint8_t aReference, uint8_t aOversampleExponent) { - uint16_t tSumValue = 0; - ADMUX = aChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE); - - ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1. - // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag - ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | ADC_PRESCALE); - - uint8_t tCount = _BV(aOversampleExponent); - for (uint8_t i = 0; i < tCount; i++) { - /* - * wait for free running conversion to finish. - * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion. - */ - loop_until_bit_is_set(ADCSRA, ADIF); - - ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished - // Add value - tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here - // tSumValue += (ADCH << 8) | ADCL; // this does NOT work! - } - ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode) - // return rounded value - return ((tSumValue + (tCount >> 1)) >> aOversampleExponent); -} - -/* - * Use ADC_PRESCALE32 which gives 26 us conversion time and good linearity for 16 MHz Arduino - */ -uint16_t readADCChannelWithReferenceOversampleFast(uint8_t aChannelNumber, uint8_t aReference, uint8_t aOversampleExponent) { - uint16_t tSumValue = 0; - ADMUX = aChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE); - - ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1. - // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag - ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | ADC_PRESCALE32); - - uint8_t tCount = _BV(aOversampleExponent); - for (uint8_t i = 0; i < tCount; i++) { - /* - * wait for free running conversion to finish. - * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion. - */ - loop_until_bit_is_set(ADCSRA, ADIF); - - ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished - // Add value - tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here - // tSumValue += (ADCH << 8) | ADCL; // this does NOT work! - } - ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode) - return ((tSumValue + (tCount >> 1)) >> aOversampleExponent); -} - -/* - * Returns sum of all sample values - * Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino by ADC_PRESCALE in ADCUtils.h. - */ -uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples) { - uint16_t tSumValue = 0; - ADMUX = aChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE); - - ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1. - // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag - ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | ADC_PRESCALE); - - for (uint8_t i = 0; i < aNumberOfSamples; i++) { - /* - * wait for free running conversion to finish. - * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion. - */ - loop_until_bit_is_set(ADCSRA, ADIF); - - ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished - // Add value - tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here - // tSumValue += (ADCH << 8) | ADCL; // this does NOT work! - } - ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode) - return tSumValue; -} - -/* - * use ADC_PRESCALE32 which gives 26 us conversion time and good linearity - * @return the maximum of aNumberOfSamples measurements. - */ -uint16_t readADCChannelWithReferenceMax(uint8_t aChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples) { - uint16_t tADCValue = 0; - uint16_t tMaximum = 0; - ADMUX = aChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE); - - ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1. - // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag - ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | ADC_PRESCALE32); - - for (uint16_t i = 0; i < aNumberOfSamples; i++) { - /* - * wait for free running conversion to finish. - * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion. - */ - loop_until_bit_is_set(ADCSRA, ADIF); - - ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished - // check value - tADCValue = ADCL | (ADCH << 8); - if (tADCValue > tMaximum) { - tMaximum = tADCValue; - } - } - ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode) - return tMaximum; -} - -/* - * use ADC_PRESCALE32 which gives 26 us conversion time and good linearity - */ -uint16_t readADCChannelWithReferenceMaxMicros(uint8_t aChannelNumber, uint8_t aReference, uint16_t aMicrosecondsToAquire) { - uint16_t tNumberOfSamples = aMicrosecondsToAquire / 26; - return readADCChannelWithReferenceMax(aChannelNumber, aReference, tNumberOfSamples); -} - -/* - * aMaxRetries = 255 -> try forever - * @return (tMax + tMin) / 2 - */ -uint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aChannelNumber, uint8_t aDelay, uint8_t aAllowedDifference, - uint8_t aMaxRetries) { - int tValues[4]; - int tMin; - int tMax; - - tValues[0] = readADCChannel(aChannelNumber); - for (int i = 1; i < 4; ++i) { - delay(aDelay); // Only 3 delays! - tValues[i] = readADCChannel(aChannelNumber); - } - - do { - // find min and max - tMin = 1024; - tMax = 0; - for (int i = 0; i < 4; ++i) { - if (tValues[i] < tMin) { - tMin = tValues[i]; - } - if (tValues[i] > tMax) { - tMax = tValues[i]; - } - } - /* - * check for terminating condition - */ - if ((tMax - tMin) <= aAllowedDifference) { - break; - } else { -// Serial.print("Difference="); -// Serial.println(tMax - tMin); - - // move values - for (int i = 0; i < 3; ++i) { - tValues[i] = tValues[i + 1]; - } - // and wait - delay(aDelay); - tValues[3] = readADCChannel(aChannelNumber); - } - if (aMaxRetries != 255) { - aMaxRetries--; - } - } while (aMaxRetries > 0); - - return (tMax + tMin) / 2; -} - -/* - * !!! Function without handling of switched reference and channel.!!! - * Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program. - * !!! Resolution is only 20 millivolt !!! - * Raw reading of 1.1 V is 225 at 5 V. - * Raw reading of 1.1 V is 221 at 5.1 V. - * Raw reading of 1.1 V is 214 at 5.25 V (+5 %). - * Raw reading of 1.1 V is 204 at 5.5 V (+10 %). - */ -float getVCCVoltageSimple(void) { - // use AVCC with (optional) external capacitor at AREF pin as reference - float tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4); - return ((1023 * 1.1 * 4) / tVCC); -} - -/* - * !!! Function without handling of switched reference and channel.!!! - * Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program. - * !!! Resolution is only 20 millivolt !!! - */ -uint16_t getVCCVoltageMillivoltSimple(void) { - // use AVCC with external capacitor at AREF pin as reference - uint16_t tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4); - return ((1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCC); -} - -/* - * Gets the hypothetical 14 bit reading of VCC using 1.1 volt reference - * Similar to getVCCVoltageMillivolt() * 1023 / 1100 - */ -uint16_t getVCCVoltageReadingFor1_1VoltReference(void) { - uint16_t tVCC = waitAndReadADCChannelWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT); - /* - * Do not switch back ADMUX to enable checkAndWaitForReferenceAndChannelToSwitch() to work correctly for the next measurement - */ - return ((1023L * 1023L) / tVCC); -} - -/* - * !!! Resolution is only 20 millivolt !!! - */ -float getVCCVoltage(void) { - return (getVCCVoltageMillivolt() / 1000.0); -} - -/* - * Read value of 1.1 volt internal channel using VCC (DEFAULT) as reference. - * Handles reference and channel switching by introducing the appropriate delays. - * !!! Resolution is only 20 millivolt !!! - * Raw reading of 1.1 V is 225 at 5 V. - * Raw reading of 1.1 V is 221 at 5.1 V. - * Raw reading of 1.1 V is 214 at 5.25 V (+5 %). - * Raw reading of 1.1 V is 204 at 5.5 V (+10 %). - */ -uint16_t getVCCVoltageMillivolt(void) { - uint16_t tVCC = waitAndReadADCChannelWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT); - /* - * Do not switch back ADMUX to enable checkAndWaitForReferenceAndChannelToSwitch() to work correctly for the next measurement - */ - return ((1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT) / tVCC); -} - -uint16_t printVCCVoltageMillivolt(Print *aSerial) { - aSerial->print(F("VCC=")); - uint16_t tVCCVoltageMillivolt = getVCCVoltageMillivolt(); - aSerial->print(tVCCVoltageMillivolt); - aSerial->println(" mV"); - return tVCCVoltageMillivolt; -} - -void readAndPrintVCCVoltageMillivolt(Print *aSerial) { - aSerial->print(F("VCC=")); - sVCCVoltageMillivolt = getVCCVoltageMillivolt(); - aSerial->print(sVCCVoltageMillivolt); - aSerial->println(" mV"); -} -/* - * !!! Function without handling of switched reference and channel.!!! - * Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program. - * !!! Resolution is only 20 millivolt !!! - */ -void readVCCVoltageSimple(void) { - // use AVCC with (optional) external capacitor at AREF pin as reference - float tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4); - sVCCVoltage = (1023 * 1.1 * 4) / tVCC; -} - -/* - * !!! Function without handling of switched reference and channel.!!! - * Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program. - * !!! Resolution is only 20 millivolt !!! - */ -void readVCCVoltageMillivoltSimple(void) { - // use AVCC with external capacitor at AREF pin as reference - uint16_t tVCCVoltageMillivoltRaw = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4); - sVCCVoltageMillivolt = (1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCCVoltageMillivoltRaw; -} - -/* - * !!! Resolution is only 20 millivolt !!! - */ -void readVCCVoltage(void) { - sVCCVoltage = getVCCVoltageMillivolt() / 1000.0; -} - -/* - * Read value of 1.1 volt internal channel using VCC (DEFAULT) as reference. - * Handles reference and channel switching by introducing the appropriate delays. - * !!! Resolution is only 20 millivolt !!! - * Sets also the sVCCVoltageMillivolt variable. - */ -void readVCCVoltageMillivolt(void) { - uint16_t tVCCVoltageMillivoltRaw = waitAndReadADCChannelWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT); - /* - * Do not switch back ADMUX to enable checkAndWaitForReferenceAndChannelToSwitch() to work correctly for the next measurement - */ - sVCCVoltageMillivolt = (1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT) / tVCCVoltageMillivoltRaw; -} - -/* - * Get voltage at ADC channel aADCChannelForVoltageMeasurement - * aVCCVoltageMillivolt is assumed as reference voltage - */ -uint16_t getVoltageMillivolt(uint16_t aVCCVoltageMillivolt, uint8_t aADCChannelForVoltageMeasurement) { - uint16_t tInputVoltageRaw = waitAndReadADCChannelWithReference(aADCChannelForVoltageMeasurement, DEFAULT); - return (aVCCVoltageMillivolt * (uint32_t) tInputVoltageRaw) / 1023; -} - -/* - * Get voltage at ADC channel aADCChannelForVoltageMeasurement - * Reference voltage VCC is determined just before - */ -uint16_t getVoltageMillivolt(uint8_t aADCChannelForVoltageMeasurement) { - uint16_t tInputVoltageRaw = waitAndReadADCChannelWithReference(aADCChannelForVoltageMeasurement, DEFAULT); - return (getVCCVoltageMillivolt() * (uint32_t) tInputVoltageRaw) / 1023; -} - -uint16_t getVoltageMillivoltWith_1_1VoltReference(uint8_t aADCChannelForVoltageMeasurement) { - uint16_t tInputVoltageRaw = waitAndReadADCChannelWithReference(aADCChannelForVoltageMeasurement, INTERNAL); - return (ADC_INTERNAL_REFERENCE_MILLIVOLT * (uint32_t) tInputVoltageRaw) / 1023; -} - -/* - * Default values are suitable for Li-ion batteries. - * We normally have voltage drop at the connectors, so the battery voltage is assumed slightly higher, than the Arduino VCC. - * But keep in mind that the ultrasonic distance module HC-SR04 may not work reliable below 3.7 volt. - */ -#if !defined(VCC_STOP_THRESHOLD_MILLIVOLT) -#define VCC_STOP_THRESHOLD_MILLIVOLT 3400 // Do not stress your battery and we require some power for standby -#endif -#if !defined(VCC_EMERGENCY_STOP_MILLIVOLT) -#define VCC_EMERGENCY_STOP_MILLIVOLT 3000 // Many Li-ions are specified down to 3.0 volt -#endif -#if !defined(VCC_TOO_HIGH_STOP_MILLIVOLT) -#define VCC_TOO_HIGH_STOP_MILLIVOLT 5250 // + 5 % operation voltage -#endif -#if !defined(VCC_TOO_HIGH_EMERGENCY_STOP_MILLIVOLT) -#define VCC_TOO_HIGH_EMERGENCY_STOP_MILLIVOLT 5500 // +10 %. Max recommended operation voltage -#endif -#if !defined(VCC_CHECK_PERIOD_MILLIS) -#define VCC_CHECK_PERIOD_MILLIS 10000 // Period of VCC checks -#endif -#if !defined(VCC_CHECKS_TOO_LOW_BEFORE_STOP) -#define VCC_CHECKS_TOO_LOW_BEFORE_STOP 6 // Shutdown after 6 times (60 seconds) VCC below VCC_STOP_THRESHOLD_MILLIVOLT or 1 time below VCC_EMERGENCY_STOP_MILLIVOLT -#endif - -/* - * @ return true only once, when VCC_CHECKS_TOO_LOW_BEFORE_STOP (6) times voltage too low -> shutdown - */ -bool isVCCTooLowMultipleTimes() { - /* - * Check VCC every VCC_CHECK_PERIOD_MILLIS (10) seconds - */ - - if (millis() - sLastVCCCheckMillis >= VCC_CHECK_PERIOD_MILLIS) { - sLastVCCCheckMillis = millis(); - -# if defined(INFO) - readAndPrintVCCVoltageMillivolt(&Serial); -# else - readVCCVoltageMillivolt(); -# endif - - if (sVCCTooLowCounter < VCC_CHECKS_TOO_LOW_BEFORE_STOP) { - /* - * Do not check again if shutdown has happened - */ - if (sVCCVoltageMillivolt > VCC_STOP_THRESHOLD_MILLIVOLT) { - sVCCTooLowCounter = 0; // reset counter - } else { - /* - * Voltage too low, wait VCC_CHECKS_TOO_LOW_BEFORE_STOP (6) times and then shut down. - */ - if (sVCCVoltageMillivolt < VCC_EMERGENCY_STOP_MILLIVOLT) { - // emergency shutdown - sVCCTooLowCounter = VCC_CHECKS_TOO_LOW_BEFORE_STOP; -# if defined(INFO) - Serial.println(F("Voltage < " STR(VCC_EMERGENCY_STOP_MILLIVOLT) " mV detected -> emergency shutdown")); -# endif - } else { - sVCCTooLowCounter++; -# if defined(INFO) - Serial.print(F("Voltage < " STR(VCC_STOP_THRESHOLD_MILLIVOLT) " mV detected: ")); - Serial.print(VCC_CHECKS_TOO_LOW_BEFORE_STOP - sVCCTooLowCounter); - Serial.println(F(" tries left")); -# endif - } - if (sVCCTooLowCounter == VCC_CHECKS_TOO_LOW_BEFORE_STOP) { - /* - * 6 times voltage too low -> shutdown - */ - return true; - } - } - } - } - return false; -} - - -/* - * Return true if VCC_EMERGENCY_STOP_MILLIVOLT (3 V) reached - */ -bool isVCCTooLow(){ - return (sVCCVoltageMillivolt < VCC_EMERGENCY_STOP_MILLIVOLT); -} - - -void resetVCCTooLowMultipleTimes(){ - sVCCTooLowCounter = 0; -} - -/* - * Recommended VCC is 1.8 V to 5.5 V, absolute maximum VCC is 6.0 V. - * Check for 5.25 V, because such overvoltage is quite unlikely to happen during regular operation. - * Raw reading of 1.1 V is 225 at 5 V. - * Raw reading of 1.1 V is 221 at 5.1 V. - * Raw reading of 1.1 V is 214 at 5.25 V (+5 %). - * Raw reading of 1.1 V is 204 at 5.5 V (+10 %). - * @return true if 5 % overvoltage reached - */ -bool isVCCTooHigh(){ - readVCCVoltageMillivolt(); - return (sVCCVoltageMillivolt > VCC_TOO_HIGH_STOP_MILLIVOLT); -} -bool isVCCTooHighSimple(){ - readVCCVoltageMillivoltSimple(); - return (sVCCVoltageMillivolt > VCC_TOO_HIGH_STOP_MILLIVOLT); -} - -/* - * !!! Function without handling of switched reference and channel.!!! - * Use it ONLY if you only use INTERNAL reference (call getTemperatureSimple()) in your program. - */ -float getTemperatureSimple(void) { -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - return 0.0; -#else -// use internal 1.1 volt as reference - float tTemp = (readADCChannelWithReferenceMultiSamples(ADC_TEMPERATURE_CHANNEL_MUX, INTERNAL, 2) - 317); - return (tTemp * (4 / 1.22)); -#endif -} - -/* - * Handles reference and channel switching by introducing the appropriate delays. - */ -float getTemperature(void) { -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - return 0.0; -#else - // use internal 1.1 volt as reference - checkAndWaitForReferenceAndChannelToSwitch(ADC_TEMPERATURE_CHANNEL_MUX, INTERNAL); - // assume the signal has noise, but never verified :-( - float tTemp = (readADCChannelWithReferenceOversample(ADC_TEMPERATURE_CHANNEL_MUX, INTERNAL, 1) - 317); - return (tTemp / 1.22); -#endif -} - -#elif defined(ARDUINO_ARCH_APOLLO3) // defined(ADC_UTILS_ARE_AVAILABLE) - void ADCUtilsDummyToAvoidBFDAssertions(){ - ; - } -#endif // defined(ADC_UTILS_ARE_AVAILABLE) - -#endif // _ADC_UTILS_HPP diff --git a/IRremote/examples/AllProtocolsOnLCD/AllProtocolsOnLCD.ino b/IRremote/examples/AllProtocolsOnLCD/AllProtocolsOnLCD.ino deleted file mode 100644 index e26b6432314a7c82621839b4f5997e69f74e2547..0000000000000000000000000000000000000000 --- a/IRremote/examples/AllProtocolsOnLCD/AllProtocolsOnLCD.ino +++ /dev/null @@ -1,438 +0,0 @@ -/* - * AllProtocolsOnLCD.cpp - * - * Modified ReceiveDemo.cpp with additional 1602 LCD output. - * If debug button is pressed (pin connected to ground) a long output is generated. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -#if !defined(RAW_BUFFER_LENGTH) -# if RAMEND <= 0x4FF || RAMSIZE < 0x4FF -#define RAW_BUFFER_LENGTH 180 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# elif RAMEND <= 0x8FF || RAMSIZE < 0x8FF -#define RAW_BUFFER_LENGTH 600 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# else -#define RAW_BUFFER_LENGTH 750 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# endif -#endif - -//#define NO_LED_FEEDBACK_CODE // saves 92 bytes program memory -#if FLASHEND <= 0x1FFF // For 8k flash or less, like ATtiny85. Exclude exotic protocols. -#define EXCLUDE_EXOTIC_PROTOCOLS -# if !defined(DIGISTUMPCORE) // ATTinyCore is bigger than Digispark core -#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. -# endif -#endif -//#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. -//#define EXCLUDE_EXOTIC_PROTOCOLS // saves around 650 bytes program memory if all other protocols are active - -// MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, -// to compensate for the signal forming of different IR receiver modules. See also IRremote.hpp line 142. -#define MARK_EXCESS_MICROS 20 // Adapt it to your IR receiver module. 20 is recommended for the cheap VS1838 modules. - -//#define RECORD_GAP_MICROS 12000 // Default is 5000. Activate it for some LG air conditioner protocols. - -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. -//#define DECODE_NEC // Includes Apple and Onkyo - -#include <IRremote.hpp> - -/* - * Activate the type of LCD you use - * Default is parallel LCD with 2 rows of 16 characters (1602). - * Serial LCD has the disadvantage, that the first repeat is not detected, - * because of the long lasting serial communication. - */ -//#define USE_NO_LCD -//#define USE_SERIAL_LCD -// Definitions for the 1602 LCD -#define LCD_COLUMNS 16 -#define LCD_ROWS 2 - -#if defined(USE_SERIAL_LCD) -#include "LiquidCrystal_I2C.h" // Use an up to date library version, which has the init method -LiquidCrystal_I2C myLCD(0x27, LCD_COLUMNS, LCD_ROWS); // set the LCD address to 0x27 for a 16 chars and 2 line display -#elif !defined(USE_NO_LCD) -#define USE_PARALLEL_LCD -#include "LiquidCrystal.h" -//LiquidCrystal myLCD(4, 5, 6, 7, 8, 9); -LiquidCrystal myLCD(7, 8, 3, 4, 5, 6); -#endif - -#if defined(USE_PARALLEL_LCD) -#define DEBUG_BUTTON_PIN 11 // If low, print timing for each received data set -#undef TONE_PIN -#define TONE_PIN 9 // Pin 4 is used by LCD -#else -#define DEBUG_BUTTON_PIN 6 -#endif -#define AUXILIARY_DEBUG_BUTTON_PIN 12 // Is set to low to enable using of a simple connector for enabling debug - -#define MILLIS_BETWEEN_ATTENTION_BEEP 60000 // 60 sec -uint32_t sMillisOfLastReceivedIRFrame = 0; - -#if defined(USE_SERIAL_LCD) || defined(USE_PARALLEL_LCD) -#define USE_LCD -# if defined(__AVR__) && defined(ADCSRA) && defined(ADATE) -// For cyclically display of VCC -#include "ADCUtils.hpp" -#define MILLIS_BETWEEN_VOLTAGE_PRINT 5000 -#define LCD_VOLTAGE_START_INDEX 11 -uint32_t volatile sMillisOfLastVoltagePrint = 0; -bool ProtocolStringOverwritesVoltage = false; -# endif -#define LCD_IR_COMMAND_START_INDEX 9 - -#endif // defined(USE_SERIAL_LCD) || defined(USE_PARALLEL_LCD) - -void printIRResultOnLCD(); -size_t printByteHexOnLCD(uint16_t aHexByteValue); -void printSpacesOnLCD(uint_fast8_t aNumberOfSpacesToPrint); - -uint16_t sVCCMillivolt; - -void setup() { -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc. - pinMode(DEBUG_BUTTON_PIN, INPUT_PULLUP); -# if defined(AUXILIARY_DEBUG_BUTTON_PIN) - pinMode(AUXILIARY_DEBUG_BUTTON_PIN, OUTPUT); - digitalWrite(AUXILIARY_DEBUG_BUTTON_PIN, LOW); // To use a simple connector to enable debug -# endif -#endif - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif -// Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - tone(TONE_PIN, 2200); - delay(200); - noTone(TONE_PIN); - -// In case the interrupt driver crashes on setup, give a clue -// to the user what's going on. - Serial.println(F("Enabling IRin...")); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); - -#if defined(USE_SERIAL_LCD) - Serial.println( - F("With serial LCD connection, the first repeat is not detected, because of the long lasting serial communication!")); -#endif - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc. - Serial.println(); - Serial.print(F("If you connect debug pin ")); -# if defined(APPLICATION_PIN_STRING) - Serial.print(APPLICATION_PIN_STRING); -# else - Serial.print(DEBUG_BUTTON_PIN); -# endif - Serial.print(F(" to ground or to pin ")); - Serial.print(AUXILIARY_DEBUG_BUTTON_PIN); - Serial.println(F(", raw data is always printed")); - - // infos for receive - Serial.print(RECORD_GAP_MICROS); - Serial.println(F(" us is the (minimum) gap, after which the start of a new IR packet is assumed")); - Serial.print(MARK_EXCESS_MICROS); - Serial.println(F(" us are subtracted from all marks and added to all spaces for decoding")); -#endif - -#if defined(USE_LCD) && defined(__AVR__) && defined(ADCSRA) && defined(ADATE) - getVCCVoltageMillivoltSimple(); // to initialize ADC mux and reference -#endif - -#if defined(USE_SERIAL_LCD) - myLCD.init(); - myLCD.clear(); - myLCD.backlight(); // Switch backlight LED on -#endif -#if defined(USE_PARALLEL_LCD) - myLCD.begin(LCD_COLUMNS, LCD_ROWS); // This also clears display -#endif - -#if defined(USE_LCD) - myLCD.setCursor(0, 0); - myLCD.print(F("IRRemote v" VERSION_IRREMOTE)); - myLCD.setCursor(0, 1); - myLCD.print(F(__DATE__)); -#endif - -#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE) - sVCCMillivolt = getVCCVoltageMillivoltSimple(); -#endif -} - -void loop() { - /* - * Check if received data is available and if yes, try to decode it. - * Decoded result is in the IrReceiver.decodedIRData structure. - * - * E.g. command is in IrReceiver.decodedIRData.command - * address is in command is in IrReceiver.decodedIRData.address - * and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData - */ - if (IrReceiver.decode()) { - Serial.println(); - // Print a short summary of received data - IrReceiver.printIRResultShort(&Serial); - - if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_WAS_OVERFLOW) { - Serial.println(F("Try to increase the \"RAW_BUFFER_LENGTH\" value of " STR(RAW_BUFFER_LENGTH) " in " __FILE__)); -#if defined(USE_LCD) - myLCD.setCursor(0, 0); - myLCD.print(F("Overflow ")); -#endif - - // see also https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library - - } else { - // play tone - auto tStartMillis = millis(); - IrReceiver.stop(); - tone(TONE_PIN, 2200); - - if ((IrReceiver.decodedIRData.protocol == UNKNOWN || digitalRead(DEBUG_BUTTON_PIN) == LOW) -#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE) - && sVCCMillivolt > 4222 -#endif - ) { - // Print more info, but only if we are connected to USB, i.e. VCC is > 4222 mV, because this may take to long to detect some fast repeats - IrReceiver.printIRSendUsage(&Serial); - IrReceiver.printIRResultRawFormatted(&Serial, false); // print ticks, this is faster :-) - } - - // Guarantee at least 5 millis for tone. decode starts 5 millis (RECORD_GAP_MICROS) after end of frame - // so here we are 10 millis after end of frame. Sony20 has only a 12 ms repeat gap. - while ((millis() - tStartMillis) < 5) - ; - noTone(TONE_PIN); - - // Restore IR timer. millis() - tStartMillis to compensate for stop of receiver. This enables a correct gap measurement. - IrReceiver.startWithTicksToAdd((millis() - tStartMillis) * (MICROS_IN_ONE_MILLI / MICROS_PER_TICK)); - -#if defined(USE_LCD) - printIRResultOnLCD(); -#endif - } - - /* - * !!!Important!!! Enable receiving of the next value, - * since receiving has stopped after the end of the current received data packet. - */ - IrReceiver.resume(); - } // if (IrReceiver.decode()) - - /* - * Check for attention every 10 minute, after the current measurement was finished - */ - if (millis() - sMillisOfLastReceivedIRFrame >= MILLIS_BETWEEN_ATTENTION_BEEP) { - sMillisOfLastReceivedIRFrame = millis(); - IrReceiver.stop(); - tone(TONE_PIN, 2200); - delay(50); - noTone(TONE_PIN); - IrReceiver.startWithTicksToAdd(50 * (MICROS_IN_ONE_MILLI / MICROS_PER_TICK)); - } - -#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE) - //Periodically print VCC - if (!ProtocolStringOverwritesVoltage && millis() - sMillisOfLastVoltagePrint > MILLIS_BETWEEN_VOLTAGE_PRINT) { - /* - * Periodically print VCC - */ - sMillisOfLastVoltagePrint = millis(); - sVCCMillivolt = getVCCVoltageMillivoltSimple(); - char tVoltageString[5]; - dtostrf(sVCCMillivolt / 1000.0, 4, 2, tVoltageString); - myLCD.setCursor(LCD_VOLTAGE_START_INDEX - 1, 0); - myLCD.print(' '); - myLCD.print(tVoltageString); - myLCD.print('V'); - } -#endif - -} - -/* - * LCD output for 1602 LCDs - * 40 - 55 Milliseconds per initial output - * The expander runs at 100 kHz :-( - * 8 milliseconds for 8 bit; 10 ms for 16 bit code output - * 3 milliseconds for repeat output - * - */ -void printIRResultOnLCD() { -#if defined(USE_LCD) - static uint16_t sLastProtocolIndex = 4711; - static uint16_t sLastProtocolAddress = 4711; - static uint16_t sLastCommand = 0; - static uint8_t sLastCommandPrintPosition; - - /* - * Print only if protocol has changed - */ - if (sLastProtocolIndex != IrReceiver.decodedIRData.protocol) { - sLastProtocolIndex = IrReceiver.decodedIRData.protocol; - /* - * Show protocol name and handle overwrite over voltage display - */ - myLCD.setCursor(0, 0); - uint_fast8_t tProtocolStringLength = myLCD.print(getProtocolString(IrReceiver.decodedIRData.protocol)); -# if defined(__AVR__) && defined(ADCSRA) && defined(ADATE) - if (tProtocolStringLength > LCD_VOLTAGE_START_INDEX) { - // we overwrite the voltage -> clear rest of line and inhibit new printing of voltage - ProtocolStringOverwritesVoltage = true; - if (tProtocolStringLength < LCD_COLUMNS) { - printSpacesOnLCD(LCD_COLUMNS - tProtocolStringLength); - } - } else { - // Trigger printing of VCC in main loop - sMillisOfLastVoltagePrint = 0; - ProtocolStringOverwritesVoltage = false; - printSpacesOnLCD(LCD_VOLTAGE_START_INDEX - tProtocolStringLength); - } -# else - printSpacesOnLCD(LCD_COLUMNS - tProtocolStringLength); -# endif - } - - if (IrReceiver.decodedIRData.protocol == UNKNOWN) { - /* - * Print number of bits received and microseconds of signal - */ - myLCD.setCursor(0, 1); - uint8_t tNumberOfBits = (IrReceiver.decodedIRData.rawDataPtr->rawlen + 1) / 2; - if (tNumberOfBits < 10) { - myLCD.print(' '); // padding space - } - myLCD.print(tNumberOfBits); - myLCD.print(F(" bit ")); - uint_fast8_t tDurationStringLength = myLCD.print(IrReceiver.getTotalDurationOfRawData()); - myLCD.print(F(" \xE4s")); // \xE4 is micro symbol - printSpacesOnLCD(7 - tDurationStringLength); - sLastProtocolAddress = 4711; - sLastCommand = 44711; - - } else { - /* - * Print only if address has changed - */ - if (sLastProtocolAddress != IrReceiver.decodedIRData.address) { - sLastProtocolAddress = IrReceiver.decodedIRData.address; - - myLCD.setCursor(0, 1); - /* - * Show address - */ -# if defined(DECODE_DISTANCE_WIDTH) - if (IrReceiver.decodedIRData.protocol == PULSE_DISTANCE || IrReceiver.decodedIRData.protocol == PULSE_WIDTH) { - myLCD.print(F("[0]=0x")); - uint_fast8_t tAddressStringLength = myLCD.print(IrReceiver.decodedIRData.decodedRawDataArray[0], HEX); - printSpacesOnLCD(LCD_COLUMNS - tAddressStringLength); - sLastCommand = 0; // to trigger restoration of "C=" string - return; // no command here - } else { -# endif - myLCD.print(F("A=")); - uint_fast8_t tAddressStringLength = printByteHexOnLCD(IrReceiver.decodedIRData.address); - printSpacesOnLCD((LCD_IR_COMMAND_START_INDEX - 2) - tAddressStringLength); -# if defined(DECODE_DISTANCE_WIDTH) - } -# endif - } - - /* - * Print command always - */ - uint16_t tCommand = IrReceiver.decodedIRData.command; - -// Check if prefix position must change - if (sLastCommand == 0 || (sLastCommand >= 0x100 && tCommand < 0x100) || (sLastCommand < 0x100 && tCommand >= 0x100)) { - sLastCommand = tCommand; - /* - * Print prefix for 8/16 bit commands - */ - if (tCommand >= 0x100) { - // Do not print "C=" here to have 2 additional characters for command - sLastCommandPrintPosition = 9; - } else { - myLCD.setCursor(LCD_IR_COMMAND_START_INDEX, 1); - myLCD.print(F("C=")); - sLastCommandPrintPosition = 11; - } - } - - /* - * Command data - */ - myLCD.setCursor(sLastCommandPrintPosition, 1); - printByteHexOnLCD(tCommand); - - /* - * Show or clear repetition flag - */ - if (IrReceiver.decodedIRData.flags & (IRDATA_FLAGS_IS_REPEAT)) { - myLCD.print('R'); - return; // Since it is a repetition, printed data has not changed - } else { - myLCD.print(' '); - } - } // IrReceiver.decodedIRData.protocol == UNKNOWN -#endif // defined(USE_LCD) -} - -#if defined(USE_LCD) -size_t printByteHexOnLCD(uint16_t aHexByteValue) { - myLCD.print(F("0x")); - size_t tPrintSize = 2; - if (aHexByteValue < 0x10 || (aHexByteValue > 0x100 && aHexByteValue < 0x1000)) { - myLCD.print('0'); // leading 0 - tPrintSize++; - } - return myLCD.print(aHexByteValue, HEX) + tPrintSize; -} - -void printSpacesOnLCD(uint_fast8_t aNumberOfSpacesToPrint) { - for (uint_fast8_t i = 0; i < aNumberOfSpacesToPrint; ++i) { - myLCD.print(' '); - } -} -#endif diff --git a/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal.cpp b/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal.cpp deleted file mode 100644 index 5dcef0838442a63601b58872204687ee9471a00c..0000000000000000000000000000000000000000 --- a/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include "LiquidCrystal.h" - -#include <stdio.h> -#include <string.h> -#include <inttypes.h> -#include "Arduino.h" - -// When the display powers up, it is configured as follows: -// -// 1. Display clear -// 2. Function set: -// DL = 1; 8-bit interface data -// N = 0; 1-line display -// F = 0; 5x8 dot character font -// 3. Display on/off control: -// D = 0; Display off -// C = 0; Cursor off -// B = 0; Blinking off -// 4. Entry mode set: -// I/D = 1; Increment by 1 -// S = 0; No shift -// -// Note, however, that resetting the Arduino doesn't reset the LCD, so we -// can't assume that its in that state when a sketch starts (and the -// LiquidCrystal constructor is called). - -LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, - uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) -{ - init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); -} - -LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, - uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) -{ - init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); -} - -LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) -{ - init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); -} - -LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) -{ - init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); -} - -void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, - uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) -{ - _rs_pin = rs; - _rw_pin = rw; - _enable_pin = enable; - - _data_pins[0] = d0; - _data_pins[1] = d1; - _data_pins[2] = d2; - _data_pins[3] = d3; - _data_pins[4] = d4; - _data_pins[5] = d5; - _data_pins[6] = d6; - _data_pins[7] = d7; - - if (fourbitmode) - _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; - else - _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; - - begin(16, 1); -} - -void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { - if (lines > 1) { - _displayfunction |= LCD_2LINE; - } - _numlines = lines; - - setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols); - - // for some 1 line displays you can select a 10 pixel high font - if ((dotsize != LCD_5x8DOTS) && (lines == 1)) { - _displayfunction |= LCD_5x10DOTS; - } - - pinMode(_rs_pin, OUTPUT); - // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# - if (_rw_pin != 255) { - pinMode(_rw_pin, OUTPUT); - } - pinMode(_enable_pin, OUTPUT); - - // Do these once, instead of every time a character is drawn for speed reasons. - for (int i=0; i<((_displayfunction & LCD_8BITMODE) ? 8 : 4); ++i) - { - pinMode(_data_pins[i], OUTPUT); - } - - // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! - // according to datasheet, we need at least 40ms after power rises above 2.7V - // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50 - delayMicroseconds(50000); - // Now we pull both RS and R/W low to begin commands - digitalWrite(_rs_pin, LOW); - digitalWrite(_enable_pin, LOW); - if (_rw_pin != 255) { - digitalWrite(_rw_pin, LOW); - } - - //put the LCD into 4 bit or 8 bit mode - if (! (_displayfunction & LCD_8BITMODE)) { - // this is according to the hitachi HD44780 datasheet - // figure 24, pg 46 - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02); - } else { - // this is according to the hitachi HD44780 datasheet - // page 45 figure 23 - - // Send function set command sequence - command(LCD_FUNCTIONSET | _displayfunction); - delayMicroseconds(4500); // wait more than 4.1ms - - // second try - command(LCD_FUNCTIONSET | _displayfunction); - delayMicroseconds(150); - - // third go - command(LCD_FUNCTIONSET | _displayfunction); - } - - // finally, set # lines, font size, etc. - command(LCD_FUNCTIONSET | _displayfunction); - - // turn the display on with no cursor or blinking default - _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; - display(); - - // clear it off - clear(); - - // Initialize to default text direction (for romance languages) - _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; - // set the entry mode - command(LCD_ENTRYMODESET | _displaymode); - -} - -void LiquidCrystal::setRowOffsets(int row0, int row1, int row2, int row3) -{ - _row_offsets[0] = row0; - _row_offsets[1] = row1; - _row_offsets[2] = row2; - _row_offsets[3] = row3; -} - -/********** high level commands, for the user! */ -void LiquidCrystal::clear() -{ - command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - delayMicroseconds(2000); // this command takes a long time! -} - -void LiquidCrystal::home() -{ - command(LCD_RETURNHOME); // set cursor position to zero - delayMicroseconds(2000); // this command takes a long time! -} - -void LiquidCrystal::setCursor(uint8_t col, uint8_t row) -{ - const size_t max_lines = sizeof(_row_offsets) / sizeof(*_row_offsets); - if ( row >= max_lines ) { - row = max_lines - 1; // we count rows starting w/0 - } - if ( row >= _numlines ) { - row = _numlines - 1; // we count rows starting w/0 - } - - command(LCD_SETDDRAMADDR | (col + _row_offsets[row])); -} - -// Turn the display on/off (quickly) -void LiquidCrystal::noDisplay() { - _displaycontrol &= ~LCD_DISPLAYON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal::display() { - _displaycontrol |= LCD_DISPLAYON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// Turns the underline cursor on/off -void LiquidCrystal::noCursor() { - _displaycontrol &= ~LCD_CURSORON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal::cursor() { - _displaycontrol |= LCD_CURSORON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// Turn on and off the blinking cursor -void LiquidCrystal::noBlink() { - _displaycontrol &= ~LCD_BLINKON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal::blink() { - _displaycontrol |= LCD_BLINKON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// These commands scroll the display without changing the RAM -void LiquidCrystal::scrollDisplayLeft(void) { - command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); -} -void LiquidCrystal::scrollDisplayRight(void) { - command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); -} - -// This is for text that flows Left to Right -void LiquidCrystal::leftToRight(void) { - _displaymode |= LCD_ENTRYLEFT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This is for text that flows Right to Left -void LiquidCrystal::rightToLeft(void) { - _displaymode &= ~LCD_ENTRYLEFT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This will 'right justify' text from the cursor -void LiquidCrystal::autoscroll(void) { - _displaymode |= LCD_ENTRYSHIFTINCREMENT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This will 'left justify' text from the cursor -void LiquidCrystal::noAutoscroll(void) { - _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// Allows us to fill the first 8 CGRAM locations -// with custom characters -void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) { - location &= 0x7; // we only have 8 locations 0-7 - command(LCD_SETCGRAMADDR | (location << 3)); - for (int i=0; i<8; i++) { - write(charmap[i]); - } -} - -/*********** mid level commands, for sending data/cmds */ - -inline void LiquidCrystal::command(uint8_t value) { - send(value, LOW); -} - -inline size_t LiquidCrystal::write(uint8_t value) { - send(value, HIGH); - return 1; // assume sucess -} - -/************ low level data pushing commands **********/ - -// write either command or data, with automatic 4/8-bit selection -void LiquidCrystal::send(uint8_t value, uint8_t mode) { - digitalWrite(_rs_pin, mode); - - // if there is a RW pin indicated, set it low to Write - if (_rw_pin != 255) { - digitalWrite(_rw_pin, LOW); - } - - if (_displayfunction & LCD_8BITMODE) { - write8bits(value); - } else { - write4bits(value>>4); - write4bits(value); - } -} - -void LiquidCrystal::pulseEnable(void) { - digitalWrite(_enable_pin, LOW); - delayMicroseconds(1); - digitalWrite(_enable_pin, HIGH); - delayMicroseconds(1); // enable pulse must be >450ns - digitalWrite(_enable_pin, LOW); - delayMicroseconds(100); // commands need > 37us to settle -} - -void LiquidCrystal::write4bits(uint8_t value) { - for (int i = 0; i < 4; i++) { - digitalWrite(_data_pins[i], (value >> i) & 0x01); - } - - pulseEnable(); -} - -void LiquidCrystal::write8bits(uint8_t value) { - for (int i = 0; i < 8; i++) { - digitalWrite(_data_pins[i], (value >> i) & 0x01); - } - - pulseEnable(); -} diff --git a/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal.h b/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal.h deleted file mode 100644 index 07206242596e1675329ba360269106198aee4fbd..0000000000000000000000000000000000000000 --- a/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef LiquidCrystal_h -#define LiquidCrystal_h - -#include <inttypes.h> -#include "Print.h" - -// commands -#define LCD_CLEARDISPLAY 0x01 -#define LCD_RETURNHOME 0x02 -#define LCD_ENTRYMODESET 0x04 -#define LCD_DISPLAYCONTROL 0x08 -#define LCD_CURSORSHIFT 0x10 -#define LCD_FUNCTIONSET 0x20 -#define LCD_SETCGRAMADDR 0x40 -#define LCD_SETDDRAMADDR 0x80 - -// flags for display entry mode -#define LCD_ENTRYRIGHT 0x00 -#define LCD_ENTRYLEFT 0x02 -#define LCD_ENTRYSHIFTINCREMENT 0x01 -#define LCD_ENTRYSHIFTDECREMENT 0x00 - -// flags for display on/off control -#define LCD_DISPLAYON 0x04 -#define LCD_DISPLAYOFF 0x00 -#define LCD_CURSORON 0x02 -#define LCD_CURSOROFF 0x00 -#define LCD_BLINKON 0x01 -#define LCD_BLINKOFF 0x00 - -// flags for display/cursor shift -#define LCD_DISPLAYMOVE 0x08 -#define LCD_CURSORMOVE 0x00 -#define LCD_MOVERIGHT 0x04 -#define LCD_MOVELEFT 0x00 - -// flags for function set -#define LCD_8BITMODE 0x10 -#define LCD_4BITMODE 0x00 -#define LCD_2LINE 0x08 -#define LCD_1LINE 0x00 -#define LCD_5x10DOTS 0x04 -#define LCD_5x8DOTS 0x00 - -class LiquidCrystal : public Print { -public: - LiquidCrystal(uint8_t rs, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, - uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); - LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, - uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); - LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); - LiquidCrystal(uint8_t rs, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); - - void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, - uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, - uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); - - void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); - - void clear(); - void home(); - - void noDisplay(); - void display(); - void noBlink(); - void blink(); - void noCursor(); - void cursor(); - void scrollDisplayLeft(); - void scrollDisplayRight(); - void leftToRight(); - void rightToLeft(); - void autoscroll(); - void noAutoscroll(); - - void setRowOffsets(int row1, int row2, int row3, int row4); - void createChar(uint8_t, uint8_t[]); - void setCursor(uint8_t, uint8_t); - virtual size_t write(uint8_t); - void command(uint8_t); - - using Print::write; -private: - void send(uint8_t, uint8_t); - void write4bits(uint8_t); - void write8bits(uint8_t); - void pulseEnable(); - - uint8_t _rs_pin; // LOW: command. HIGH: character. - uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD. - uint8_t _enable_pin; // activated by a HIGH pulse. - uint8_t _data_pins[8]; - - uint8_t _displayfunction; - uint8_t _displaycontrol; - uint8_t _displaymode; - - uint8_t _initialized; - - uint8_t _numlines; - uint8_t _row_offsets[4]; -}; - -#endif diff --git a/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal_I2C.cpp b/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal_I2C.cpp deleted file mode 100644 index f89c9810911a62c2a00e467af7b4fc34ca621bb3..0000000000000000000000000000000000000000 --- a/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal_I2C.cpp +++ /dev/null @@ -1,344 +0,0 @@ -// Based on the work by DFRobot - -#include "Arduino.h" - -#if defined(__AVR__) && !defined(USE_SOFT_I2C_MASTER) && __has_include("SoftI2CMasterConfig.h") -#define USE_SOFT_I2C_MASTER // must be before #include "LiquidCrystal_I2C.h" -#endif - -#include "LiquidCrystal_I2C.h" -#include <inttypes.h> - -inline size_t LiquidCrystal_I2C::write(uint8_t value) { - send(value, Rs); - return 1; -} - -#if defined(USE_SOFT_I2C_MASTER) -//#define USE_SOFT_I2C_MASTER_H_AS_PLAIN_INCLUDE -#include "SoftI2CMasterConfig.h" // Include configuration for sources -#include "SoftI2CMaster.h" // include sources -#elif defined(USE_SOFT_WIRE) -#define USE_SOFTWIRE_H_AS_PLAIN_INCLUDE -#include "SoftWire.h" -#endif - -// When the display powers up, it is configured as follows: -// -// 1. Display clear -// 2. Function set: -// DL = 1; 8-bit interface data -// N = 0; 1-line display -// F = 0; 5x8 dot character font -// 3. Display on/off control: -// D = 0; Display off -// C = 0; Cursor off -// B = 0; Blinking off -// 4. Entry mode set: -// I/D = 1; Increment by 1 -// S = 0; No shift -// -// Note, however, that resetting the Arduino doesn't reset the LCD, so we -// can't assume that its in that state when a sketch starts (and the -// LiquidCrystal constructor is called). - -LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t lcd_cols, uint8_t lcd_rows) { - _Addr = lcd_Addr; - _cols = lcd_cols; - _rows = lcd_rows; - _backlightval = LCD_NOBACKLIGHT; - _oled = false; -} - -void LiquidCrystal_I2C::oled_init() { - _oled = true; - init_priv(); -} - -void LiquidCrystal_I2C::init() { - init_priv(); -} - -void LiquidCrystal_I2C::init_priv() { -#if defined(USE_SOFT_I2C_MASTER) - i2c_init(); -#else - Wire.begin(); -#endif - _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; - begin(_cols, _rows); -} - -void LiquidCrystal_I2C::begin(uint8_t cols __attribute__((unused)), uint8_t lines, uint8_t dotsize) { - if (lines > 1) { - _displayfunction |= LCD_2LINE; - } - _numlines = lines; - - // for some 1 line displays you can select a 10 pixel high font - if ((dotsize != 0) && (lines == 1)) { - _displayfunction |= LCD_5x10DOTS; - } - - // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! - // according to datasheet, we need at least 40ms after power rises above 2.7V - // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50 - delay(50); - - // Now we pull both RS and R/W low to begin commands - expanderWrite(_backlightval); // reset expander and turn backlight off (Bit 8 =1) - delay(1000); - - //put the LCD into 4 bit mode - // this is according to the hitachi HD44780 datasheet - // figure 24, pg 46 - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03 << 4); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02 << 4); - - // set # lines, font size, etc. - command(LCD_FUNCTIONSET | _displayfunction); - - // turn the display on with no cursor or blinking default - _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; - display(); - - // clear it off - clear(); - - // Initialize to default text direction (for roman languages) - _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; - - // set the entry mode - command(LCD_ENTRYMODESET | _displaymode); - - home(); - -} - -/********** high level commands, for the user! */ -void LiquidCrystal_I2C::clear() { - command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - delayMicroseconds(2000); // this command takes a long time! - if (_oled) - setCursor(0, 0); -} - -void LiquidCrystal_I2C::home() { - command(LCD_RETURNHOME); // set cursor position to zero - delayMicroseconds(2000); // this command takes a long time! -} - -void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row) { - int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; - if (row > _numlines) { - row = _numlines - 1; // we count rows starting w/0 - } - command(LCD_SETDDRAMADDR | (col + row_offsets[row])); -} - -// Turn the display on/off (quickly) -void LiquidCrystal_I2C::noDisplay() { - _displaycontrol &= ~LCD_DISPLAYON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal_I2C::display() { - _displaycontrol |= LCD_DISPLAYON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// Turns the underline cursor on/off -void LiquidCrystal_I2C::noCursor() { - _displaycontrol &= ~LCD_CURSORON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal_I2C::cursor() { - _displaycontrol |= LCD_CURSORON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// Turn on and off the blinking cursor -void LiquidCrystal_I2C::noBlink() { - _displaycontrol &= ~LCD_BLINKON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal_I2C::blink() { - _displaycontrol |= LCD_BLINKON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// These commands scroll the display without changing the RAM -void LiquidCrystal_I2C::scrollDisplayLeft(void) { - command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); -} -void LiquidCrystal_I2C::scrollDisplayRight(void) { - command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); -} - -// This is for text that flows Left to Right -void LiquidCrystal_I2C::leftToRight(void) { - _displaymode |= LCD_ENTRYLEFT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This is for text that flows Right to Left -void LiquidCrystal_I2C::rightToLeft(void) { - _displaymode &= ~LCD_ENTRYLEFT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This will 'right justify' text from the cursor -void LiquidCrystal_I2C::autoscroll(void) { - _displaymode |= LCD_ENTRYSHIFTINCREMENT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This will 'left justify' text from the cursor -void LiquidCrystal_I2C::noAutoscroll(void) { - _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// Allows us to fill the first 8 CGRAM locations -// with custom characters -void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) { - location &= 0x7; // we only have 8 locations 0-7 - command(LCD_SETCGRAMADDR | (location << 3)); - for (int i = 0; i < 8; i++) { - write(charmap[i]); - } -} - -//createChar with PROGMEM input -void LiquidCrystal_I2C::createChar(uint8_t location, const char *charmap) { - location &= 0x7; // we only have 8 locations 0-7 - command(LCD_SETCGRAMADDR | (location << 3)); - for (int i = 0; i < 8; i++) { - write(pgm_read_byte_near(charmap++)); - } -} - -// Turn the (optional) backlight off/on -void LiquidCrystal_I2C::noBacklight(void) { - _backlightval = LCD_NOBACKLIGHT; - expanderWrite(0); -} - -void LiquidCrystal_I2C::backlight(void) { - _backlightval = LCD_BACKLIGHT; - expanderWrite(0); -} - -/*********** mid level commands, for sending data/cmds */ - -inline void LiquidCrystal_I2C::command(uint8_t value) { - send(value, 0); -} - -/************ low level data pushing commands **********/ - -// write either command or data -void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) { - uint8_t highnib = value & 0xf0; - uint8_t lownib = (value << 4) & 0xf0; - write4bits((highnib) | mode); - write4bits((lownib) | mode); -} - -void LiquidCrystal_I2C::write4bits(uint8_t value) { - expanderWrite(value); - pulseEnable(value); -} - -void LiquidCrystal_I2C::expanderWrite(uint8_t _data) { -#if defined(USE_SOFT_I2C_MASTER) - i2c_write_byte(_Addr << 1, _data | _backlightval); -#else - Wire.beginTransmission(_Addr); - Wire.write((int )(_data) | _backlightval); - Wire.endTransmission(); -#endif -} - -void LiquidCrystal_I2C::pulseEnable(uint8_t _data) { - expanderWrite(_data | En); // En high - delayMicroseconds(1); // enable pulse must be >450ns - - expanderWrite(_data & ~En); // En low - delayMicroseconds(50); // commands need > 37us to settle -} - -// Alias functions - -void LiquidCrystal_I2C::cursor_on() { - cursor(); -} - -void LiquidCrystal_I2C::cursor_off() { - noCursor(); -} - -void LiquidCrystal_I2C::blink_on() { - blink(); -} - -void LiquidCrystal_I2C::blink_off() { - noBlink(); -} - -void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows) { - createChar(char_num, rows); -} - -void LiquidCrystal_I2C::setBacklight(uint8_t new_val) { - if (new_val) { - backlight(); // turn backlight on - } else { - noBacklight(); // turn backlight off - } -} - -void LiquidCrystal_I2C::printstr(const char c[]) { - //This function is not identical to the function used for "real" I2C displays - //it's here so the user sketch doesn't have to be changed - print(c); -} - -// unsupported API functions -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -void LiquidCrystal_I2C::off() { -} -void LiquidCrystal_I2C::on() { -} -void LiquidCrystal_I2C::setDelay(int cmdDelay, int charDelay) { -} -uint8_t LiquidCrystal_I2C::status() { - return 0; -} -uint8_t LiquidCrystal_I2C::keypad() { - return 0; -} -uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype) { - return 0; -} -void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end) { -} -void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end) { -} -void LiquidCrystal_I2C::setContrast(uint8_t new_val) { -} -#pragma GCC diagnostic pop - diff --git a/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal_I2C.h b/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal_I2C.h deleted file mode 100644 index 420214a481a98b6f08f926a5f2d9aa665d8a5aee..0000000000000000000000000000000000000000 --- a/IRremote/examples/AllProtocolsOnLCD/LiquidCrystal_I2C.h +++ /dev/null @@ -1,129 +0,0 @@ -//YWROBOT -#ifndef LiquidCrystal_I2C_h -#define LiquidCrystal_I2C_h - -#include <inttypes.h> -#include "Print.h" -#if !defined(USE_SOFT_I2C_MASTER) && !defined(USE_SOFT_WIRE) -#include <Wire.h> -#endif - -// commands -#define LCD_CLEARDISPLAY 0x01 -#define LCD_RETURNHOME 0x02 -#define LCD_ENTRYMODESET 0x04 -#define LCD_DISPLAYCONTROL 0x08 -#define LCD_CURSORSHIFT 0x10 -#define LCD_FUNCTIONSET 0x20 -#define LCD_SETCGRAMADDR 0x40 -#define LCD_SETDDRAMADDR 0x80 - -// flags for display entry mode -#define LCD_ENTRYRIGHT 0x00 -#define LCD_ENTRYLEFT 0x02 -#define LCD_ENTRYSHIFTINCREMENT 0x01 -#define LCD_ENTRYSHIFTDECREMENT 0x00 - -// flags for display on/off control -#define LCD_DISPLAYON 0x04 -#define LCD_DISPLAYOFF 0x00 -#define LCD_CURSORON 0x02 -#define LCD_CURSOROFF 0x00 -#define LCD_BLINKON 0x01 -#define LCD_BLINKOFF 0x00 - -// flags for display/cursor shift -#define LCD_DISPLAYMOVE 0x08 -#define LCD_CURSORMOVE 0x00 -#define LCD_MOVERIGHT 0x04 -#define LCD_MOVELEFT 0x00 - -// flags for function set -#define LCD_8BITMODE 0x10 -#define LCD_4BITMODE 0x00 -#define LCD_2LINE 0x08 -#define LCD_1LINE 0x00 -#define LCD_5x10DOTS 0x04 -#define LCD_5x8DOTS 0x00 - -// flags for backlight control -#define LCD_BACKLIGHT 0x08 -#define LCD_NOBACKLIGHT 0x00 - -#define En 0b00000100 // Enable bit -#define Rw 0b00000010 // Read/Write bit -#define Rs 0b00000001 // Register select bit - -class LiquidCrystal_I2C : public Print { -public: - LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows); - void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS ); - void clear(); - void home(); - void noDisplay(); - void display(); - void noBlink(); - void blink(); - void noCursor(); - void cursor(); - void scrollDisplayLeft(); - void scrollDisplayRight(); - void printLeft(); - void printRight(); - void leftToRight(); - void rightToLeft(); - void shiftIncrement(); - void shiftDecrement(); - void noBacklight(); - void backlight(); - void autoscroll(); - void noAutoscroll(); - void createChar(uint8_t, uint8_t[]); - void createChar(uint8_t location, const char *charmap); - // Example: const char bell[8] PROGMEM = {B00100,B01110,B01110,B01110,B11111,B00000,B00100,B00000}; - - void setCursor(uint8_t, uint8_t); - size_t write(uint8_t); - void command(uint8_t); - void init(); - void oled_init(); - -////compatibility API function aliases -void blink_on(); // alias for blink() -void blink_off(); // alias for noBlink() -void cursor_on(); // alias for cursor() -void cursor_off(); // alias for noCursor() -void setBacklight(uint8_t new_val); // alias for backlight() and nobacklight() -void load_custom_character(uint8_t char_num, uint8_t *rows); // alias for createChar() -void printstr(const char[]); - -////Unsupported API functions (not implemented in this library) -uint8_t status(); -void setContrast(uint8_t new_val); -uint8_t keypad(); -void setDelay(int,int); -void on(); -void off(); -uint8_t init_bargraph(uint8_t graphtype); -void draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); -void draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); - - -private: - void init_priv(); - void send(uint8_t, uint8_t); - void write4bits(uint8_t); - void expanderWrite(uint8_t); - void pulseEnable(uint8_t); - uint8_t _Addr; - uint8_t _displayfunction; - uint8_t _displaycontrol; - uint8_t _displaymode; - uint8_t _numlines; - bool _oled; - uint8_t _cols; - uint8_t _rows; - uint8_t _backlightval; -}; - -#endif diff --git a/IRremote/examples/AllProtocolsOnLCD/PinDefinitionsAndMore.h b/IRremote/examples/AllProtocolsOnLCD/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/AllProtocolsOnLCD/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/ControlRelay/ControlRelay.ino b/IRremote/examples/ControlRelay/ControlRelay.ino deleted file mode 100644 index 1460872f40213e8bf6fa669eb0f679e6866eda62..0000000000000000000000000000000000000000 --- a/IRremote/examples/ControlRelay/ControlRelay.ino +++ /dev/null @@ -1,106 +0,0 @@ -/* - * ControlRelay.cpp - * - * Toggles an output pin at each command received - * An IR detector/demodulator must be connected to the input RECV_PIN. - * Initially coded 2009 Ken Shirriff http://www.righto.com - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2009-2021 Ken Shirriff, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -#if FLASHEND <= 0x1FFF || (RAMEND <= 0x4FF || RAMSIZE < 0x4FF) // For 8k flash or 512 bytes RAM or less, like ATtiny85, ATtiny167 -#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. -#define EXCLUDE_EXOTIC_PROTOCOLS -#endif - -#include <IRremote.hpp> - -#if defined(APPLICATION_PIN) -#define RELAY_PIN APPLICATION_PIN -#else -#define RELAY_PIN 5 -#endif - -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - pinMode(RELAY_PIN, OUTPUT); - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); -} - -int on = 0; -unsigned long last = millis(); - -void loop() { - if (IrReceiver.decode()) { - // If it's been at least 1/4 second since the last - // IR received, toggle the relay - if (millis() - last > 250) { - on = !on; - Serial.print(F("Switch relay ")); - if (on) { - digitalWrite(RELAY_PIN, HIGH); - Serial.println(F("on")); - } else { - digitalWrite(RELAY_PIN, LOW); - Serial.println(F("off")); - } - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); - Serial.println(); - if (IrReceiver.decodedIRData.protocol == UNKNOWN) { - // We have an unknown protocol, print more info - Serial.println(F("Received noise or an unknown (or not yet enabled) protocol")); - IrReceiver.printIRResultRawFormatted(&Serial, true); - } -#else - // Print a minimal summary of received data - IrReceiver.printIRResultMinimal(&Serial); - Serial.println(); -#endif // FLASHEND - } - last = millis(); - IrReceiver.resume(); // Enable receiving of the next value - } -} diff --git a/IRremote/examples/ControlRelay/PinDefinitionsAndMore.h b/IRremote/examples/ControlRelay/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/ControlRelay/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/IRDispatcherDemo/DemoIRCommandMapping.h b/IRremote/examples/IRDispatcherDemo/DemoIRCommandMapping.h deleted file mode 100644 index 26110da23a09e5a9dcdc6f2308d3ee32fec3cdbc..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRDispatcherDemo/DemoIRCommandMapping.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * DemoIRCommandMapping.h - * - * IR remote button codes, strings, and functions to call - * - * Copyright (C) 2019-2022 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - */ - -#ifndef _IR_COMMAND_MAPPING_H -#define _IR_COMMAND_MAPPING_H - -#include <Arduino.h> -//#include "Commands.h" // includes all the commands used in the mapping arrays below - -/* - * !!! Choose your remote !!! - */ -//#define USE_KEYES_REMOTE_CLONE With number pad and direction control switched, will be taken as default -//#define USE_KEYES_REMOTE -#if !defined(USE_KEYES_REMOTE) && !defined(USE_KEYES_REMOTE_CLONE) -#define USE_KEYES_REMOTE_CLONE // the one you can buy at aliexpress -#endif - -#if (defined(USE_KEYES_REMOTE) && defined(USE_KEYES_REMOTE_CLONE)) -#error "Please choose only one remote for compile" -#endif - -#if defined(USE_KEYES_REMOTE_CLONE) -#define IR_REMOTE_NAME "KEYES_CLONE" -// Codes for the KEYES CLONE remote control with 17 keys with number pad above direction control -#if defined(USE_IRMP_LIBRARY) -#define IR_ADDRESS 0xFF00 // IRMP interprets NEC addresses always as 16 bit -#else -#define IR_ADDRESS 0x00 -#endif - -#define IR_UP 0x18 -#define IR_DOWN 0x52 -#define IR_RIGHT 0x5A -#define IR_LEFT 0x08 -#define IR_OK 0x1C - -#define IR_1 0x45 -#define IR_2 0x46 -#define IR_3 0x47 -#define IR_4 0x44 -#define IR_5 0x40 -#define IR_6 0x43 -#define IR_7 0x07 -#define IR_8 0x15 -#define IR_9 0x09 -#define IR_0 0x19 - -#define IR_STAR 0x16 -#define IR_HASH 0x0D -/* - * SECOND: - * IR button to command mapping for better reading. IR buttons should only referenced here. - */ -#define COMMAND_ON IR_UP -#define COMMAND_OFF IR_DOWN -#define COMMAND_INCREASE_BLINK IR_RIGHT -#define COMMAND_DECREASE_BLINK IR_LEFT - -#define COMMAND_START IR_OK -#define COMMAND_STOP IR_HASH -#define COMMAND_RESET IR_STAR -#define COMMAND_BLINK IR_0 -#define COMMAND_TONE1 IR_1 - -#define COMMAND_TONE2 IR_2 -#define COMMAND_TONE3 IR_3 -//#define IR_4 -//#define IR_5 -//#define IR_6 -//#define IR_7 -//#define IR_8 -//#define IR_9 - -#endif - -#if defined(USE_KEYES_REMOTE) -#define IR_REMOTE_NAME "KEYES" -/* - * FIRST: - * IR code to button mapping for better reading. IR codes should only referenced here. - */ -// Codes for the KEYES remote control with 17 keys and direction control above number pad -#if defined(USE_IRMP_LIBRARY) -#define IR_ADDRESS 0xFF00 // IRMP interprets NEC addresses always as 16 bit -#else -#define IR_ADDRESS 0x00 -#endif - -#define IR_UP 0x46 -#define IR_DOWN 0x15 -#define IR_RIGHT 0x43 -#define IR_LEFT 0x44 -#define IR_OK 0x40 - -#define IR_1 0x16 -#define IR_2 0x19 -#define IR_3 0x0D -#define IR_4 0x0C -#define IR_5 0x18 -#define IR_6 0x5E -#define IR_7 0x08 -#define IR_8 0x1C -#define IR_9 0x5A -#define IR_0 0x52 - -#define IR_STAR 0x42 -#define IR_HASH 0x4A - -/* - * SECOND: - * IR button to command mapping for better reading. IR buttons should only referenced here. - */ -#define COMMAND_ON IR_UP -#define COMMAND_OFF IR_DOWN -#define COMMAND_INCREASE_BLINK IR_RIGHT -#define COMMAND_DECREASE_BLINK IR_LEFT - -#define COMMAND_RESET IR_OK -#define COMMAND_STOP IR_HASH -#define COMMAND_STOP IR_STAR -#define COMMAND_BLINK IR_0 -#define COMMAND_TONE2 IR_1 - -#define COMMAND_TONE1 IR_2 -#define COMMAND_TONE2 IR_3 -#define COMMAND_TONE2 IR_4 -#define COMMAND_TONE2 IR_5 -#define COMMAND_TONE2 IR_6 -#define COMMAND_TONE2 IR_7 -#define COMMAND_TONE2 IR_8 -#define COMMAND_TONE2 IR_9 -#endif - -/* - * THIRD: - * Main mapping of commands to C functions - */ - -// IR strings of functions for output -static const char LEDon[] PROGMEM ="LED on"; -static const char LEDoff[] PROGMEM ="LED off"; - -static const char blink20times[] PROGMEM ="blink 20 times"; -static const char blinkStart[] PROGMEM ="blink start"; - -static const char increaseBlink[] PROGMEM ="increase blink frequency"; -static const char decreaseBlink[] PROGMEM ="decrease blink frequency"; - -static const char tone2200[] PROGMEM ="tone 2200"; -static const char tone1800[] PROGMEM ="tone 1800"; -static const char printMenu[] PROGMEM ="printMenu"; - -static const char reset[] PROGMEM ="reset"; -static const char stop[] PROGMEM ="stop"; - -// not used yet -static const char test[] PROGMEM ="test"; -static const char pattern[] PROGMEM ="pattern"; -static const char unknown[] PROGMEM ="unknown"; - -/* - * Main mapping array of commands to C functions and command strings - */ -const struct IRToCommandMappingStruct IRMapping[] = { /**/ -{ COMMAND_BLINK, IR_COMMAND_FLAG_BLOCKING, &doLedBlink20times, blink20times }, /**/ -{ COMMAND_STOP, IR_COMMAND_FLAG_BLOCKING, &doStop, stop }, - -/* - * Short commands, which can be executed always - */ -{ COMMAND_TONE1, IR_COMMAND_FLAG_BLOCKING, &doTone1800, tone1800 }, /**/ -{ COMMAND_TONE3, IR_COMMAND_FLAG_BLOCKING, &doPrintMenu, printMenu }, /**/ -{ COMMAND_ON, IR_COMMAND_FLAG_NON_BLOCKING, &doLedOn, LEDon }, /**/ -{ COMMAND_OFF, IR_COMMAND_FLAG_NON_BLOCKING, &doLedOff, LEDoff }, /**/ -{ COMMAND_START, IR_COMMAND_FLAG_NON_BLOCKING, &doLedBlinkStart, blinkStart }, /**/ -{ COMMAND_RESET, IR_COMMAND_FLAG_NON_BLOCKING, &doResetBlinkFrequency, reset }, - -/* - * Repeatable short commands - */ -{ COMMAND_TONE2, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doTone2200, tone2200 }, /**/ -{ COMMAND_INCREASE_BLINK, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doIncreaseBlinkFrequency, increaseBlink }, /**/ -{ COMMAND_DECREASE_BLINK, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doDecreaseBlinkFrequency, decreaseBlink } }; - -#endif // _IR_COMMAND_MAPPING_H diff --git a/IRremote/examples/IRDispatcherDemo/IRCommandDispatcher.h b/IRremote/examples/IRDispatcherDemo/IRCommandDispatcher.h deleted file mode 100644 index e3f46127b1f3d4a1457b7f39aaa7ecf66d8efed2..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRDispatcherDemo/IRCommandDispatcher.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * IRCommandDispatcher.h - * - * Library to process IR commands by calling functions specified in a mapping array. - * - * To run this example you need to install the "IRremote" or "IRMP" library under "Tools -> Manage Libraries..." or "Ctrl+Shift+I" - * - * Copyright (C) 2019-2021 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of ServoEasing https://github.com/ArminJo/ServoEasing. - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * ServoEasing is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - */ - -#ifndef _IR_COMMAND_DISPATCHER_H -#define _IR_COMMAND_DISPATCHER_H - -#include <stdint.h> - -/* - * For command mapping file - */ -#define IR_COMMAND_FLAG_BLOCKING 0x00 // default - blocking command, repeat not accepted, only one command at a time. Stops an already running command. -#define IR_COMMAND_FLAG_REPEATABLE 0x01 // repeat accepted -#define IR_COMMAND_FLAG_NON_BLOCKING 0x02 // Non blocking (short) command that can be processed any time and may interrupt other IR commands - used for stop, set direction etc. -#define IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING (IR_COMMAND_FLAG_REPEATABLE | IR_COMMAND_FLAG_NON_BLOCKING) - -// Basic mapping structure -struct IRToCommandMappingStruct { -#if defined(IR_COMMAND_HAS_MORE_THAN_8_BIT) - uint16_t IRCode; -#else - uint8_t IRCode; -#endif - uint8_t Flags; - void (*CommandToCall)(); - const char *CommandString; -}; - -struct IRDataForCommandDispatcherStruct { - uint16_t address; // to distinguish between multiple senders -#if defined(IR_COMMAND_HAS_MORE_THAN_8_BIT) - uint16_t command; -#else - uint8_t command; -#endif - bool isRepeat; - uint32_t MillisOfLastCode; // millis() of last IR command -including repeats!- received - for timeouts etc. - volatile bool isAvailable; // flag for a polling interpreting function, that a new command has arrived. Is set true by library and set false by main loop. -}; - -/* - * Special codes (hopefully) not sent by the remote - otherwise please redefine it here - */ -#if defined(IR_COMMAND_HAS_MORE_THAN_8_BIT) -#define COMMAND_EMPTY 0xFFFF // code no command -#else -#define COMMAND_EMPTY 0xFF // code no command -#endif - -#define RETURN_IF_STOP if (IRDispatcher.requestToStopReceived) return -#define BREAK_IF_STOP if (IRDispatcher.requestToStopReceived) break -#define DELAY_AND_RETURN_IF_STOP(aDurationMillis) if (IRDispatcher.delayAndCheckForStop(aDurationMillis)) return - -class IRCommandDispatcher { -public: - void init(); - - bool checkAndRunNonBlockingCommands(); - bool checkAndRunSuspendedBlockingCommands(); -#if defined(IR_COMMAND_HAS_MORE_THAN_8_BIT) - void setNextBlockingCommand(uint16_t aBlockingCommandToRunNext); -#else - void setNextBlockingCommand(uint8_t aBlockingCommandToRunNext); -#endif - bool delayAndCheckForStop(uint16_t aDelayMillis); - - // The main dispatcher function - void checkAndCallCommand(bool aCallBlockingCommandImmediately); - - void printIRCommandString(Print *aSerial); - void setRequestToStopReceived(bool aRequestToStopReceived = true); - -#if defined(IR_COMMAND_HAS_MORE_THAN_8_BIT) - uint16_t currentBlockingCommandCalled = COMMAND_EMPTY; // The code for the current called command - uint16_t lastBlockingCommandCalled = COMMAND_EMPTY; // The code for the last called command. Can be evaluated by main loop - uint16_t BlockingCommandToRunNext = COMMAND_EMPTY; // Storage for command currently suspended to allow the current command to end, before it is called by main loop -#else - uint8_t currentBlockingCommandCalled = COMMAND_EMPTY; // The code for the current called command - uint8_t lastBlockingCommandCalled = COMMAND_EMPTY; // The code for the last called command. Can be evaluated by main loop - uint8_t BlockingCommandToRunNext = COMMAND_EMPTY; // Storage for command currently suspended to allow the current command to end, before it is called by main loop -#endif - bool justCalledBlockingCommand = false; // Flag that a blocking command was received and called - is set before call of command - /* - * Flag for running blocking commands to terminate. To check, you can use "if (IRDispatcher.requestToStopReceived) return;" (available as macro RETURN_IF_STOP). - * Is reset by next IR command received. Can be reset by main loop, if command has stopped. - */ - volatile bool requestToStopReceived; - /* - * This flag must be true, if we have a function, which want to interpret the IR codes by itself e.g. the calibrate function of QuadrupedControl - */ - bool doNotUseDispatcher = false; - - struct IRDataForCommandDispatcherStruct IRReceivedData; - -}; - -extern IRCommandDispatcher IRDispatcher; - -#endif // _IR_COMMAND_DISPATCHER_H diff --git a/IRremote/examples/IRDispatcherDemo/IRCommandDispatcher.hpp b/IRremote/examples/IRDispatcherDemo/IRCommandDispatcher.hpp deleted file mode 100644 index f2bc25982926c7aa91447031110ecd7d209753c7..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRDispatcherDemo/IRCommandDispatcher.hpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * IRCommandDispatcher.hpp - * - * Library to process IR commands by calling functions specified in a mapping array. - * Commands can be tagged as blocking or non blocking. - * - * To run this example you need to install the "IRremote" or "IRMP" library. - * Install it under "Tools -> Manage Libraries..." or "Ctrl+Shift+I" - * - * The IR library calls a callback function, which executes a non blocking command directly in ISR (Interrupt Service Routine) context! - * A blocking command is stored and sets a stop flag for an already running blocking function to terminate. - * The blocking command can in turn be executed by main loop by calling IRDispatcher.checkAndRunSuspendedBlockingCommands(). - * - * Copyright (C) 2019-2022 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of ServoEasing https://github.com/ArminJo/ServoEasing. - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * ServoEasing is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - */ -#ifndef _IR_COMMAND_DISPATCHER_HPP -#define _IR_COMMAND_DISPATCHER_HPP - -#include <Arduino.h> - -#include "IRCommandDispatcher.h" - -/* - * Enable this to see information on each call. - * Since there should be no library which uses Serial, it should only be enabled for development purposes. - */ -#if defined(INFO) && !defined(LOCAL_INFO) -#define LOCAL_INFO -#else -//#define LOCAL_INFO // This enables info output only for this file -#endif -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -// Propagate debug level -#define LOCAL_INFO -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -IRCommandDispatcher IRDispatcher; - -#if defined(USE_TINY_IR_RECEIVER) -#include "TinyIRReceiver.hpp" // included in "IRremote" library - -#if defined(LOCAL_INFO) -#define CD_INFO_PRINT(...) Serial.print(__VA_ARGS__); -#define CD_INFO_PRINTLN(...) Serial.println(__VA_ARGS__); -#else -#define CD_INFO_PRINT(...) void(); -#define CD_INFO_PRINTLN(...) void(); -#endif - -void IRCommandDispatcher::init() { - initPCIInterruptForTinyReceiver(); -} - -/* - * This is the TinyReceiver callback function, which is called if a complete command was received - * It checks for right address and then call the dispatcher - */ -#if defined(ESP8266) || defined(ESP32) -IRAM_ATTR -#endif -void handleReceivedTinyIRData(uint8_t aAddress, uint8_t aCommand, uint8_t aFlags) { - IRDispatcher.IRReceivedData.address = aAddress; - IRDispatcher.IRReceivedData.command = aCommand; - IRDispatcher.IRReceivedData.isRepeat = aFlags & IRDATA_FLAGS_IS_REPEAT; - IRDispatcher.IRReceivedData.MillisOfLastCode = millis(); - - CD_INFO_PRINT(F("A=0x")); - CD_INFO_PRINT(aAddress, HEX); - CD_INFO_PRINT(F(" C=0x")); - CD_INFO_PRINT(aCommand, HEX); - if (IRDispatcher.IRReceivedData.isRepeat) { - CD_INFO_PRINT(F("R")); - } - CD_INFO_PRINTLN(); - - if (aAddress == IR_ADDRESS) { // IR_ADDRESS is defined in *IRCommandMapping.h - IRDispatcher.IRReceivedData.isAvailable = true; - if(!IRDispatcher.doNotUseDispatcher) { - /* - * Only short (non blocking) commands are executed directly in ISR (Interrupt Service Routine) context, - * others are stored for main loop which calls checkAndRunSuspendedBlockingCommands() - */ - IRDispatcher.checkAndCallCommand(false); - } - - } else { - CD_INFO_PRINT(F("Wrong address. Expected 0x")); - CD_INFO_PRINTLN(IR_ADDRESS, HEX); - } -} - -#elif defined(USE_IRMP_LIBRARY) -# if !defined(IRMP_USE_COMPLETE_CALLBACK) -# error IRMP_USE_COMPLETE_CALLBACK must be activated for IRMP library -# endif - -void IRCommandDispatcher::init() { - irmp_init(); -} - -/* - * This is the callback function, which is called if a complete command was received - */ -#if defined(ESP8266) || defined(ESP32) -IRAM_ATTR -#endif -void handleReceivedIRData() { - IRMP_DATA tTeporaryData; - irmp_get_data(&tTeporaryData); - IRDispatcher.IRReceivedData.address = tTeporaryData.address; - IRDispatcher.IRReceivedData.command = tTeporaryData.command; - IRDispatcher.IRReceivedData.isRepeat = tTeporaryData.flags & IRMP_FLAG_REPETITION; - IRDispatcher.IRReceivedData.MillisOfLastCode = millis(); - - CD_INFO_PRINT(F("A=0x")); - CD_INFO_PRINT(IRDispatcher.IRReceivedData.address, HEX); - CD_INFO_PRINT(F(" C=0x")); - CD_INFO_PRINT(IRDispatcher.IRReceivedData.command, HEX); - if (IRDispatcher.IRReceivedData.isRepeat) { - CD_INFO_PRINT(F("R")); - } - CD_INFO_PRINTLN(); - - // To enable delay() for commands -# if !defined(ARDUINO_ARCH_MBED) - interrupts(); // be careful with always executable commands which lasts longer than the IR repeat duration. -# endif - - if (IRDispatcher.IRReceivedData.address == IR_ADDRESS) { - IRDispatcher.checkAndCallCommand(true); - } else { - CD_INFO_PRINT(F("Wrong address. Expected 0x")); - CD_INFO_PRINTLN(IR_ADDRESS, HEX); - } -} -#endif // elif defined(USE_IRMP_LIBRARY) - -/* - * The main dispatcher function - * Sets flags justCalledRegularIRCommand, executingBlockingCommand - * @param aCallBlockingCommandImmediately Run blocking command directly, otherwise set request to stop to true - * and store command for main loop to execute by checkAndRunSuspendedBlockingCommands(). - * Should be false if called by ISR. - */ -void IRCommandDispatcher::checkAndCallCommand(bool aCallBlockingCommandImmediately) { - if (IRReceivedData.command == COMMAND_EMPTY) { - return; - } - - /* - * Search for command in Array of IRToCommandMappingStruct - */ - for (uint_fast8_t i = 0; i < sizeof(IRMapping) / sizeof(struct IRToCommandMappingStruct); ++i) { - if (IRReceivedData.command == IRMapping[i].IRCode) { - /* - * Command found - */ -#if defined(LOCAL_INFO) - const __FlashStringHelper *tCommandName = reinterpret_cast<const __FlashStringHelper*>(IRMapping[i].CommandString); -#endif - /* - * Check for repeat and if repeat is allowed for the current command - */ - if (IRReceivedData.isRepeat && !(IRMapping[i].Flags & IR_COMMAND_FLAG_REPEATABLE)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Repeats of command \"")); - Serial.print(tCommandName); - Serial.println("\" not accepted"); -#endif - return; - } - - /* - * Do not accept recursive call of the same command - */ - if (currentBlockingCommandCalled == IRReceivedData.command) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Recursive command \"")); - Serial.print(tCommandName); - Serial.println("\" not accepted"); -#endif - return; - } - - /* - * lets start a new turn - */ - requestToStopReceived = false; - - bool tIsNonBlockingCommand = (IRMapping[i].Flags & IR_COMMAND_FLAG_NON_BLOCKING); - if (tIsNonBlockingCommand) { - // short command here, just call - CD_INFO_PRINT(F("Run non blocking command: ")); - CD_INFO_PRINTLN (tCommandName); - IRMapping[i].CommandToCall(); - } else { - if (aCallBlockingCommandImmediately && currentBlockingCommandCalled == COMMAND_EMPTY) { - /* - * here we are called from main loop to execute a command - */ - justCalledBlockingCommand = true; - currentBlockingCommandCalled = IRReceivedData.command; // set lock for recursive calls - lastBlockingCommandCalled = IRReceivedData.command; // set history, can be evaluated by main loop - /* - * This call is blocking!!! - */ - CD_INFO_PRINT(F("Run blocking command: ")); - CD_INFO_PRINTLN (tCommandName); - - IRMapping[i].CommandToCall(); -#if defined(TRACE) - Serial.println(F("End of blocking command")); -#endif - currentBlockingCommandCalled = COMMAND_EMPTY; - } else { - /* - * Do not run command directly, but set request to stop to true and store command for main loop to execute - */ - BlockingCommandToRunNext = IRReceivedData.command; - requestToStopReceived = true; // to stop running command - CD_INFO_PRINT(F("Requested stop and stored blocking command ")); - CD_INFO_PRINT (tCommandName); - CD_INFO_PRINTLN(F(" as next command to run.")); - } - } - break; // command found - } // if (IRReceivedData.command == IRMapping[i].IRCode) - } // for loop - return; -} - -/* - * Intended to be called from main loop - * @return true, if command was called - */ -bool IRCommandDispatcher::checkAndRunSuspendedBlockingCommands() { - /* - * Take last rejected command and call associated function - */ - if (BlockingCommandToRunNext != COMMAND_EMPTY) { - - CD_INFO_PRINT(F("Take stored command = 0x")); - CD_INFO_PRINTLN(BlockingCommandToRunNext, HEX); - - IRReceivedData.command = BlockingCommandToRunNext; - BlockingCommandToRunNext = COMMAND_EMPTY; - IRReceivedData.isRepeat = false; - checkAndCallCommand(true); - return true; - } - return false; -} - -#if defined(IR_COMMAND_HAS_MORE_THAN_8_BIT) -void IRCommandDispatcher::setNextBlockingCommand(uint16_t aBlockingCommandToRunNext) -#else -void IRCommandDispatcher::setNextBlockingCommand(uint8_t aBlockingCommandToRunNext) -#endif - { - CD_INFO_PRINT(F("Set next command to 0x")); - CD_INFO_PRINTLN(aBlockingCommandToRunNext, HEX); - BlockingCommandToRunNext = aBlockingCommandToRunNext; - requestToStopReceived = true; -} - -/* - * Special delay function for the IRCommandDispatcher. Returns prematurely if requestToStopReceived is set. - * To be used in blocking functions as delay - * @return true - as soon as stop received - */ -bool IRCommandDispatcher::delayAndCheckForStop(uint16_t aDelayMillis) { - uint32_t tStartMillis = millis(); - do { - if (requestToStopReceived) { - return true; - } - } while (millis() - tStartMillis < aDelayMillis); - return false; -} - -void IRCommandDispatcher::printIRCommandString(Print *aSerial) { - aSerial->print(F("IRCommand=")); - for (uint_fast8_t i = 0; i < sizeof(IRMapping) / sizeof(struct IRToCommandMappingStruct); ++i) { - if (IRReceivedData.command == IRMapping[i].IRCode) { - aSerial->println(reinterpret_cast<const __FlashStringHelper*>(IRMapping[i].CommandString)); - return; - } - } - aSerial->println(reinterpret_cast<const __FlashStringHelper*>(unknown)); -} - -void IRCommandDispatcher::setRequestToStopReceived(bool aRequestToStopReceived) { - requestToStopReceived = aRequestToStopReceived; -} - -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#if defined(LOCAL_INFO) -#undef LOCAL_INFO -#endif -#endif // _IR_COMMAND_DISPATCHER_HPP diff --git a/IRremote/examples/IRDispatcherDemo/IRDispatcherDemo.ino b/IRremote/examples/IRDispatcherDemo/IRDispatcherDemo.ino deleted file mode 100644 index 8a66d4fc8cc815b3424b5816360e870b63bfc3ee..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRDispatcherDemo/IRDispatcherDemo.ino +++ /dev/null @@ -1,306 +0,0 @@ -/* - * IRDispatcherDemo.cpp - * - * Receives NEC IR commands and maps them to different actions by means of a mapping array. - * - * Copyright (C) 2020-2021 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * IRMP is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -#include <Arduino.h> - -/* - * Choose the library to be used for IR receiving - */ -#define USE_TINY_IR_RECEIVER // Recommended, but only for NEC protocol!!! If disabled and IRMP_INPUT_PIN is defined, the IRMP library is used for decoding -//#define TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT // Requires additional 112 bytes program memory + 4 bytes RAM - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -// Some kind of auto detect library if USE_TINY_IR_RECEIVER is deactivated -#if !defined(USE_TINY_IR_RECEIVER) -# if defined(IR_RECEIVE_PIN) -#define USE_TINY_IR_RECEIVER -# elif !defined(USE_IRMP_LIBRARY) && defined(IRMP_INPUT_PIN) -#define USE_IRMP_LIBRARY -# else -#error No IR library selected -# endif -#endif - -//#define NO_LED_FEEDBACK_CODE // You can set it here, before the include of IRCommandDispatcher below - -#if defined(USE_TINY_IR_RECEIVER) -//#define NO_LED_FEEDBACK_CODE // Activate this if you want to suppress LED feedback or if you do not have a LED. This saves 14 bytes code and 2 clock cycles per interrupt. - -/* - * Set sensible receive pin for different CPU's - */ -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -# if defined(ARDUINO_AVR_DIGISPARKPRO) -#define IR_INPUT_PIN 9 // PA3 - on Digispark board labeled as pin 9 -# else -#define IR_INPUT_PIN 0 // PCINT0 -# endif -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) -#define IR_INPUT_PIN 10 -# elif (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)) -#define IR_INPUT_PIN 21 // INT0 -# elif defined(ESP8266) -#define IR_INPUT_PIN 14 // D5 -# elif defined(ESP32) -#define IR_INPUT_PIN 15 -# elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) -#define IR_INPUT_PIN 3 // GPIO15 Use pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -# elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_INPUT_PIN 15 // to be compatible with the Arduino Nano RP2040 Connect (pin3) -# else -#define IR_INPUT_PIN 2 // INT0 -# endif - -#elif defined(USE_IRMP_LIBRARY) -/* - * IRMP version - */ -#define IR_INPUT_PIN 2 -#define IRMP_USE_COMPLETE_CALLBACK 1 // Enable callback functionality. It is required if IRMP library is used. -#if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN) -#define FEEDBACK_LED_PIN ALTERNATIVE_IR_FEEDBACK_LED_PIN -#endif - -//#define IRMP_ENABLE_PIN_CHANGE_INTERRUPT // Enable interrupt functionality (not for all protocols) - requires around 376 additional bytes of program memory - -#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - requires some program memory. Must before #include <irmp*> - -#define IRMP_SUPPORT_NEC_PROTOCOL 1 // this enables only one protocol -//#define IRMP_SUPPORT_KASEIKYO_PROTOCOL 1 - -# if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN) -#define IRMP_FEEDBACK_LED_PIN ALTERNATIVE_IR_FEEDBACK_LED_PIN -# endif -/* - * After setting the definitions we can include the code and compile it. - */ -#include <irmp.hpp> -void handleReceivedIRData(); -void irmp_tone(uint8_t _pin, unsigned int frequency, unsigned long duration); -#endif // #if defined(USE_IRMP_LIBRARY) - -bool doBlink = false; -uint16_t sBlinkDelay = 200; - -void doPrintMenu(); -void doLedOn(); -void doLedOff(); -void doIncreaseBlinkFrequency(); -void doDecreaseBlinkFrequency(); -void doStop(); -void doResetBlinkFrequency(); -void doLedBlinkStart(); -void doLedBlink20times(); -void doTone1800(); -void doTone2200(); - -/* - * Set definitions and include IRCommandDispatcher library after the declaration of all commands to map - */ -#define INFO // to see some informative output -#include "IRCommandDispatcher.h" // Only for required declarations, the library itself is included below after the definitions of the commands -#include "DemoIRCommandMapping.h" // must be included before IRCommandDispatcher.hpp to define IR_ADDRESS and IRMapping and string "unknown". -#include "IRCommandDispatcher.hpp" - -/* - * Helper macro for getting a macro definition as string - */ -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) - -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif -#if defined(ESP8266) - Serial.println(); // to separate it from the internal boot output -#endif - - // Just to know which program is running on my Arduino -#if defined(USE_TINY_IR_RECEIVER) - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing TinyIRReceiver")); -#elif defined(USE_IRREMOTE_LIBRARY) - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing IRremote library version " VERSION_IRREMOTE)); -#elif defined(USE_IRMP_LIBRARY) - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing IRMP library version " VERSION_IRMP)); -#endif - -#if !defined(ESP8266) && !defined(NRF5) - // play feedback tone before setup, since it kills the IR timer settings - tone(TONE_PIN, 1000, 50); - delay(50); -#endif - - IRDispatcher.init(); // This just calls irmp_init() -#if defined(USE_TINY_IR_RECEIVER) - Serial.println(F("Ready to receive NEC IR signals at pin " STR(IR_INPUT_PIN))); -#else - irmp_register_complete_callback_function(&handleReceivedIRData); // fixed function in IRCommandDispatcher.hpp - - Serial.print(F("Ready to receive IR signals of protocols: ")); - irmp_print_active_protocols(&Serial); - Serial.println(F("at pin " STR(IRMP_INPUT_PIN))); - -# if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN) - irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at ALTERNATIVE_IR_FEEDBACK_LED_PIN - Serial.println(F("IR feedback pin is " STR(ALTERNATIVE_IR_FEEDBACK_LED_PIN))); -# endif -#endif - - Serial.print(F("Listening to commands of IR remote of type ")); - Serial.println(IR_REMOTE_NAME); - doPrintMenu(); -} - -void loop() { - - IRDispatcher.checkAndRunSuspendedBlockingCommands(); - - if (doBlink) { - digitalWrite(LED_BUILTIN, HIGH); - DELAY_AND_RETURN_IF_STOP(sBlinkDelay); - digitalWrite(LED_BUILTIN, LOW); - DELAY_AND_RETURN_IF_STOP(sBlinkDelay); - } - - if (millis() - IRDispatcher.IRReceivedData.MillisOfLastCode > 120000) - { - //Short beep as remainder, if we did not receive any command in the last 2 minutes - IRDispatcher.IRReceivedData.MillisOfLastCode += 120000; - doTone1800(); - } - -// delay(10); -} - -void doPrintMenu(){ - Serial.println(); - Serial.println(F("Press 1 for tone 1800 Hz")); - Serial.println(F("Press 2 for tone 2200 Hz")); - Serial.println(F("Press 3 for this Menu")); - Serial.println(F("Press 0 for LED blink 20 times")); - Serial.println(F("Press UP for LED on")); - Serial.println(F("Press DOWN for LED off")); - Serial.println(F("Press OK for LED blink start")); - Serial.println(F("Press RIGHT for LED increase blink frequency")); - Serial.println(F("Press LEFT for LED decrease blink frequency")); - Serial.println(F("Press STAR for reset blink frequency")); - Serial.println(F("Press HASH for stop")); - Serial.println(); -} -/* - * Here the actions that are matched to IR keys - */ -void doLedOn() { - digitalWrite(LED_BUILTIN, HIGH); - doBlink = false; -} -void doLedOff() { - digitalWrite(LED_BUILTIN, LOW); - doBlink = false; -} -void doIncreaseBlinkFrequency() { - doBlink = true; - if (sBlinkDelay > 5) { - sBlinkDelay -= sBlinkDelay / 4; - } -} -void doDecreaseBlinkFrequency() { - doBlink = true; - sBlinkDelay += sBlinkDelay / 4; -} -void doStop() { - doBlink = false; -} -void doResetBlinkFrequency() { - sBlinkDelay = 200; - digitalWrite(LED_BUILTIN, LOW); -} -void doLedBlinkStart() { - doBlink = true; -} -/* - * This is a blocking function and checks periodically for stop - */ -void doLedBlink20times() { - for (int i = 0; i < 20; ++i) { - digitalWrite(LED_BUILTIN, HIGH); - DELAY_AND_RETURN_IF_STOP(200); - digitalWrite(LED_BUILTIN, LOW); - DELAY_AND_RETURN_IF_STOP(200); - } -} - - -void doTone1800() { -#if defined(USE_IRMP_LIBRARY) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT) - irmp_tone(TONE_PIN, 1800, 200); -#else -# if !defined(ESP8266) && !defined(NRF5) // tone() stops timer 1 for ESP8266 - tone(TONE_PIN, 1800, 200); -# endif -#endif -} - -void doTone2200() { -#if defined(USE_IRMP_LIBRARY) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT) - // use IRMP compatible function for tone() - irmp_tone(TONE_PIN, 2200, 50); -#else -# if !defined(ESP8266) && !defined(NRF5) // tone() stops timer 1 for ESP8266 - tone(TONE_PIN, 2200, 50); -# endif -#endif -} - -#if defined(USE_IRMP_LIBRARY) -/* - * Convenience IRMP compatible wrapper function for Arduino tone() if IRMP_ENABLE_PIN_CHANGE_INTERRUPT is NOT activated - * It currently disables the receiving of repeats - */ -void irmp_tone(uint8_t _pin, unsigned int frequency, unsigned long duration) { -# if defined(__AVR__) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT) - storeIRTimer(); - tone(_pin, frequency, 0); - if (duration == 0) { - duration = 100; - } - delay(duration); - noTone(_pin); - restoreIRTimer(); -#elif defined(ESP8266) - // tone() stops timer 1 - (void) _pin; - (void) frequency; - (void) duration; -#else - tone(_pin, frequency, duration); -#endif -} -#endif // #if defined(USE_IRMP_LIBRARY) diff --git a/IRremote/examples/IRDispatcherDemo/PinDefinitionsAndMore.h b/IRremote/examples/IRDispatcherDemo/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRDispatcherDemo/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/IRrecord/IRrecord.ino b/IRremote/examples/IRrecord/IRrecord.ino deleted file mode 100644 index 7fc5cfd39715aac170348a7b6fa0a2feaa58bf05..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRrecord/IRrecord.ino +++ /dev/null @@ -1,183 +0,0 @@ -/* - * IRrecord: record and play back IR signals as a minimal - * An IR detector/demodulator must be connected to the input RECV_PIN. - * An IR LED must be connected to the output PWM pin 3. - * A button must be connected to the input BUTTON_PIN; this is the - * send button. - * A visible LED can be connected to STATUS_PIN to provide status. - * - * The logic is: - * If the button is pressed, send the IR code. - * If an IR code is received, record it. - * - * Version 0.11 September, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - */ - -#include <IRremote.h> - -int RECV_PIN = 11; -int BUTTON_PIN = 12; -int STATUS_PIN = 13; - -IRrecv irrecv(RECV_PIN); -IRsend irsend; - -decode_results results; - -void setup() -{ - Serial.begin(9600); - irrecv.enableIRIn(); // Start the receiver - pinMode(BUTTON_PIN, INPUT); - pinMode(STATUS_PIN, OUTPUT); -} - -// Storage for the recorded code -int codeType = -1; // The type of code -unsigned long codeValue; // The code value if not raw -unsigned int rawCodes[RAWBUF]; // The durations if raw -int codeLen; // The length of the code -int toggle = 0; // The RC5/6 toggle state - -// Stores the code for later playback -// Most of this code is just logging -void storeCode(decode_results *results) { - codeType = results->decode_type; - int count = results->rawlen; - if (codeType == UNKNOWN) { - Serial.println("Received unknown code, saving as raw"); - codeLen = results->rawlen - 1; - // To store raw codes: - // Drop first value (gap) - // Convert from ticks to microseconds - // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion - for (int i = 1; i <= codeLen; i++) { - if (i % 2) { - // Mark - rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS; - Serial.print(" m"); - } - else { - // Space - rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS; - Serial.print(" s"); - } - Serial.print(rawCodes[i - 1], DEC); - } - Serial.println(""); - } - else { - if (codeType == NEC) { - Serial.print("Received NEC: "); - if (results->value == REPEAT) { - // Don't record a NEC repeat value as that's useless. - Serial.println("repeat; ignoring."); - return; - } - } - else if (codeType == SONY) { - Serial.print("Received SONY: "); - } - else if (codeType == PANASONIC) { - Serial.print("Received PANASONIC: "); - } - else if (codeType == JVC) { - Serial.print("Received JVC: "); - } - else if (codeType == RC5) { - Serial.print("Received RC5: "); - } - else if (codeType == RC6) { - Serial.print("Received RC6: "); - } - else { - Serial.print("Unexpected codeType "); - Serial.print(codeType, DEC); - Serial.println(""); - } - Serial.println(results->value, HEX); - codeValue = results->value; - codeLen = results->bits; - } -} - -void sendCode(int repeat) { - if (codeType == NEC) { - if (repeat) { - irsend.sendNEC(REPEAT, codeLen); - Serial.println("Sent NEC repeat"); - } - else { - irsend.sendNEC(codeValue, codeLen); - Serial.print("Sent NEC "); - Serial.println(codeValue, HEX); - } - } - else if (codeType == SONY) { - irsend.sendSony(codeValue, codeLen); - Serial.print("Sent Sony "); - Serial.println(codeValue, HEX); - } - else if (codeType == PANASONIC) { - irsend.sendPanasonic(codeValue, codeLen); - Serial.print("Sent Panasonic"); - Serial.println(codeValue, HEX); - } - else if (codeType == JVC) { - irsend.sendJVC(codeValue, codeLen, false); - Serial.print("Sent JVC"); - Serial.println(codeValue, HEX); - } - else if (codeType == RC5 || codeType == RC6) { - if (!repeat) { - // Flip the toggle bit for a new button press - toggle = 1 - toggle; - } - // Put the toggle bit into the code to send - codeValue = codeValue & ~(1 << (codeLen - 1)); - codeValue = codeValue | (toggle << (codeLen - 1)); - if (codeType == RC5) { - Serial.print("Sent RC5 "); - Serial.println(codeValue, HEX); - irsend.sendRC5(codeValue, codeLen); - } - else { - irsend.sendRC6(codeValue, codeLen); - Serial.print("Sent RC6 "); - Serial.println(codeValue, HEX); - } - } - else if (codeType == UNKNOWN /* i.e. raw */) { - // Assume 38 KHz - irsend.sendRaw(rawCodes, codeLen, 38); - Serial.println("Sent raw"); - } -} - -int lastButtonState; - -void loop() { - // If button pressed, send the code. - int buttonState = digitalRead(BUTTON_PIN); - if (lastButtonState == HIGH && buttonState == LOW) { - Serial.println("Released"); - irrecv.enableIRIn(); // Re-enable receiver - } - - if (buttonState) { - Serial.println("Pressed, sending"); - digitalWrite(STATUS_PIN, HIGH); - sendCode(lastButtonState == buttonState); - digitalWrite(STATUS_PIN, LOW); - delay(50); // Wait a bit between retransmissions - } - else if (irrecv.decode(&results)) { - digitalWrite(STATUS_PIN, HIGH); - storeCode(&results); - irrecv.resume(); // resume receiver - digitalWrite(STATUS_PIN, LOW); - } - lastButtonState = buttonState; -} diff --git a/IRremote/examples/IRrecvDemo/IRrecvDemo.ino b/IRremote/examples/IRrecvDemo/IRrecvDemo.ino deleted file mode 100644 index 3e2d280eb6888b4644a6cbe785bb5d6518d17f33..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRrecvDemo/IRrecvDemo.ino +++ /dev/null @@ -1,33 +0,0 @@ -/* - * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv - * An IR detector/demodulator must be connected to the input RECV_PIN. - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - */ - -#include <IRremote.h> - -int RECV_PIN = 11; - -IRrecv irrecv(RECV_PIN); - -decode_results results; - -void setup() -{ - Serial.begin(9600); - // In case the interrupt driver crashes on setup, give a clue - // to the user what's going on. - Serial.println("Enabling IRin"); - irrecv.enableIRIn(); // Start the receiver - Serial.println("Enabled IRin"); -} - -void loop() { - if (irrecv.decode(&results)) { - Serial.println(results.value, HEX); - irrecv.resume(); // Receive the next value - } - delay(100); -} diff --git a/IRremote/examples/IRrecvDump/IRrecvDump.ino b/IRremote/examples/IRrecvDump/IRrecvDump.ino deleted file mode 100644 index fa25cd8eaae31825e104bbc9bcbbca4a41ab6079..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRrecvDump/IRrecvDump.ino +++ /dev/null @@ -1,95 +0,0 @@ -/* - * IRremote: IRrecvDump - dump details of IR codes with IRrecv - * An IR detector/demodulator must be connected to the input RECV_PIN. - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) - * LG added by Darryl Smith (based on the JVC protocol) - */ - -#include <IRremote.h> - -/* -* Default is Arduino pin D11. -* You can change this to another available Arduino Pin. -* Your IR receiver should be connected to the pin defined here -*/ -int RECV_PIN = 11; - -IRrecv irrecv(RECV_PIN); - -decode_results results; - -void setup() -{ - Serial.begin(9600); - irrecv.enableIRIn(); // Start the receiver -} - - -void dump(decode_results *results) { - // Dumps out the decode_results structure. - // Call this after IRrecv::decode() - int count = results->rawlen; - if (results->decode_type == UNKNOWN) { - Serial.print("Unknown encoding: "); - } - else if (results->decode_type == NEC) { - Serial.print("Decoded NEC: "); - - } - else if (results->decode_type == SONY) { - Serial.print("Decoded SONY: "); - } - else if (results->decode_type == RC5) { - Serial.print("Decoded RC5: "); - } - else if (results->decode_type == RC6) { - Serial.print("Decoded RC6: "); - } - else if (results->decode_type == PANASONIC) { - Serial.print("Decoded PANASONIC - Address: "); - Serial.print(results->address, HEX); - Serial.print(" Value: "); - } - else if (results->decode_type == LG) { - Serial.print("Decoded LG: "); - } - else if (results->decode_type == JVC) { - Serial.print("Decoded JVC: "); - } - else if (results->decode_type == AIWA_RC_T501) { - Serial.print("Decoded AIWA RC T501: "); - } - else if (results->decode_type == WHYNTER) { - Serial.print("Decoded Whynter: "); - } - Serial.print(results->value, HEX); - Serial.print(" ("); - Serial.print(results->bits, DEC); - Serial.println(" bits)"); - Serial.print("Raw ("); - Serial.print(count, DEC); - Serial.print("): "); - - for (int i = 1; i < count; i++) { - if (i & 1) { - Serial.print(results->rawbuf[i]*USECPERTICK, DEC); - } - else { - Serial.write('-'); - Serial.print((unsigned long) results->rawbuf[i]*USECPERTICK, DEC); - } - Serial.print(" "); - } - Serial.println(); -} - -void loop() { - if (irrecv.decode(&results)) { - Serial.println(results.value, HEX); - dump(&results); - irrecv.resume(); // Receive the next value - } -} diff --git a/IRremote/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/IRremote/examples/IRrecvDumpV2/IRrecvDumpV2.ino deleted file mode 100644 index 7256127353c7d29ec3009eace13983dba8efce96..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ /dev/null @@ -1,177 +0,0 @@ -//------------------------------------------------------------------------------ -// Include the IRremote library header -// -#include <IRremote.h> - -//------------------------------------------------------------------------------ -// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) -// -int recvPin = 11; -IRrecv irrecv(recvPin); - -//+============================================================================= -// Configure the Arduino -// -void setup ( ) -{ - Serial.begin(9600); // Status message will be sent to PC at 9600 baud - irrecv.enableIRIn(); // Start the receiver -} - -//+============================================================================= -// Display IR code -// -void ircode (decode_results *results) -{ - // Panasonic has an Address - if (results->decode_type == PANASONIC) { - Serial.print(results->address, HEX); - Serial.print(":"); - } - - // Print Code - Serial.print(results->value, HEX); -} - -//+============================================================================= -// Display encoding type -// -void encoding (decode_results *results) -{ - switch (results->decode_type) { - default: - case UNKNOWN: Serial.print("UNKNOWN"); break ; - case NEC: Serial.print("NEC"); break ; - case SONY: Serial.print("SONY"); break ; - case RC5: Serial.print("RC5"); break ; - case RC6: Serial.print("RC6"); break ; - case DISH: Serial.print("DISH"); break ; - case SHARP: Serial.print("SHARP"); break ; - case JVC: Serial.print("JVC"); break ; - case SANYO: Serial.print("SANYO"); break ; - case MITSUBISHI: Serial.print("MITSUBISHI"); break ; - case SAMSUNG: Serial.print("SAMSUNG"); break ; - case LG: Serial.print("LG"); break ; - case WHYNTER: Serial.print("WHYNTER"); break ; - case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ; - case PANASONIC: Serial.print("PANASONIC"); break ; - case DENON: Serial.print("Denon"); break ; - } -} - -//+============================================================================= -// Dump out the decode_results structure. -// -void dumpInfo (decode_results *results) -{ - // Check if the buffer overflowed - if (results->overflow) { - Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF"); - return; - } - - // Show Encoding standard - Serial.print("Encoding : "); - encoding(results); - Serial.println(""); - - // Show Code & length - Serial.print("Code : "); - ircode(results); - Serial.print(" ("); - Serial.print(results->bits, DEC); - Serial.println(" bits)"); -} - -//+============================================================================= -// Dump out the decode_results structure. -// -void dumpRaw (decode_results *results) -{ - // Print Raw data - Serial.print("Timing["); - Serial.print(results->rawlen-1, DEC); - Serial.println("]: "); - - for (int i = 1; i < results->rawlen; i++) { - unsigned long x = results->rawbuf[i] * USECPERTICK; - if (!(i & 1)) { // even - Serial.print("-"); - if (x < 1000) Serial.print(" ") ; - if (x < 100) Serial.print(" ") ; - Serial.print(x, DEC); - } else { // odd - Serial.print(" "); - Serial.print("+"); - if (x < 1000) Serial.print(" ") ; - if (x < 100) Serial.print(" ") ; - Serial.print(x, DEC); - if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one - } - if (!(i % 8)) Serial.println(""); - } - Serial.println(""); // Newline -} - -//+============================================================================= -// Dump out the decode_results structure. -// -void dumpCode (decode_results *results) -{ - // Start declaration - Serial.print("unsigned int "); // variable type - Serial.print("rawData["); // array name - Serial.print(results->rawlen - 1, DEC); // array size - Serial.print("] = {"); // Start declaration - - // Dump data - for (int i = 1; i < results->rawlen; i++) { - Serial.print(results->rawbuf[i] * USECPERTICK, DEC); - if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last one - if (!(i & 1)) Serial.print(" "); - } - - // End declaration - Serial.print("};"); // - - // Comment - Serial.print(" // "); - encoding(results); - Serial.print(" "); - ircode(results); - - // Newline - Serial.println(""); - - // Now dump "known" codes - if (results->decode_type != UNKNOWN) { - - // Some protocols have an address - if (results->decode_type == PANASONIC) { - Serial.print("unsigned int addr = 0x"); - Serial.print(results->address, HEX); - Serial.println(";"); - } - - // All protocols have data - Serial.print("unsigned int data = 0x"); - Serial.print(results->value, HEX); - Serial.println(";"); - } -} - -//+============================================================================= -// The repeating section of the code -// -void loop ( ) -{ - decode_results results; // Somewhere to store the results - - if (irrecv.decode(&results)) { // Grab an IR code - dumpInfo(&results); // Output the results - dumpRaw(&results); // Output the results in RAW format - dumpCode(&results); // Output the results as source code - Serial.println(""); // Blank line between entries - irrecv.resume(); // Prepare for the next value - } -} diff --git a/IRremote/examples/IRrelay/IRrelay.ino b/IRremote/examples/IRrelay/IRrelay.ino deleted file mode 100644 index 046fb5fa6bd668759f54b7e1f610594d5092c3b6..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRrelay/IRrelay.ino +++ /dev/null @@ -1,85 +0,0 @@ -/* - * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv - * An IR detector/demodulator must be connected to the input RECV_PIN. - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - */ - -#include <IRremote.h> - -int RECV_PIN = 11; -int RELAY_PIN = 4; - -IRrecv irrecv(RECV_PIN); -decode_results results; - -// Dumps out the decode_results structure. -// Call this after IRrecv::decode() -// void * to work around compiler issue -//void dump(void *v) { -// decode_results *results = (decode_results *)v -void dump(decode_results *results) { - int count = results->rawlen; - if (results->decode_type == UNKNOWN) { - Serial.println("Could not decode message"); - } - else { - if (results->decode_type == NEC) { - Serial.print("Decoded NEC: "); - } - else if (results->decode_type == SONY) { - Serial.print("Decoded SONY: "); - } - else if (results->decode_type == RC5) { - Serial.print("Decoded RC5: "); - } - else if (results->decode_type == RC6) { - Serial.print("Decoded RC6: "); - } - Serial.print(results->value, HEX); - Serial.print(" ("); - Serial.print(results->bits, DEC); - Serial.println(" bits)"); - } - Serial.print("Raw ("); - Serial.print(count, DEC); - Serial.print("): "); - - for (int i = 0; i < count; i++) { - if ((i % 2) == 1) { - Serial.print(results->rawbuf[i]*USECPERTICK, DEC); - } - else { - Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); - } - Serial.print(" "); - } - Serial.println(""); -} - -void setup() -{ - pinMode(RELAY_PIN, OUTPUT); - pinMode(13, OUTPUT); - Serial.begin(9600); - irrecv.enableIRIn(); // Start the receiver -} - -int on = 0; -unsigned long last = millis(); - -void loop() { - if (irrecv.decode(&results)) { - // If it's been at least 1/4 second since the last - // IR received, toggle the relay - if (millis() - last > 250) { - on = !on; - digitalWrite(RELAY_PIN, on ? HIGH : LOW); - digitalWrite(13, on ? HIGH : LOW); - dump(&results); - } - last = millis(); - irrecv.resume(); // Receive the next value - } -} diff --git a/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionClass.cpp b/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionClass.cpp deleted file mode 100644 index 328db5b8dc85408ae0b34bc8a8ce25d09e5bbd25..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionClass.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * IRremoteExtensionClass.cpp - * - * Example for a class which itself uses the IRrecv class from IRremote - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2021 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#include "IRremoteExtensionClass.h" - -IRExtensionClass::IRExtensionClass(IRrecv *aIrReceiver) { - MyIrReceiver = aIrReceiver; -} -void IRExtensionClass::resume() { - Serial.println(F("Call resume()")); - MyIrReceiver->resume(); -} diff --git a/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionClass.h b/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionClass.h deleted file mode 100644 index 5c50fd5e4aa8d0abd39cdfcf073c88797fcfebc3..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionClass.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * IRremoteExtensionClass.h - * - * Example for a class which itself uses the IRrecv class from IRremote - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2021 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#define USE_IRREMOTE_HPP_AS_PLAIN_INCLUDE -#include <IRremote.hpp> - -class IRExtensionClass -{ -public: - IRrecv * MyIrReceiver; - IRExtensionClass(IRrecv * aIrReceiver); - void resume(); -}; - diff --git a/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionTest.ino b/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionTest.ino deleted file mode 100644 index 65b42c03c7774a0b1f0543e3292bb184bd974f18..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRremoteExtensionTest/IRremoteExtensionTest.ino +++ /dev/null @@ -1,79 +0,0 @@ -/* - * IRremoteExtensionTest.cpp - * Simple test using the IRremoteExtensionClass. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -#if !defined(RAW_BUFFER_LENGTH) -# if RAMEND <= 0x4FF || RAMSIZE < 0x4FF -#define RAW_BUFFER_LENGTH 180 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# elif RAMEND <= 0x8FF || RAMSIZE < 0x8FF -#define RAW_BUFFER_LENGTH 500 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# else -#define RAW_BUFFER_LENGTH 750 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# endif -#endif - -#include <IRremote.hpp> - -#include "IRremoteExtensionClass.h" - -/* - * Create the class, which itself uses the IRrecv class from IRremote - */ -IRExtensionClass IRExtension(&IrReceiver); - -void setup() { - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif -// Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); - -} - -void loop() { - if (IrReceiver.decode()) { - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); - IRExtension.resume(); // Use the extended function provided by IRExtension class - } - delay(100); -} diff --git a/IRremote/examples/IRremoteExtensionTest/PinDefinitionsAndMore.h b/IRremote/examples/IRremoteExtensionTest/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRremoteExtensionTest/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/IRremoteInfo/IRremoteInfo.ino b/IRremote/examples/IRremoteInfo/IRremoteInfo.ino deleted file mode 100644 index 22ae75fbbf8ab00b7266173c71bb896ba8d7cd9a..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRremoteInfo/IRremoteInfo.ino +++ /dev/null @@ -1,362 +0,0 @@ -/* - * IRremote: IRremoteInfo - prints relevant config info & settings for IRremote over serial - * Intended to help identify & troubleshoot the various settings of IRremote - * For example, sometimes users are unsure of which pin is used for Tx or the RAW_BUFFER_LENGTH value - * This example can be used to assist the user directly or with support. - * Intended to help identify & troubleshoot the various settings of IRremote - * Hopefully this utility will be a useful tool for support & troubleshooting for IRremote - * Check out the blog post describing the sketch via http://www.analysir.com/blog/2015/11/28/helper-utility-for-troubleshooting-irremote/ - * Version 1.0 November 2015 - * Original Author: AnalysIR - IR software & modules for Makers & Pros, visit http://www.AnalysIR.com - */ -#include <Arduino.h> - -//#define EXCLUDE_EXOTIC_PROTOCOLS // saves around 240 bytes program memory if IrSender.write is used -//#define SEND_PWM_BY_TIMER -//#define USE_NO_SEND_PWM -//#define NO_LED_FEEDBACK_CODE // saves 566 bytes program memory - -#include <IRremote.hpp> - -// Function declarations for non Arduino IDE's -void dumpHeader(); -void dumpRAW_BUFFER_LENGTH(); -void dumpTIMER(); -void dumpTimerPin(); -void dumpClock(); -void dumpPlatform(); -void dumpPulseParams(); -void dumpSignalParams(); -void dumpArduinoIDE(); -void dumpDebugMode(); -void dumpProtocols(); -void dumpFooter(); - -void setup() { - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - //Runs only once per restart of the Arduino. - dumpHeader(); - dumpRAW_BUFFER_LENGTH(); - dumpTIMER(); - dumpTimerPin(); - dumpClock(); - dumpPlatform(); - dumpPulseParams(); - dumpSignalParams(); - dumpArduinoIDE(); - dumpDebugMode(); - dumpProtocols(); - dumpFooter(); -} - -void loop() { - //nothing to do! -} - -void dumpRAW_BUFFER_LENGTH() { - Serial.print(F("RAW_BUFFER_LENGTH: ")); - Serial.println(RAW_BUFFER_LENGTH); -} - -void dumpTIMER() { - bool flag = false; -#if defined(IR_USE_TIMER1) - Serial.print(F("Timer defined for use: ")); - Serial.println(F("Timer1")); - flag = true; -#endif -#if defined(IR_USE_TIMER2) - Serial.print(F("Timer defined for use: ")); - Serial.println(F("Timer2")); - flag = true; -#endif -#if defined(IR_USE_TIMER3) - Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer3")); flag = true; -#endif -#if defined(IR_USE_TIMER4) - Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer4")); flag = true; -#endif -#if defined(IR_USE_TIMER5) - Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer5")); flag = true; -#endif -#if defined(IR_USE_TIMER4_HS) - Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer4_HS")); flag = true; -#endif -#if defined(IR_USE_TIMER_CMT) - Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_CMT")); flag = true; -#endif -#if defined(IR_USE_TIMER_TPM1) - Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_TPM1")); flag = true; -#endif -#if defined(IR_USE_TIMER_TINY0) - Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_TINY0")); flag = true; -#endif - - if (!flag) { - Serial.print(F("Timer Error: ")); - Serial.println(F("not defined")); - } -} - -void dumpTimerPin() { - Serial.print(F("IR Send Pin: ")); -#if defined(IR_SEND_PIN) - Serial.println(IR_SEND_PIN); -#else - Serial.println(IrSender.sendPin); -#endif -} - -void dumpClock() { -#if defined(F_CPU) - Serial.print(F("MCU Clock: ")); - Serial.println(F_CPU); -#endif -} - -void dumpPlatform() { - Serial.print(F("MCU Platform: ")); - -#if defined(__AVR_ATmega8__) - Serial.println(F("Atmega8")); -#elif defined(__AVR_ATmega16__) - Serial.println(F("ATmega16")); -#elif defined(__AVR_ATmega32__) - Serial.println(F("ATmega32")); -#elif defined(__AVR_ATmega32U4__) - Serial.println(F("Arduino Leonardo / Yun / Teensy 1.0 / ATmega32U4")); -#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) - Serial.println(F("ATmega48")); -#elif defined(__AVR_ATmega64__) - Serial.println(F("ATmega64")); -#elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega88P__) - Serial.println(F("ATmega88")); -#elif defined(__AVR_ATmega162__) - Serial.println(F("ATmega162")); -#elif defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__) - Serial.println(F("ATmega164")); -#elif defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) || defined(__AVR_ATmega324PA__) - Serial.println(F("ATmega324")); - -#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) - Serial.println(F("ATmega644")); -#elif defined(__AVR_ATmega1280__) - Serial.println(F("Arduino Mega1280")); -#elif defined(__AVR_ATmega1281__) - Serial.println(F("ATmega1281")); -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) - Serial.println(F("ATmega1284")); -#elif defined(__AVR_ATmega2560__) - Serial.println(F("Arduino Mega2560")); -#elif defined(__AVR_ATmega2561__) - Serial.println(F("ATmega2561")); - -#elif defined(__AVR_ATmega8515__) - Serial.println(F("ATmega8515")); -#elif defined(__AVR_ATmega8535__) - Serial.println(F("ATmega8535")); - -#elif defined(__AVR_AT90USB162__) - Serial.println(F("Teensy 1.0 / AT90USB162")); - // Teensy 2.0 -#elif defined(__MK20DX128__) || defined(__MK20DX256__) - Serial.println(F("Teensy 3.0 / Teensy 3.1 / MK20DX128 / MK20DX256")); -#elif defined(__MKL26Z64__) - Serial.println(F("Teensy-LC / MKL26Z64")); -#elif defined(__AVR_AT90USB646__) - Serial.println(F("Teensy++ 1.0 / AT90USB646")); -#elif defined(__AVR_AT90USB1286__) - Serial.println(F("Teensy++ 2.0 / AT90USB1286")); - -#elif defined(__AVR_ATtiny84__) - Serial.println(F("ATtiny84")); -#elif defined(__AVR_ATtiny85__) - Serial.println(F("ATtiny85")); -#else - Serial.println(F("ATmega328(P) / (Duemilanove, Diecimila, LilyPad, Mini, Micro, Fio, Nano, etc)")); -#endif -} - -void dumpPulseParams() { - Serial.print(F("Mark Excess: ")); - Serial.print(MARK_EXCESS_MICROS); - ; - Serial.println(F(" uSecs")); - Serial.print(F("Microseconds per tick: ")); - Serial.print(MICROS_PER_TICK); - ; - Serial.println(F(" uSecs")); - Serial.print(F("Measurement tolerance: ")); - Serial.print(TOLERANCE_FOR_DECODERS_MARK_OR_SPACE_MATCHING); - Serial.println(F("%")); -} - -void dumpSignalParams() { - Serial.print(F("Minimum Gap between IR Signals: ")); - Serial.print(RECORD_GAP_MICROS); - Serial.println(F(" uSecs")); -} - -void dumpDebugMode() { - Serial.print(F("Debug Mode: ")); -#if DEBUG - Serial.println(F("ON")); -#else - Serial.println(F("OFF (Normal)")); -#endif - -} - -void dumpArduinoIDE() { - Serial.print(F("Arduino IDE version: ")); - Serial.print(ARDUINO / 10000); - Serial.write('.'); - Serial.print((ARDUINO % 10000) / 100); - Serial.write('.'); - Serial.println(ARDUINO % 100); -} - -void dumpProtocols() { - - Serial.println(); - Serial.print(F("IR PROTOCOLS ")); - Serial.print(F("SEND ")); - Serial.println(F("DECODE")); - Serial.print(F("============= ")); - Serial.print(F("======== ")); - Serial.println(F("========")); - Serial.print(F("RC5: ")); -#if defined(DECODE_RC5) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("RC6: ")); -#if defined(DECODE_RC6) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("NEC: ")); -#if defined(DECODE_NEC) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("SONY: ")); -#if defined(DECODE_SONY) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("PANASONIC: ")); -#if defined(DECODE_PANASONIC) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("JVC: ")); -#if defined(DECODE_JVC) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("SAMSUNG: ")); -#if defined(DECODE_SAMSUNG) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("LG: ")); -#if defined(DECODE_LG) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("DENON: ")); -#if defined(DECODE_DENON) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - -#if !defined(EXCLUDE_EXOTIC_PROTOCOLS) // saves around 2000 bytes program memory - - Serial.print(F("BANG_OLUFSEN: ")); -#if defined(DECODE_BEO) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("BOSEWAVE: ")); -#if defined(DECODE_BOSEWAVE) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("WHYNTER: ")); -#if defined(DECODE_WHYNTER) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif - - Serial.print(F("FAST: ")); -#if defined(DECODE_FAST) - Serial.println(F("Enabled")); -#else - Serial.println(F("Disabled")); -#endif -#endif -} - -void printDecodeEnabled(int flag) { - if (flag) { - Serial.println(F("Enabled")); - } else { - Serial.println(F("Disabled")); - } -} - -void dumpHeader() { - Serial.println(F("IRremoteInfo - by AnalysIR (http://www.AnalysIR.com/)")); - Serial.println( - F( - "- A helper sketch to assist in troubleshooting issues with the library by reviewing the settings within the IRremote library")); - Serial.println( - F( - "- Prints out the important settings within the library, which can be configured to suit the many supported platforms")); - Serial.println(F("- When seeking on-line support, please post or upload the output of this sketch, where appropriate")); - Serial.println(); - Serial.println(F("IRremote Library Settings")); - Serial.println(F("=========================")); -} - -void dumpFooter() { - Serial.println(); - Serial.println(F("Notes: ")); - Serial.println(F("- Most of the settings above can be configured in the following files included as part of the library")); - Serial.println(F("- IRremoteInt.h")); - Serial.println(F("- IRremote.h")); - Serial.println( - F("- You can save SRAM by disabling the Decode or Send features for any protocol (Near the top of IRremoteInt.h)")); - Serial.println( - F( - "- Some Timer conflicts, with other libraries, can be easily resolved by configuring a different Timer for your platform")); -} diff --git a/IRremote/examples/IRsendDemo/IRsendDemo.ino b/IRremote/examples/IRsendDemo/IRsendDemo.ino deleted file mode 100644 index 4f23af6cf3cfe90694d2884fc078568e3ea43ea9..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRsendDemo/IRsendDemo.ino +++ /dev/null @@ -1,24 +0,0 @@ -/* - * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend - * An IR LED must be connected to Arduino PWM pin 3. - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - */ - - -#include <IRremote.h> - -IRsend irsend; - -void setup() -{ -} - -void loop() { - for (int i = 0; i < 3; i++) { - irsend.sendSony(0xa90, 12); - delay(40); - } - delay(5000); //5 second delay between each signal burst -} diff --git a/IRremote/examples/IRsendRawDemo/IRsendRawDemo.ino b/IRremote/examples/IRsendRawDemo/IRsendRawDemo.ino deleted file mode 100644 index e83d6e6df68c44b2f0f03bf18edf34e9d2908351..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRsendRawDemo/IRsendRawDemo.ino +++ /dev/null @@ -1,37 +0,0 @@ -/* - * IRremote: IRsendRawDemo - demonstrates sending IR codes with sendRaw - * An IR LED must be connected to Arduino PWM pin 3. - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - * - * IRsendRawDemo - added by AnalysIR (via www.AnalysIR.com), 24 August 2015 - * - * This example shows how to send a RAW signal using the IRremote library. - * The example signal is actually a 32 bit NEC signal. - * Remote Control button: LGTV Power On/Off. - * Hex Value: 0x20DF10EF, 32 bits - * - * It is more efficient to use the sendNEC function to send NEC signals. - * Use of sendRaw here, serves only as an example of using the function. - * - */ - - -#include <IRremote.h> - -IRsend irsend; - -void setup() -{ - -} - -void loop() { - int khz = 38; // 38kHz carrier frequency for the NEC protocol - unsigned int irSignal[] = {9000, 4500, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 39416, 9000, 2210, 560}; //AnalysIR Batch Export (IRremote) - RAW - - irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array. - - delay(5000); //In this example, the signal will be repeated every 5 seconds, approximately. -} diff --git a/IRremote/examples/IRtest/IRtest.ino b/IRremote/examples/IRtest/IRtest.ino deleted file mode 100644 index 4845a4a4d00f871da17ee3859a21d0cebe4c3dfb..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRtest/IRtest.ino +++ /dev/null @@ -1,190 +0,0 @@ -/* - * IRremote: IRtest unittest - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - * - * Note: to run these tests, edit IRremote/IRremote.h to add "#define TEST" - * You must then recompile the library by removing IRremote.o and restarting - * the arduino IDE. - */ - -#include <IRremote.h> -#include <IRremoteInt.h> - -// Dumps out the decode_results structure. -// Call this after IRrecv::decode() -// void * to work around compiler issue -//void dump(void *v) { -// decode_results *results = (decode_results *)v -void dump(decode_results *results) { - int count = results->rawlen; - if (results->decode_type == UNKNOWN) { - Serial.println("Could not decode message"); - } - else { - if (results->decode_type == NEC) { - Serial.print("Decoded NEC: "); - } - else if (results->decode_type == SONY) { - Serial.print("Decoded SONY: "); - } - else if (results->decode_type == RC5) { - Serial.print("Decoded RC5: "); - } - else if (results->decode_type == RC6) { - Serial.print("Decoded RC6: "); - } - Serial.print(results->value, HEX); - Serial.print(" ("); - Serial.print(results->bits, DEC); - Serial.println(" bits)"); - } - Serial.print("Raw ("); - Serial.print(count, DEC); - Serial.print("): "); - - for (int i = 0; i < count; i++) { - if ((i % 2) == 1) { - Serial.print(results->rawbuf[i]*USECPERTICK, DEC); - } - else { - Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); - } - Serial.print(" "); - } - Serial.println(""); -} - -IRrecv irrecv(0); -decode_results results; - -class IRsendDummy : -public IRsend -{ -public: - // For testing, just log the marks/spaces -#define SENDLOG_LEN 128 - int sendlog[SENDLOG_LEN]; - int sendlogcnt; - IRsendDummy() : - IRsend() { - } - void reset() { - sendlogcnt = 0; - } - void mark(int time) { - sendlog[sendlogcnt] = time; - if (sendlogcnt < SENDLOG_LEN) sendlogcnt++; - } - void space(int time) { - sendlog[sendlogcnt] = -time; - if (sendlogcnt < SENDLOG_LEN) sendlogcnt++; - } - // Copies the dummy buf into the interrupt buf - void useDummyBuf() { - int last = SPACE; - irparams.rcvstate = STATE_STOP; - irparams.rawlen = 1; // Skip the gap - for (int i = 0 ; i < sendlogcnt; i++) { - if (sendlog[i] < 0) { - if (last == MARK) { - // New space - irparams.rawbuf[irparams.rawlen++] = (-sendlog[i] - MARK_EXCESS) / USECPERTICK; - last = SPACE; - } - else { - // More space - irparams.rawbuf[irparams.rawlen - 1] += -sendlog[i] / USECPERTICK; - } - } - else if (sendlog[i] > 0) { - if (last == SPACE) { - // New mark - irparams.rawbuf[irparams.rawlen++] = (sendlog[i] + MARK_EXCESS) / USECPERTICK; - last = MARK; - } - else { - // More mark - irparams.rawbuf[irparams.rawlen - 1] += sendlog[i] / USECPERTICK; - } - } - } - if (irparams.rawlen % 2) { - irparams.rawlen--; // Remove trailing space - } - } -}; - -IRsendDummy irsenddummy; - -void verify(unsigned long val, int bits, int type) { - irsenddummy.useDummyBuf(); - irrecv.decode(&results); - Serial.print("Testing "); - Serial.print(val, HEX); - if (results.value == val && results.bits == bits && results.decode_type == type) { - Serial.println(": OK"); - } - else { - Serial.println(": Error"); - dump(&results); - } -} - -void testNEC(unsigned long val, int bits) { - irsenddummy.reset(); - irsenddummy.sendNEC(val, bits); - verify(val, bits, NEC); -} -void testSony(unsigned long val, int bits) { - irsenddummy.reset(); - irsenddummy.sendSony(val, bits); - verify(val, bits, SONY); -} -void testRC5(unsigned long val, int bits) { - irsenddummy.reset(); - irsenddummy.sendRC5(val, bits); - verify(val, bits, RC5); -} -void testRC6(unsigned long val, int bits) { - irsenddummy.reset(); - irsenddummy.sendRC6(val, bits); - verify(val, bits, RC6); -} - -void test() { - Serial.println("NEC tests"); - testNEC(0x00000000, 32); - testNEC(0xffffffff, 32); - testNEC(0xaaaaaaaa, 32); - testNEC(0x55555555, 32); - testNEC(0x12345678, 32); - Serial.println("Sony tests"); - testSony(0xfff, 12); - testSony(0x000, 12); - testSony(0xaaa, 12); - testSony(0x555, 12); - testSony(0x123, 12); - Serial.println("RC5 tests"); - testRC5(0xfff, 12); - testRC5(0x000, 12); - testRC5(0xaaa, 12); - testRC5(0x555, 12); - testRC5(0x123, 12); - Serial.println("RC6 tests"); - testRC6(0xfffff, 20); - testRC6(0x00000, 20); - testRC6(0xaaaaa, 20); - testRC6(0x55555, 20); - testRC6(0x12345, 20); -} - -void setup() -{ - Serial.begin(9600); - test(); -} - -void loop() { -} diff --git a/IRremote/examples/IRtest2/IRtest2.ino b/IRremote/examples/IRtest2/IRtest2.ino deleted file mode 100644 index 56b8a4d2aa49fa4166ba9d42dfdd8ca4118b0b57..0000000000000000000000000000000000000000 --- a/IRremote/examples/IRtest2/IRtest2.ino +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Test send/receive functions of IRremote, using a pair of Arduinos. - * - * Arduino #1 should have an IR LED connected to the send pin (3). - * Arduino #2 should have an IR detector/demodulator connected to the - * receive pin (11) and a visible LED connected to pin 3. - * - * The cycle: - * Arduino #1 will wait 2 seconds, then run through the tests. - * It repeats this forever. - * Arduino #2 will wait for at least one second of no signal - * (to synchronize with #1). It will then wait for the same test - * signals. It will log all the status to the serial port. It will - * also indicate status through the LED, which will flash each time a test - * is completed. If there is an error, it will light up for 5 seconds. - * - * The test passes if the LED flashes 19 times, pauses, and then repeats. - * The test fails if the LED lights for 5 seconds. - * - * The test software automatically decides which board is the sender and which is - * the receiver by looking for an input on the send pin, which will indicate - * the sender. You should hook the serial port to the receiver for debugging. - * - * Copyright 2010 Ken Shirriff - * http://arcfn.com - */ - -#include <IRremote.h> - -int RECV_PIN = 11; -int LED_PIN = 3; - -IRrecv irrecv(RECV_PIN); -IRsend irsend; - -decode_results results; - -#define RECEIVER 1 -#define SENDER 2 -#define ERROR 3 - -int mode; - -void setup() -{ - Serial.begin(9600); - // Check RECV_PIN to decide if we're RECEIVER or SENDER - if (digitalRead(RECV_PIN) == HIGH) { - mode = RECEIVER; - irrecv.enableIRIn(); - pinMode(LED_PIN, OUTPUT); - digitalWrite(LED_PIN, LOW); - Serial.println("Receiver mode"); - } - else { - mode = SENDER; - Serial.println("Sender mode"); - } -} - -// Wait for the gap between tests, to synchronize with -// the sender. -// Specifically, wait for a signal followed by a gap of at last gap ms. -void waitForGap(int gap) { - Serial.println("Waiting for gap"); - while (1) { - while (digitalRead(RECV_PIN) == LOW) { - } - unsigned long time = millis(); - while (digitalRead(RECV_PIN) == HIGH) { - if (millis() - time > gap) { - return; - } - } - } -} - -// Dumps out the decode_results structure. -// Call this after IRrecv::decode() -void dump(decode_results *results) { - int count = results->rawlen; - if (results->decode_type == UNKNOWN) { - Serial.println("Could not decode message"); - } - else { - if (results->decode_type == NEC) { - Serial.print("Decoded NEC: "); - } - else if (results->decode_type == SONY) { - Serial.print("Decoded SONY: "); - } - else if (results->decode_type == RC5) { - Serial.print("Decoded RC5: "); - } - else if (results->decode_type == RC6) { - Serial.print("Decoded RC6: "); - } - Serial.print(results->value, HEX); - Serial.print(" ("); - Serial.print(results->bits, DEC); - Serial.println(" bits)"); - } - Serial.print("Raw ("); - Serial.print(count, DEC); - Serial.print("): "); - - for (int i = 0; i < count; i++) { - if ((i % 2) == 1) { - Serial.print(results->rawbuf[i]*USECPERTICK, DEC); - } - else { - Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); - } - Serial.print(" "); - } - Serial.println(""); -} - - -// Test send or receive. -// If mode is SENDER, send a code of the specified type, value, and bits -// If mode is RECEIVER, receive a code and verify that it is of the -// specified type, value, and bits. For success, the LED is flashed; -// for failure, the mode is set to ERROR. -// The motivation behind this method is that the sender and the receiver -// can do the same test calls, and the mode variable indicates whether -// to send or receive. -void test(char *label, int type, unsigned long value, int bits) { - if (mode == SENDER) { - Serial.println(label); - if (type == NEC) { - irsend.sendNEC(value, bits); - } - else if (type == SONY) { - irsend.sendSony(value, bits); - } - else if (type == RC5) { - irsend.sendRC5(value, bits); - } - else if (type == RC6) { - irsend.sendRC6(value, bits); - } - else { - Serial.print(label); - Serial.println("Bad type!"); - } - delay(200); - } - else if (mode == RECEIVER) { - irrecv.resume(); // Receive the next value - unsigned long max_time = millis() + 30000; - Serial.print(label); - - // Wait for decode or timeout - while (!irrecv.decode(&results)) { - if (millis() > max_time) { - Serial.println("Timeout receiving data"); - mode = ERROR; - return; - } - } - if (type == results.decode_type && value == results.value && bits == results.bits) { - Serial.println (": OK"); - digitalWrite(LED_PIN, HIGH); - delay(20); - digitalWrite(LED_PIN, LOW); - } - else { - Serial.println(": BAD"); - dump(&results); - mode = ERROR; - } - } -} - -// Test raw send or receive. This is similar to the test method, -// except it send/receives raw data. -void testRaw(char *label, unsigned int *rawbuf, int rawlen) { - if (mode == SENDER) { - Serial.println(label); - irsend.sendRaw(rawbuf, rawlen, 38 /* kHz */); - delay(200); - } - else if (mode == RECEIVER ) { - irrecv.resume(); // Receive the next value - unsigned long max_time = millis() + 30000; - Serial.print(label); - - // Wait for decode or timeout - while (!irrecv.decode(&results)) { - if (millis() > max_time) { - Serial.println("Timeout receiving data"); - mode = ERROR; - return; - } - } - - // Received length has extra first element for gap - if (rawlen != results.rawlen - 1) { - Serial.print("Bad raw length "); - Serial.println(results.rawlen, DEC); - mode = ERROR; - return; - } - for (int i = 0; i < rawlen; i++) { - long got = results.rawbuf[i+1] * USECPERTICK; - // Adjust for extra duration of marks - if (i % 2 == 0) { - got -= MARK_EXCESS; - } - else { - got += MARK_EXCESS; - } - // See if close enough, within 25% - if (rawbuf[i] * 1.25 < got || got * 1.25 < rawbuf[i]) { - Serial.println(": BAD"); - dump(&results); - mode = ERROR; - return; - } - - } - Serial.println (": OK"); - digitalWrite(LED_PIN, HIGH); - delay(20); - digitalWrite(LED_PIN, LOW); - } -} - -// This is the raw data corresponding to NEC 0x12345678 -unsigned int sendbuf[] = { /* NEC format */ - 9000, 4500, - 560, 560, 560, 560, 560, 560, 560, 1690, /* 1 */ - 560, 560, 560, 560, 560, 1690, 560, 560, /* 2 */ - 560, 560, 560, 560, 560, 1690, 560, 1690, /* 3 */ - 560, 560, 560, 1690, 560, 560, 560, 560, /* 4 */ - 560, 560, 560, 1690, 560, 560, 560, 1690, /* 5 */ - 560, 560, 560, 1690, 560, 1690, 560, 560, /* 6 */ - 560, 560, 560, 1690, 560, 1690, 560, 1690, /* 7 */ - 560, 1690, 560, 560, 560, 560, 560, 560, /* 8 */ - 560}; - -void loop() { - if (mode == SENDER) { - delay(2000); // Delay for more than gap to give receiver a better chance to sync. - } - else if (mode == RECEIVER) { - waitForGap(1000); - } - else if (mode == ERROR) { - // Light up for 5 seconds for error - digitalWrite(LED_PIN, HIGH); - delay(5000); - digitalWrite(LED_PIN, LOW); - mode = RECEIVER; // Try again - return; - } - - // The test suite. - test("SONY1", SONY, 0x123, 12); - test("SONY2", SONY, 0x000, 12); - test("SONY3", SONY, 0xfff, 12); - test("SONY4", SONY, 0x12345, 20); - test("SONY5", SONY, 0x00000, 20); - test("SONY6", SONY, 0xfffff, 20); - test("NEC1", NEC, 0x12345678, 32); - test("NEC2", NEC, 0x00000000, 32); - test("NEC3", NEC, 0xffffffff, 32); - test("NEC4", NEC, REPEAT, 32); - test("RC51", RC5, 0x12345678, 32); - test("RC52", RC5, 0x0, 32); - test("RC53", RC5, 0xffffffff, 32); - test("RC61", RC6, 0x12345678, 32); - test("RC62", RC6, 0x0, 32); - test("RC63", RC6, 0xffffffff, 32); - - // Tests of raw sending and receiving. - // First test sending raw and receiving raw. - // Then test sending raw and receiving decoded NEC - // Then test sending NEC and receiving raw - testRaw("RAW1", sendbuf, 67); - if (mode == SENDER) { - testRaw("RAW2", sendbuf, 67); - test("RAW3", NEC, 0x12345678, 32); - } - else { - test("RAW2", NEC, 0x12345678, 32); - testRaw("RAW3", sendbuf, 67); - } -} diff --git a/IRremote/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino b/IRremote/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino deleted file mode 100644 index 33c167c582a52fe822381dc03f3ca7446c39b11f..0000000000000000000000000000000000000000 --- a/IRremote/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino +++ /dev/null @@ -1,29 +0,0 @@ -/* - * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend - * An IR LED must be connected to Arduino PWM pin 3. - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) - */ -#include <IRremote.h> - -#define PanasonicAddress 0x4004 // Panasonic address (Pre data) -#define PanasonicPower 0x100BCBD // Panasonic Power button - -#define JVCPower 0xC5E8 - -IRsend irsend; - -void setup() -{ -} - -void loop() { - irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off - - irsend.sendJVC(JVCPower, 16,0); // hex value, 16 bits, no repeat - delayMicroseconds(50); // see http://www.sbprojects.com/knowledge/ir/jvc.php for information - irsend.sendJVC(JVCPower, 16,1); // hex value, 16 bits, repeat - delayMicroseconds(50); -} diff --git a/IRremote/examples/LGACSendDemo/LGACSendDemo.ino b/IRremote/examples/LGACSendDemo/LGACSendDemo.ino deleted file mode 100644 index da5db37ebfff734a43c6ae71527f6a7473b4677d..0000000000000000000000000000000000000000 --- a/IRremote/examples/LGACSendDemo/LGACSendDemo.ino +++ /dev/null @@ -1,263 +0,0 @@ -#include <IRremote.h> -#include <Wire.h> - - -IRsend irsend; -// not used -int RECV_PIN = 11; -IRrecv irrecv (RECV_PIN); - -const int AC_TYPE = 0; -// 0 : TOWER -// 1 : WALL -// - -int AC_HEAT = 0; -// 0 : cooling -// 1 : heating - -int AC_POWER_ON = 0; -// 0 : off -// 1 : on - -int AC_AIR_ACLEAN = 0; -// 0 : off -// 1 : on --> power on - -int AC_TEMPERATURE = 27; -// temperature : 18 ~ 30 - -int AC_FLOW = 1; -// 0 : low -// 1 : mid -// 2 : high -// if AC_TYPE =1, 3 : change -// - - -const int AC_FLOW_TOWER[3] = {0, 4, 6}; -const int AC_FLOW_WALL[4] = {0, 2, 4, 5}; - -unsigned long AC_CODE_TO_SEND; - -int r = LOW; -int o_r = LOW; - -byte a, b; - -void ac_send_code(unsigned long code) -{ - Serial.print("code to send : "); - Serial.print(code, BIN); - Serial.print(" : "); - Serial.println(code, HEX); - - irsend.sendLG(code, 28); -} - -void ac_activate(int temperature, int air_flow) -{ - - int AC_MSBITS1 = 8; - int AC_MSBITS2 = 8; - int AC_MSBITS3 = 0; - int AC_MSBITS4 ; - if ( AC_HEAT == 1 ) { - // heating - AC_MSBITS4 = 4; - } else { - // cooling - AC_MSBITS4 = 0; - } - int AC_MSBITS5 = temperature - 15; - int AC_MSBITS6 ; - - if ( AC_TYPE == 0) { - AC_MSBITS6 = AC_FLOW_TOWER[air_flow]; - } else { - AC_MSBITS6 = AC_FLOW_WALL[air_flow]; - } - - int AC_MSBITS7 = (AC_MSBITS3 + AC_MSBITS4 + AC_MSBITS5 + AC_MSBITS6) & B00001111; - - AC_CODE_TO_SEND = AC_MSBITS1 << 4 ; - AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS2) << 4; - AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS3) << 4; - AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS4) << 4; - AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS5) << 4; - AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS6) << 4; - AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS7); - - ac_send_code(AC_CODE_TO_SEND); - - AC_POWER_ON = 1; - AC_TEMPERATURE = temperature; - AC_FLOW = air_flow; -} - -void ac_change_air_swing(int air_swing) -{ - if ( AC_TYPE == 0) { - if ( air_swing == 1) { - AC_CODE_TO_SEND = 0x881316B; - } else { - AC_CODE_TO_SEND = 0x881317C; - } - } else { - if ( air_swing == 1) { - AC_CODE_TO_SEND = 0x8813149; - } else { - AC_CODE_TO_SEND = 0x881315A; - } - } - - ac_send_code(AC_CODE_TO_SEND); -} - -void ac_power_down() -{ - AC_CODE_TO_SEND = 0x88C0051; - - ac_send_code(AC_CODE_TO_SEND); - - AC_POWER_ON = 0; -} - -void ac_air_clean(int air_clean) -{ - if ( air_clean == 1) { - AC_CODE_TO_SEND = 0x88C000C; - } else { - AC_CODE_TO_SEND = 0x88C0084; - } - - ac_send_code(AC_CODE_TO_SEND); - - AC_AIR_ACLEAN = air_clean; -} - -void setup() -{ - Serial.begin(38400); - delay(1000); - Wire.begin(7); - Wire.onReceive(receiveEvent); - - Serial.println(" - - - T E S T - - - "); - - /* test - ac_activate(25, 1); - delay(5000); - ac_activate(27, 2); - delay(5000); - - */ -} - -void loop() -{ - - - ac_activate(25, 1); - delay(5000); - ac_activate(27, 0); - delay(5000); - - - if ( r != o_r) { - - /* - # a : mode or temp b : air_flow, temp, swing, clean, cooling/heating - # 18 ~ 30 : temp 0 ~ 2 : flow // on - # 0 : off 0 - # 1 : on 0 - # 2 : air_swing 0 or 1 - # 3 : air_clean 0 or 1 - # 4 : air_flow 0 ~ 2 : flow - # 5 : temp 18 ~ 30 - # + : temp + 1 - # - : temp - 1 - # m : change cooling to air clean, air clean to cooling - */ - Serial.print("a : "); - Serial.print(a); - Serial.print(" b : "); - Serial.println(b); - - switch (a) { - case 0: // off - ac_power_down(); - break; - case 1: // on - ac_activate(AC_TEMPERATURE, AC_FLOW); - break; - case 2: - if ( b == 0 | b == 1 ) { - ac_change_air_swing(b); - } - break; - case 3: // 1 : clean on, power on - if ( b == 0 | b == 1 ) { - ac_air_clean(b); - } - break; - case 4: - if ( 0 <= b && b <= 2 ) { - ac_activate(AC_TEMPERATURE, b); - } - break; - case 5: - if (18 <= b && b <= 30 ) { - ac_activate(b, AC_FLOW); - } - break; - case '+': - if ( 18 <= AC_TEMPERATURE && AC_TEMPERATURE <= 29 ) { - ac_activate((AC_TEMPERATURE + 1), AC_FLOW); - } - break; - case '-': - if ( 19 <= AC_TEMPERATURE && AC_TEMPERATURE <= 30 ) { - ac_activate((AC_TEMPERATURE - 1), AC_FLOW); - } - break; - case 'm': - /* - if ac is on, 1) turn off, 2) turn on ac_air_clean(1) - if ac is off, 1) turn on, 2) turn off ac_air_clean(0) - */ - if ( AC_POWER_ON == 1 ) { - ac_power_down(); - delay(100); - ac_air_clean(1); - } else { - if ( AC_AIR_ACLEAN == 1) { - ac_air_clean(0); - delay(100); - } - ac_activate(AC_TEMPERATURE, AC_FLOW); - } - break; - default: - if ( 18 <= a && a <= 30 ) { - if ( 0 <= b && b <= 2 ) { - ac_activate(a, b); - } - } - } - - o_r = r ; - } - delay(100); -} - - - -void receiveEvent(int howMany) -{ - a = Wire.read(); - b = Wire.read(); - r = !r ; -} - - diff --git a/IRremote/examples/LGACSendDemo/LGACSendDemo.md b/IRremote/examples/LGACSendDemo/LGACSendDemo.md deleted file mode 100644 index 62c7073165fc64bcfed09754f7f8ebb26ccb724d..0000000000000000000000000000000000000000 --- a/IRremote/examples/LGACSendDemo/LGACSendDemo.md +++ /dev/null @@ -1,93 +0,0 @@ -=== decoding for LG A/C ==== -- 1) remote of LG AC has two type of HDR mark/space, 8000/4000 and 3100/10000 -- 2) HDR 8000/4000 is decoded using decodeLG(IRrecvDumpV2) without problem -- 3) for HDR 3100/10000, use AnalysIR's code : http://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino/ -- 4) for bin output based on AnalysIR's code : https://gist.github.com/chaeplin/a3a4b4b6b887c663bfe8 -- 5) remove first two byte(11) -- 6) sample rawcode with bin output : https://gist.github.com/chaeplin/134d232e0b8cfb898860 - - -=== *** === -- 1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d -- 2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4 - - -=== *** === -- (0) : Cooling or Heating -- (1) : fixed -- (2) : fixed -- (3) : special(power, swing, air clean) -- (4) : change air flow, temperature, cooling(0)/heating(4) -- (5) : temperature ( 15 + (5) = ) -- (6) : air flow -- (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111 - - -°F = °C × 1.8 + 32 -°C = (°F − 32) / 1.8 - - -=== *** === -* remote / Korea / without heating - -| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) -|----------------|---|----|----|----|----|----|----|---- -| on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100 -| on / 26 / mid | C |1000|1000|0000|0000|1011|0010|1101 -| on / 27 / mid | C |1000|1000|0000|0000|1100|0010|1110 -| on / 28 / mid | C |1000|1000|0000|0000|1101|0010|1111 -| on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110 -| on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111 -| on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 -| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 -|----------------|---|----|----|----|----|----|----|---- -| 1 up | C |1000|1000|0000|1000|1101|0100|1001 -|----------------|---|----|----|----|----|----|----|---- -| Cool power | C |1000|1000|0001|0000|0000|1100|1101 -| energy saving | C |1000|1000|0001|0000|0000|0100|0101 -| power | C |1000|1000|0001|0000|0000|1000|1001 -| flow/up/down | C |1000|1000|0001|0011|0001|0100|1001 -| up/down off | C |1000|1000|0001|0011|0001|0101|1010 -| flow/left/right| C |1000|1000|0001|0011|0001|0110|1011 -| left/right off | C |1000|1000|0001|0011|0001|0111|1100 -|----------------|---|----|----|----|----|----|----|---- -| Air clean | C |1000|1000|1100|0000|0000|0000|1100 -|----------------|---|----|----|----|----|----|----|---- -| off | C |1000|1000|1100|0000|0000|0101|0001 - - - -* remote / with heating -* converted using raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf - -| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) -|----------------|---|----|----|----|----|----|----|---- -| on | C |1000|1000|0000|0000|1011|0010|1101 -|----------------|---|----|----|----|----|----|----|---- -| off | C |1000|1000|1100|0000|0000|0101|0001 -|----------------|---|----|----|----|----|----|----|---- -| 64 / 18 | C |1000|1000|0000|0000|0011|0100|0111 -| 66 / 19 | C |1000|1000|0000|0000|0100|0100|1000 -| 68 / 20 | C |1000|1000|0000|0000|0101|0100|1001 -| 70 / 21 | C |1000|1000|0000|0000|0110|0100|1010 -| 72 / 22 | C |1000|1000|0000|0000|0111|0100|1011 -| 74 / 23 | C |1000|1000|0000|0000|1000|0100|1100 -| 76 / 25 | C |1000|1000|0000|0000|1010|0100|1110 -| 78 / 26 | C |1000|1000|0000|0000|1011|0100|1111 -| 80 / 27 | C |1000|1000|0000|0000|1100|0100|0000 -| 82 / 28 | C |1000|1000|0000|0000|1101|0100|0001 -| 84 / 29 | C |1000|1000|0000|0000|1110|0100|0010 -| 86 / 30 | C |1000|1000|0000|0000|1111|0100|0011 -|----------------|---|----|----|----|----|----|----|---- -| heat64 | H |1000|1000|0000|0100|0011|0100|1011 -| heat66 | H |1000|1000|0000|0100|0100|0100|1100 -| heat68 | H |1000|1000|0000|0100|0101|0100|1101 -| heat70 | H |1000|1000|0000|0100|0110|0100|1110 -| heat72 | H |1000|1000|0000|0100|0111|0100|1111 -| heat74 | H |1000|1000|0000|0100|1000|0100|0000 -| heat76 | H |1000|1000|0000|0100|1001|0100|0001 -| heat78 | H |1000|1000|0000|0100|1011|0100|0011 -| heat80 | H |1000|1000|0000|0100|1100|0100|0100 -| heat82 | H |1000|1000|0000|0100|1101|0100|0101 -| heat84 | H |1000|1000|0000|0100|1110|0100|0110 -| heat86 | H |1000|1000|0000|0100|1111|0100|0111 diff --git a/IRremote/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino b/IRremote/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino deleted file mode 100644 index e43d06c2e36f1a9f385a2061a9641fac8e1fb88f..0000000000000000000000000000000000000000 --- a/IRremote/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino +++ /dev/null @@ -1,22 +0,0 @@ -/* - * LegoPowerFunctionsSendDemo: LEGO Power Functions - * Copyright (c) 2016 Philipp Henkel - */ - -#include <IRremote.h> -#include <IRremoteInt.h> - -IRsend irsend; - -void setup() { -} - -void loop() { - // Send repeated command "channel 1, blue forward, red backward" - irsend.sendLegoPowerFunctions(0x197); - delay(2000); - - // Send single command "channel 1, blue forward, red backward" - irsend.sendLegoPowerFunctions(0x197, false); - delay(2000); -} diff --git a/IRremote/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino b/IRremote/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino deleted file mode 100644 index 65760e2fddf32368644224ffe47deb1ef8821f94..0000000000000000000000000000000000000000 --- a/IRremote/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino +++ /dev/null @@ -1,193 +0,0 @@ -/* - * LegoPowerFunctionsTest: LEGO Power Functions Tests - * Copyright (c) 2016, 2017 Philipp Henkel - */ - -#include <ir_Lego_PF_BitStreamEncoder.h> - -void setup() { - Serial.begin(9600); - delay(1000); // wait for reset triggered by serial connection - runBitStreamEncoderTests(); -} - -void loop() { -} - -void runBitStreamEncoderTests() { - Serial.println(); - Serial.println("BitStreamEncoder Tests"); - static LegoPfBitStreamEncoder bitStreamEncoder; - testStartBit(bitStreamEncoder); - testLowBit(bitStreamEncoder); - testHighBit(bitStreamEncoder); - testMessageBitCount(bitStreamEncoder); - testMessageBitCountRepeat(bitStreamEncoder); - testMessage407(bitStreamEncoder); - testMessage407Repeated(bitStreamEncoder); - testGetChannelId1(bitStreamEncoder); - testGetChannelId2(bitStreamEncoder); - testGetChannelId3(bitStreamEncoder); - testGetChannelId4(bitStreamEncoder); - testGetMessageLengthAllHigh(bitStreamEncoder); - testGetMessageLengthAllLow(bitStreamEncoder); -} - -void logTestResult(bool testPassed) { - if (testPassed) { - Serial.println("OK"); - } - else { - Serial.println("FAIL ############"); - } -} - -void testStartBit(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testStartBit "); - bitStreamEncoder.reset(0, false); - int startMark = bitStreamEncoder.getMarkDuration(); - int startPause = bitStreamEncoder.getPauseDuration(); - logTestResult(startMark == 158 && startPause == 1184-158); -} - -void testLowBit(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testLowBit "); - bitStreamEncoder.reset(0, false); - bitStreamEncoder.next(); - int lowMark = bitStreamEncoder.getMarkDuration(); - int lowPause = bitStreamEncoder.getPauseDuration(); - logTestResult(lowMark == 158 && lowPause == 421-158); -} - -void testHighBit(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testHighBit "); - bitStreamEncoder.reset(0xFFFF, false); - bitStreamEncoder.next(); - int highMark = bitStreamEncoder.getMarkDuration(); - int highPause = bitStreamEncoder.getPauseDuration(); - logTestResult(highMark == 158 && highPause == 711-158); -} - -void testMessageBitCount(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testMessageBitCount "); - bitStreamEncoder.reset(0xFFFF, false); - int bitCount = 1; - while (bitStreamEncoder.next()) { - bitCount++; - } - logTestResult(bitCount == 18); -} - -boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) { - bool result = true; - result = result && bitStreamEncoder.getMarkDuration() == markDuration; - result = result && bitStreamEncoder.getPauseDuration() == pauseDuration; - return result; -} - -boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) { - bool result = bitStreamEncoder.next(); - result = result && check(bitStreamEncoder, markDuration, pauseDuration); - return result; -} - -boolean checkDataBitsOfMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) { - bool result = true; - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 553); - result = result && checkNext(bitStreamEncoder, 158, 553); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 553); - result = result && checkNext(bitStreamEncoder, 158, 263); - result = result && checkNext(bitStreamEncoder, 158, 553); - result = result && checkNext(bitStreamEncoder, 158, 553); - result = result && checkNext(bitStreamEncoder, 158, 553); - return result; -} - -void testMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testMessage407 "); - bitStreamEncoder.reset(407, false); - bool result = true; - result = result && check(bitStreamEncoder, 158, 1026); - result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026); - result = result && !bitStreamEncoder.next(); - logTestResult(result); -} - -void testMessage407Repeated(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testMessage407Repeated "); - bitStreamEncoder.reset(407, true); - bool result = true; - result = result && check(bitStreamEncoder, 158, 1026); - result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L); - result = result && checkNext(bitStreamEncoder, 158, 1026); - result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L); - result = result && checkNext(bitStreamEncoder, 158, 1026); - result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L); - result = result && checkNext(bitStreamEncoder, 158, 1026); - result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L); - result = result && checkNext(bitStreamEncoder, 158, 1026); - result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026); - result = result && !bitStreamEncoder.next(); - logTestResult(result); -} - -void testMessageBitCountRepeat(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testMessageBitCountRepeat "); - bitStreamEncoder.reset(0xFFFF, true); - int bitCount = 1; - while (bitStreamEncoder.next()) { - bitCount++; - } - logTestResult(bitCount == 5*18); -} - -void testGetChannelId1(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testGetChannelId1 "); - bitStreamEncoder.reset(407, false); - logTestResult(bitStreamEncoder.getChannelId() == 1); -} - -void testGetChannelId2(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testGetChannelId2 "); - bitStreamEncoder.reset(4502, false); - logTestResult(bitStreamEncoder.getChannelId() == 2); -} - -void testGetChannelId3(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testGetChannelId3 "); - bitStreamEncoder.reset(8597, false); - logTestResult(bitStreamEncoder.getChannelId() == 3); -} - -void testGetChannelId4(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testGetChannelId4 "); - bitStreamEncoder.reset(12692, false); - logTestResult(bitStreamEncoder.getChannelId() == 4); -} - -void testGetMessageLengthAllHigh(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testGetMessageLengthAllHigh "); - bitStreamEncoder.reset(0xFFFF, false); - logTestResult(bitStreamEncoder.getMessageLength() == 13744); -} - -void testGetMessageLengthAllLow(LegoPfBitStreamEncoder& bitStreamEncoder) { - Serial.print(" testGetMessageLengthAllLow "); - bitStreamEncoder.reset(0x0, false); - logTestResult(bitStreamEncoder.getMessageLength() == 9104); -} diff --git a/IRremote/examples/MicroGirs/MicroGirs.ino b/IRremote/examples/MicroGirs/MicroGirs.ino deleted file mode 100644 index a840bf240f108c261e88e7a8f9d50fd587c7cf60..0000000000000000000000000000000000000000 --- a/IRremote/examples/MicroGirs/MicroGirs.ino +++ /dev/null @@ -1,398 +0,0 @@ -/** - * @file MicroGirs.ino - * - * @brief This is a minimalistic <a href="http://harctoolbox.org/Girs.html">Girs server</a>. - * It only depends on (a subset of) IRremote. It can be used with - * <a href="http://www.harctoolbox.org/IrScrutinizer.html">IrScrutinizer</a> - * (select Sending/Capturing hw = Girs Client) as well as - * <a href="http://lirc.org">Lirc</a> - * version 0.9.4 and later, using the driver <a href="http://lirc.org/html/girs.html">Girs</a>). - * (Authors of similar software are encourage to implement support.) - * - * It runs on all hardware on which IRemote runs. - * - * It consists of an interactive IR server, taking one-line commands from - * the "user" (which is typically not a person but another program), and - * responds with a one-line response. In the language of the Girs - * specifications, the modules "base", receive, and transmit are - * implemented. (The two latter can be disabled by not defining two - * corresponding CPP symbols.) - * - * It understands the following commands: - * - * The "version" command returns the program name and version, - * The "modules" command returns the modules implemented, normally base, receive and transmit. - * The "receive" command reads an IR signal using the used, demodulating IR sensor. - * The "send" commands transmits a supplied raw signal the requested number of times. - * - * Only the first character of the command is evaluated in this implementation. - * - * The "receive" command returns the received IR sequence as a sequence - * of durations, including a (dummy) trailing silence. On-periods - * ("marks", "flashes") are prefixed by "+", while off-periods ("spaces", - * "gaps") are prefixed by "-". The present version never times out. - * - * The \c send command takes the following parameters: - * - * send noSends frequencyHz introLength repeatLength endingLength durations... - - * where - * - * * frequencyHz denotes the modulation frequency in Hz - * (\e not khz, as is normally used in IRremote) - * * introLength denotes the length of the intro sequence, must be even, - * * repeatLength denotes the length of the repeat sequence, must be even, - * * endingLength denotes the length of the ending sequence (normally 0), must be even. - * * duration... denotes the microsecond durations to send, - * starting with the first on-period, ending with a (possibly dummy) trailing silence - * - * Semantics: first the intro sequence will be sent once (i.e., the first - * repeatLength durations) (if non-empty). Then the repeat sequence will - * be sent (noSends-1) times, unless the intro sequence was empty, in - * which case it will be send noSends times. Finally, the ending - * sequence will be send once (if non-empty). - * - * Weaknesses of the IRremote implementation: - * * Reception never times out if no IR is seen. - * * The IRrecv class does its own decoding which is irrelevant for us. - * * The timeout at the end on a signal reception is not configurable. - * For example, a NEC1 type signal will cut after the intro sequence, - * and the repeats will be considered independent signals. - * In IrSqrutinizer, recognition of repeating signals will therefore not work. - * The size of the data is platform dependent ("unsigned int", which is 16 bit on AVR boards, 32 bits on 32 bit boards). - * - */ -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -#if !defined(RAW_BUFFER_LENGTH) -# if RAMEND <= 0x4FF || RAMSIZE < 0x4FF -#define RAW_BUFFER_LENGTH 180 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# elif RAMEND <= 0x8FF || RAMSIZE < 0x8FF -#define RAW_BUFFER_LENGTH 500 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# else -#define RAW_BUFFER_LENGTH 750 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# endif -#endif - -/** - * Baud rate for the serial/USB connection. - * (115200 is the default for IrScrutinizer and Lirc.) - */ -#define BAUDRATE 115200 -#define NO_DECODER - -#include "IRremote.hpp" -#include <limits.h> - -/** - * Define to support reception of IR. - */ -#define RECEIVE - -/** - * Define to support transmission of IR signals. - */ -#define TRANSMIT - -// (The sending pin is in general not configurable, see the documentation of IRremote.) - -/** - * Character that ends the command lines. Do not change unless you known what - * you are doing. IrScrutinizer and Lirc expects \r. - */ -#define EOLCHAR '\r' - -////// End of user configurable variables //////////////////// - -/** - * The modules supported, as given by the "modules" command. - */ -#if defined(TRANSMIT) -#if defined(RECEIVE) -#define modulesSupported "base transmit receive" -#else // ! RECEIVE -#define modulesSupported "base transmit" -#endif -#else // !TRANSMIT -#if defined(RECEIVE) -#define modulesSupported "base receive" -#else // ! RECETVE -#error At lease one of TRANSMIT and RECEIVE must be defined -#endif -#endif - -/** - * Name of program, as reported by the "version" command. - */ -#define PROGNAME "MicroGirs" - -/** - * Version of program, as reported by the "version" command. - */ -#define VERSION "2020-07-05" - -#define okString "OK" -#define errorString "ERROR" -#define timeoutString "." - -// For compatibility with IRremote, we deliberately use -// the platform dependent types. -// (Although it is a questionable idea ;-) ) -/** - * Type used for modulation frequency in Hz (\e not kHz). - */ -typedef unsigned frequency_t; // max 65535, unless 32-bit - -/** - * Type used for durations in micro seconds. - */ -typedef uint16_t microseconds_t; // max 65535 - -static const microseconds_t DUMMYENDING = 40000U; -static const frequency_t FREQUENCY_T_MAX = UINT16_MAX; -static const frequency_t MICROSECONDS_T_MAX = UINT16_MAX; - -/** - * Our own tokenizer class. Breaks the command line into tokens. - * Usage outside of this package is discouraged. - */ -class Tokenizer { -private: - static const int invalidIndex = -1; - - int index; // signed since invalidIndex is possible - const String &payload; - void trim(); - -public: - Tokenizer(const String &str); - - String getToken(); - String getRest(); - String getLine(); - long getInt(); - microseconds_t getMicroseconds(); - frequency_t getFrequency(); - - static const int invalid = INT_MAX; -}; - -Tokenizer::Tokenizer(const String &str) : - index(0), payload(str) { -} - -String Tokenizer::getRest() { - String result = index == invalidIndex ? String("") : payload.substring(index); - index = invalidIndex; - return result; -} - -String Tokenizer::getLine() { - if (index == invalidIndex) - return String(""); - - int i = payload.indexOf('\n', index); - String s = (i > 0) ? payload.substring(index, i) : payload.substring(index); - index = (i > 0) ? i + 1 : invalidIndex; - return s; -} - -String Tokenizer::getToken() { - if (index < 0) - return String(""); - - int i = payload.indexOf(' ', index); - String s = (i > 0) ? payload.substring(index, i) : payload.substring(index); - index = (i > 0) ? i : invalidIndex; - if (index != invalidIndex) - if (index != invalidIndex) - while (payload.charAt(index) == ' ') - index++; - return s; -} - -long Tokenizer::getInt() { - String token = getToken(); - return token == "" ? (long) invalid : token.toInt(); -} - -microseconds_t Tokenizer::getMicroseconds() { - long t = getToken().toInt(); - return (microseconds_t) ((t < MICROSECONDS_T_MAX) ? t : MICROSECONDS_T_MAX); -} - -frequency_t Tokenizer::getFrequency() { - long t = getToken().toInt(); - return (frequency_t) ((t < FREQUENCY_T_MAX) ? t : FREQUENCY_T_MAX); -} -///////////////// end Tokenizer ///////////////////////////////// - -#if defined(TRANSMIT) -static inline unsigned hz2khz(frequency_t hz) { - return (hz + 500) / 1000; -} - -/** - * Transmits the IR signal given as argument. - * - * The intro sequence (possibly empty) is first sent. Then the repeat signal - * (also possibly empty) is sent, "times" times, except for the case of - * the intro signal being empty, in which case it is sent "times" times. - * Finally the ending sequence (possibly empty) is sent. - * - * @param intro Sequence to be sent exactly once at the start. - * @param lengthIntro Number of durations in intro sequence, must be even. - * @param repeat Sequence top possibly be sent multiple times - * @param lengthRepeat Number of durations in repeat sequence. - * @param ending Sequence to be sent at the end, possibly empty - * @param lengthEnding Number of durations in ending sequence - * @param frequency Modulation frequency, in Hz (not kHz as normally in IRremote) - * @param times Number of times to send the signal, in the sense above. - */ -static void sendRaw(const microseconds_t intro[], unsigned lengthIntro, const microseconds_t repeat[], unsigned lengthRepeat, - const microseconds_t ending[], unsigned lengthEnding, frequency_t frequency, unsigned times) { - if (lengthIntro > 0U) - IrSender.sendRaw(intro, lengthIntro, hz2khz(frequency)); - if (lengthRepeat > 0U) - for (unsigned i = 0U; i < times - (lengthIntro > 0U); i++) - IrSender.sendRaw(repeat, lengthRepeat, hz2khz(frequency)); - if (lengthEnding > 0U) - IrSender.sendRaw(ending, lengthEnding, hz2khz(frequency)); -} -#endif // TRANSMIT - -#if defined(RECEIVE) - -static void dump(Stream &stream) { - unsigned int count = IrReceiver.decodedIRData.rawDataPtr->rawlen; - // If buffer gets full, count = RAW_BUFFER_LENGTH, which is odd, - // and IrScrutinizer does not like that. - count &= ~1; - for (unsigned int i = 1; i < count; i++) { - stream.write(i & 1 ? '+' : '-'); - stream.print(IrReceiver.decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK, DEC); - stream.print(" "); - } - stream.print('-'); - stream.println(DUMMYENDING); -} - -/** - * Reads a command from the stream given as argument. - * @param stream Stream to read from, typically Serial. - */ -static void receive(Stream &stream) { - IrReceiver.start(); - - while (!IrReceiver.decode()) { - } - IrReceiver.stop(); - - dump(stream); -} - -#endif // RECEIVE - -/** - * Initialization. - */ -void setup() { - Serial.begin(BAUDRATE); - while (!Serial) - ; // wait for serial port to connect. - - Serial.println(F(PROGNAME " " VERSION)); - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - -#if defined(RECEIVE) - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.print(F("at pin ")); -#endif - -#if defined(IR_SEND_PIN) - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin -#else - IrSender.begin(3, ENABLE_LED_FEEDBACK, USE_DEFAULT_FEEDBACK_LED_PIN); // Specify send pin and enable feedback LED at default feedback LED pin -#endif - -} - -static String readCommand(Stream &stream) { - while (stream.available() == 0) { - } - - String line = stream.readStringUntil(EOLCHAR); - line.trim(); - return line; -} - -static void processCommand(const String &line, Stream &stream) { - Tokenizer tokenizer(line); - String cmd = tokenizer.getToken(); - - // Decode the command in cmd - if (cmd.length() == 0) { - // empty command, do nothing - stream.println(F(okString)); - return; - } - - switch (cmd[0]) { - case 'm': - stream.println(F(modulesSupported)); - break; - -#if defined(RECEIVE) - case 'r': // receive - //case 'a': - //case 'c': - receive(stream); - break; -#endif // RECEIVE - -#if defined(TRANSMIT) - case 's': // send - { - // TODO: handle unparsable data gracefully - unsigned noSends = (unsigned) tokenizer.getInt(); - frequency_t frequency = tokenizer.getFrequency(); - unsigned introLength = (unsigned) tokenizer.getInt(); - unsigned repeatLength = (unsigned) tokenizer.getInt(); - unsigned endingLength = (unsigned) tokenizer.getInt(); - microseconds_t intro[introLength]; - microseconds_t repeat[repeatLength]; - microseconds_t ending[endingLength]; - for (unsigned i = 0; i < introLength; i++) - intro[i] = tokenizer.getMicroseconds(); - for (unsigned i = 0; i < repeatLength; i++) - repeat[i] = tokenizer.getMicroseconds(); - for (unsigned i = 0; i < endingLength; i++) - ending[i] = tokenizer.getMicroseconds(); - sendRaw(intro, introLength, repeat, repeatLength, ending, endingLength, frequency, noSends); - stream.println(F(okString)); - } - break; -#endif // TRANSMIT - - case 'v': // version - stream.println(F(PROGNAME " " VERSION)); - break; - default: - stream.println(F(errorString)); - } -} - -/** - * Reads a command from the serial line and executes it- - */ -void loop() { - String line = readCommand(Serial); - processCommand(line, Serial); -} diff --git a/IRremote/examples/MicroGirs/PinDefinitionsAndMore.h b/IRremote/examples/MicroGirs/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/MicroGirs/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/ReceiveAndSend/PinDefinitionsAndMore.h b/IRremote/examples/ReceiveAndSend/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveAndSend/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/ReceiveAndSend/ReceiveAndSend.ino b/IRremote/examples/ReceiveAndSend/ReceiveAndSend.ino deleted file mode 100644 index fdd4eaf369a9a13dc74efd19ea480fcf87926151..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveAndSend/ReceiveAndSend.ino +++ /dev/null @@ -1,242 +0,0 @@ -/* - * ReceiveAndSend.cpp - * - * Record and play back last received IR signal at button press. - * The logic is: - * If the button is pressed, send the IR code. - * If an IR code is received, record it. - * If the protocol is unknown or not enabled, store it as raw data for later sending. - * - * An example for simultaneous receiving and sending is in the UnitTest example. - * - * An IR detector/demodulator must be connected to the input IR_RECEIVE_PIN. - * - * A button must be connected between the input SEND_BUTTON_PIN and ground. - * A visible LED can be connected to STATUS_PIN to provide status. - * - * - * Initially coded 2009 Ken Shirriff http://www.righto.com - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2009-2023 Ken Shirriff, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -/* - * Specify which protocol(s) should be used for decoding. - * If no protocol is defined, all protocols (except Bang&Olufsen) are active. - * This must be done before the #include <IRremote.hpp> - */ -//#define DECODE_DENON // Includes Sharp -//#define DECODE_JVC -//#define DECODE_KASEIKYO -//#define DECODE_PANASONIC // alias for DECODE_KASEIKYO -//#define DECODE_LG -#define DECODE_NEC // Includes Apple and Onkyo -//#define DECODE_SAMSUNG -//#define DECODE_SONY -//#define DECODE_RC5 -//#define DECODE_RC6 - -//#define DECODE_BOSEWAVE -//#define DECODE_LEGO_PF -//#define DECODE_MAGIQUEST -//#define DECODE_WHYNTER -//#define DECODE_FAST -// -#if !defined(RAW_BUFFER_LENGTH) -# if RAMEND <= 0x4FF || RAMSIZE < 0x4FF -#define RAW_BUFFER_LENGTH 120 -# elif RAMEND <= 0xAFF || RAMSIZE < 0xAFF // 0xAFF for LEONARDO -#define RAW_BUFFER_LENGTH 400 // 600 is too much here, because we have additional uint8_t rawCode[RAW_BUFFER_LENGTH]; -# else -#define RAW_BUFFER_LENGTH 750 -# endif -#endif - -//#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. -//#define EXCLUDE_EXOTIC_PROTOCOLS // saves around 650 bytes program memory if all other protocols are active -//#define NO_LED_FEEDBACK_CODE // saves 92 bytes program memory -//#define RECORD_GAP_MICROS 12000 // Default is 5000. Activate it for some LG air conditioner protocols -//#define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM. -//#define USE_NO_SEND_PWM // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition - -// MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, -// to compensate for the signal forming of different IR receiver modules. See also IRremote.hpp line 142. -#define MARK_EXCESS_MICROS 20 // Adapt it to your IR receiver module. 20 is recommended for the cheap VS1838 modules. - -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. - -#include <IRremote.hpp> - -int SEND_BUTTON_PIN = APPLICATION_PIN; - -int DELAY_BETWEEN_REPEAT = 50; - -// Storage for the recorded code -struct storedIRDataStruct { - IRData receivedIRData; - // extensions for sendRaw - uint8_t rawCode[RAW_BUFFER_LENGTH]; // The durations if raw - uint8_t rawCodeLength; // The length of the code -} sStoredIRData; - -bool sSendButtonWasActive; - -void storeCode(); -void sendCode(storedIRDataStruct *aIRDataToSend); - -void setup() { - pinMode(SEND_BUTTON_PIN, INPUT_PULLUP); - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); - - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin - Serial.print(F("Ready to send IR signals at pin " STR(IR_SEND_PIN) " on press of button at pin ")); - Serial.println(SEND_BUTTON_PIN); -} - -void loop() { - - // If button pressed, send the code. - bool tSendButtonIsActive = (digitalRead(SEND_BUTTON_PIN) == LOW); // Button pin is active LOW - - /* - * Check for current button state - */ - if (tSendButtonIsActive) { - if (!sSendButtonWasActive) { - Serial.println(F("Stop receiving")); - IrReceiver.stop(); - } - /* - * Button pressed -> send stored data - */ - Serial.print(F("Button pressed, now sending ")); - if (sSendButtonWasActive == tSendButtonIsActive) { - Serial.print(F("repeat ")); - sStoredIRData.receivedIRData.flags = IRDATA_FLAGS_IS_REPEAT; - } else { - sStoredIRData.receivedIRData.flags = IRDATA_FLAGS_EMPTY; - } - Serial.flush(); // To avoid disturbing the software PWM generation by serial output interrupts - sendCode(&sStoredIRData); - delay(DELAY_BETWEEN_REPEAT); // Wait a bit between retransmissions - - } else if (sSendButtonWasActive) { - /* - * Button is just released -> activate receiving - */ - // Restart receiver - Serial.println(F("Button released -> start receiving")); - IrReceiver.start(); - - } else if (IrReceiver.decode()) { - /* - * Button is not pressed and data available -> store received data and resume - */ - storeCode(); - IrReceiver.resume(); // resume receiver - } - - sSendButtonWasActive = tSendButtonIsActive; - delay(100); -} - -// Stores the code for later playback in sStoredIRData -// Most of this code is just logging -void storeCode() { - if (IrReceiver.decodedIRData.rawDataPtr->rawlen < 4) { - Serial.print(F("Ignore data with rawlen=")); - Serial.println(IrReceiver.decodedIRData.rawDataPtr->rawlen); - return; - } - if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT) { - Serial.println(F("Ignore repeat")); - return; - } - if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_AUTO_REPEAT) { - Serial.println(F("Ignore autorepeat")); - return; - } - if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_PARITY_FAILED) { - Serial.println(F("Ignore parity error")); - return; - } - /* - * Copy decoded data - */ - sStoredIRData.receivedIRData = IrReceiver.decodedIRData; - - if (sStoredIRData.receivedIRData.protocol == UNKNOWN) { - Serial.print(F("Received unknown code and store ")); - Serial.print(IrReceiver.decodedIRData.rawDataPtr->rawlen - 1); - Serial.println(F(" timing entries as raw ")); - IrReceiver.printIRResultRawFormatted(&Serial, true); // Output the results in RAW format - sStoredIRData.rawCodeLength = IrReceiver.decodedIRData.rawDataPtr->rawlen - 1; - /* - * Store the current raw data in a dedicated array for later usage - */ - IrReceiver.compensateAndStoreIRResultInArray(sStoredIRData.rawCode); - } else { - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); - sStoredIRData.receivedIRData.flags = 0; // clear flags -esp. repeat- for later sending - Serial.println(); - } -} - -void sendCode(storedIRDataStruct *aIRDataToSend) { - if (aIRDataToSend->receivedIRData.protocol == UNKNOWN /* i.e. raw */) { - // Assume 38 KHz - IrSender.sendRaw(aIRDataToSend->rawCode, aIRDataToSend->rawCodeLength, 38); - - Serial.print(F("raw ")); - Serial.print(aIRDataToSend->rawCodeLength); - Serial.println(F(" marks or spaces")); - } else { - - /* - * Use the write function, which does the switch for different protocols - */ - IrSender.write(&aIRDataToSend->receivedIRData); - printIRResultShort(&Serial, &aIRDataToSend->receivedIRData, false); - } -} - diff --git a/IRremote/examples/ReceiveAndSendDistanceWidth/PinDefinitionsAndMore.h b/IRremote/examples/ReceiveAndSendDistanceWidth/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveAndSendDistanceWidth/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/ReceiveAndSendDistanceWidth/ReceiveAndSendDistanceWidth.ino b/IRremote/examples/ReceiveAndSendDistanceWidth/ReceiveAndSendDistanceWidth.ino deleted file mode 100644 index 5c2e73556da2e2ddd903896c72f0154edc5695bd..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveAndSendDistanceWidth/ReceiveAndSendDistanceWidth.ino +++ /dev/null @@ -1,184 +0,0 @@ -/* - * ReceiveAndSendDistanceWidth.cpp - * - * Record and play back last received distance width IR signal at button press. - * Using DistanceWidthProtocol covers a lot of known and unknown IR protocols, - * and requires less memory than raw protocol. - * - * The logic is: - * If the button is pressed, send the IR code. - * If an IR code is received, record it. - * - * An example for simultaneous receiving and sending is in the UnitTest example. - * - * An IR detector/demodulator must be connected to the input IR_RECEIVE_PIN. - * - * A button must be connected between the input SEND_BUTTON_PIN and ground. - * A visible LED can be connected to STATUS_PIN to provide status. - * - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -#if !defined(IR_SEND_PIN) -#define IR_SEND_PIN 3 -#endif - -/* - * Specify DistanceWidthProtocol for decoding. This must be done before the #include <IRremote.hpp> - */ -#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols -// -#if !defined(RAW_BUFFER_LENGTH) -# if RAMEND <= 0x4FF || RAMSIZE < 0x4FF -#define RAW_BUFFER_LENGTH 120 -# elif RAMEND <= 0xAFF || RAMSIZE < 0xAFF // 0xAFF for LEONARDO -#define RAW_BUFFER_LENGTH 400 // 600 is too much here, because we have additional uint8_t rawCode[RAW_BUFFER_LENGTH]; -# else -#define RAW_BUFFER_LENGTH 750 -# endif -#endif - -//#define NO_LED_FEEDBACK_CODE // saves 92 bytes program memory -//#define RECORD_GAP_MICROS 12000 // Default is 5000. Activate it for some LG air conditioner protocols -//#define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM. -//#define USE_NO_SEND_PWM // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition - -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. - -#include <IRremote.hpp> - -#define SEND_BUTTON_PIN APPLICATION_PIN - -#define DELAY_BETWEEN_REPEATS_MILLIS 70 - -// Storage for the recorded code, pre-filled with NEC data -IRRawDataType sDecodedRawDataArray[RAW_DATA_ARRAY_SIZE] = { 0x7B34ED12 }; // address 0x12 command 0x34 -DistanceWidthTimingInfoStruct sDistanceWidthTimingInfo = { 9000, 4500, 560, 1690, 560, 560 }; // NEC timing -uint8_t sNumberOfBits = 32; - -bool sSendButtonWasActive; - -void setup() { - pinMode(SEND_BUTTON_PIN, INPUT_PULLUP); - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - Serial.println(F("Ready to receive pulse distance/width coded IR signals at pin " STR(IR_RECEIVE_PIN))); - - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin - Serial.print(F("Ready to send IR signals at pin " STR(IR_SEND_PIN) " on press of button at pin ")); - Serial.println(SEND_BUTTON_PIN); -} - -void loop() { - - // If button pressed, send the code. - bool tSendButtonIsActive = (digitalRead(SEND_BUTTON_PIN) == LOW); // Button pin is active LOW - - /* - * Check for current button state - */ - if (tSendButtonIsActive) { - if (!sSendButtonWasActive) { - Serial.println(F("Stop receiving")); - IrReceiver.stop(); - } - /* - * Button pressed -> send stored data - */ - Serial.print(F("Button pressed, now sending ")); - Serial.print(sNumberOfBits); - Serial.print(F(" bits 0x")); - Serial.print(sDecodedRawDataArray[0], HEX); - Serial.print(F(" with sendPulseDistanceWidthFromArray timing=")); - IrReceiver.printDistanceWidthTimingInfo(&Serial, &sDistanceWidthTimingInfo); - Serial.println(); - Serial.flush(); // To avoid disturbing the software PWM generation by serial output interrupts - - IrSender.sendPulseDistanceWidthFromArray(38, &sDistanceWidthTimingInfo, &sDecodedRawDataArray[0], sNumberOfBits, -#if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER) - PROTOCOL_IS_MSB_FIRST -#else - PROTOCOL_IS_LSB_FIRST -#endif - , 100, 0); - - delay(DELAY_BETWEEN_REPEATS_MILLIS); // Wait a bit between retransmissions - - } else if (sSendButtonWasActive) { - /* - * Button is just released -> activate receiving - */ - // Restart receiver - Serial.println(F("Button released -> start receiving")); - IrReceiver.start(); - - } else if (IrReceiver.decode()) { - /* - * Button is not pressed and data available -> store received data and resume - * DistanceWidthTimingInfo and sNumberOfBits should be constant for all keys of the same IR remote / protocol - */ - IrReceiver.printIRResultShort(&Serial); - if (IrReceiver.decodedIRData.protocol != UNKNOWN) { - IrReceiver.printIRSendUsage(&Serial); - - if (memcmp(&sDistanceWidthTimingInfo, &IrReceiver.decodedIRData.DistanceWidthTimingInfo, - sizeof(sDistanceWidthTimingInfo)) != 0) { - Serial.print(F("Store new timing info data=")); - IrReceiver.printDistanceWidthTimingInfo(&Serial, &IrReceiver.decodedIRData.DistanceWidthTimingInfo); - Serial.println(); - sDistanceWidthTimingInfo = IrReceiver.decodedIRData.DistanceWidthTimingInfo; // copy content here - } else { - Serial.print(F("Timing did not change, so we can reuse already stored timing info.")); - } - if (sNumberOfBits != IrReceiver.decodedIRData.numberOfBits) { - Serial.print(F("Store new numberOfBits=")); - sNumberOfBits = IrReceiver.decodedIRData.numberOfBits; - Serial.println(IrReceiver.decodedIRData.numberOfBits); - } - if (sDecodedRawDataArray[0] != IrReceiver.decodedIRData.decodedRawDataArray[0]) { - *sDecodedRawDataArray = *IrReceiver.decodedIRData.decodedRawDataArray; // copy content here - Serial.print(F("Store new sDecodedRawDataArray[0]=0x")); - Serial.println(IrReceiver.decodedIRData.decodedRawDataArray[0], HEX); - } - } - IrReceiver.resume(); // resume receiver - } - - sSendButtonWasActive = tSendButtonIsActive; - delay(100); -} diff --git a/IRremote/examples/ReceiveDemo/IRremote_SendDemo_ReceiveDemo.log b/IRremote/examples/ReceiveDemo/IRremote_SendDemo_ReceiveDemo.log deleted file mode 100644 index d56a9481fc94cb187648b2523f5960c108405415..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveDemo/IRremote_SendDemo_ReceiveDemo.log +++ /dev/null @@ -1,178 +0,0 @@ -START ../src/ReceiveDemo.cpp from Feb 24 2023 -Using library version 4.1.0 -Enabling IRin... -Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, Panasonic/Kaseikyo, Denon/Sharp, Sony, RC5, RC6, LG, JVC, Samsung, FAST, Whynter, Lego Power Functions, Bosewave , MagiQuest, Universal Pulse Distance Width, Hash at pin 2 - -If you connect debug pin 5 to ground, raw data is always printed -5000 us is the (minimum) gap, after which the start of a new IR packet is assumed -20 us are subtracted from all marks and added to all spaces for decoding - -Protocol=NEC Address=0x2 Command=0x34 Raw-Data=0xCB34FD02 32 bits LSB first -Send with: IrSender.sendNEC(0x2, 0x34, <numberOfRepeats>); - -Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendNEC(0x102, 0x34, <numberOfRepeats>); - -Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendNEC(0x102, 0x34, <numberOfRepeats>); - -Protocol=NEC Address=0x80 Command=0x45 Raw-Data=0xBA457F80 32 bits LSB first -Send with: IrSender.sendNEC(0x80, 0x45, <numberOfRepeats>); - -Protocol=NEC Address=0x4 Command=0x8 Raw-Data=0xF708FB04 32 bits LSB first -Send with: IrSender.sendNEC(0x4, 0x8, <numberOfRepeats>); - -Protocol=Onkyo Address=0x102 Command=0x304 Raw-Data=0x3040102 32 bits LSB first -Send with: IrSender.sendOnkyo(0x102, 0x304, <numberOfRepeats>); - -Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendNEC(0x102, 0x34, <numberOfRepeats>); - -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); - -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); - -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); - -Protocol=PulseDistance Raw-Data=0x5A 72 bits LSB first -Send with: - uint32_t tRawData[]={0x87654321, 0xAFEDCBA9, 0x5A}; - IrSender.sendPulseDistanceWidthFromArray(38, 8850, 4400, 550, 1700, 550, 600, &tRawData[0], 72, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); - -Protocol=PulseWidth Raw-Data=0xDCBA9 52 bits LSB first -Send with: - uint32_t tRawData[]={0x87654321, 0xDCBA9}; - IrSender.sendPulseDistanceWidthFromArray(38, 300, 600, 600, 300, 350, 600, &tRawData[0], 52, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); - -Protocol=PulseWidth Raw-Data=0x87654321 32 bits LSB first -Send with: IrSender.sendPulseDistanceWidth(38, 1000, 500, 600, 300, 350, 300, 0x87654321, 32, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); - -Protocol=Onkyo Address=0x102 Command=0x5634 Raw-Data=0x56340102 32 bits LSB first -Send with: IrSender.sendOnkyo(0x102, 0x5634, <numberOfRepeats>); - -Protocol=Apple Address=0x2 Command=0x34 Raw-Data=0x23487EE 32 bits LSB first -Send with: IrSender.sendApple(0x2, 0x34, <numberOfRepeats>); - -Protocol=Panasonic Address=0x102 Command=0x34 Raw-Data=0x4341020 48 bits LSB first -Send with: IrSender.sendPanasonic(0x102, 0x34, <numberOfRepeats>); - -Protocol=Kaseikyo Address=0x102 Command=0x34 Extra=0x4711 Raw-Data=0x7341023 48 bits LSB first -Send with: IrSender.sendKaseikyo(0x102, 0x34, <numberOfRepeats>, 0x4711); - -Protocol=Kaseikyo_Denon Address=0x102 Command=0x34 Raw-Data=0x4341020 48 bits LSB first -Send with: IrSender.sendKaseikyo_Denon(0x102, 0x34, <numberOfRepeats>); - -Protocol=Denon Address=0x2 Command=0x34 Raw-Data=0x682 15 bits LSB first -Send with: IrSender.sendDenon(0x2, 0x34, <numberOfRepeats>); - -Protocol=Denon Address=0x2 Command=0x34 Auto-Repeat gap=45650us Raw-Data=0x7962 15 bits LSB first - -Protocol=Sharp Address=0x2 Command=0x34 Raw-Data=0x4682 15 bits LSB first -Send with: IrSender.sendSharp(0x2, 0x34, <numberOfRepeats>); - -Protocol=Sharp Address=0x2 Command=0x34 Auto-Repeat gap=46400us Raw-Data=0x3962 15 bits LSB first - -Protocol=Sony Address=0x2 Command=0x34 Raw-Data=0x134 12 bits LSB first -Send with: IrSender.sendSony(0x2, 0x34, 2, 12); - -Protocol=Sony Address=0x2 Command=0x34 Raw-Data=0x134 15 bits LSB first -Send with: IrSender.sendSony(0x2, 0x34, 2, 15); - -Protocol=Sony Address=0x102 Command=0x34 Raw-Data=0x8134 20 bits LSB first -Send with: IrSender.sendSony(0x102, 0x34, 2, 20); - -Protocol=Samsung Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendSamsung(0x102, 0x34, <numberOfRepeats>); - -Protocol=Samsung Address=0x102 Command=0x5634 Raw-Data=0x56340102 32 bits LSB first -Send with: IrSender.sendSamsung(0x102, 0x5634, <numberOfRepeats>); - -Protocol=Samsung48 Address=0x102 Command=0x5634 Raw-Data=0xA956 48 bits LSB first -Send with: IrSender.sendSamsung48(0x102, 0x5634, <numberOfRepeats>); - -Protocol=RC5 Address=0x2 Command=0x34 Raw-Data=0x10B4 13 bits MSB first -Send with: IrSender.sendRC5(0x2, 0x34, <numberOfRepeats>); - -Protocol=RC5 Address=0x2 Command=0x74 Toggle=1 Raw-Data=0x8B4 13 bits MSB first -Send with: IrSender.sendRC5(0x2, 0x74, <numberOfRepeats>); - -Protocol=RC6 Address=0x2 Command=0x34 Raw-Data=0x234 20 bits MSB first -Send with: IrSender.sendRC6(0x2, 0x34, <numberOfRepeats>); - -Protocol=Samsung Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendSamsung(0x102, 0x34, <numberOfRepeats>); - -Protocol=JVC Address=0x2 Command=0x34 Raw-Data=0x3402 16 bits LSB first -Send with: IrSender.sendJVC(0x2, 0x34, <numberOfRepeats>); - -Protocol=Samsung Address=0x102 Command=0x5634 Raw-Data=0x56340102 32 bits LSB first -Send with: IrSender.sendSamsung(0x102, 0x5634, <numberOfRepeats>); - -Protocol=LG Address=0x2 Command=0x5634 Raw-Data=0x256342 28 bits MSB first -Send with: IrSender.sendLG(0x2, 0x5634, <numberOfRepeats>); - -Protocol=MagiQuest Address=0x102 Command=0x34 Raw-Data=0x6BCD0102 56 bits MSB first -Send with: IrSender.sendMagiQuest(0x6BCD0102, 0x34, <numberOfRepeats>); - -Protocol=BoseWave Address=0x0 Command=0x34 Raw-Data=0xCB34 16 bits LSB first -Send with: IrSender.sendBoseWave(0x0, 0x34, <numberOfRepeats>); - -Protocol=FAST Address=0x0 Command=0x34 Raw-Data=0xCB34 16 bits LSB first -Send with: IrSender.sendFAST(0x0, 0x34, <numberOfRepeats>); - -Protocol=Lego Address=0x2 Command=0x14 Raw-Data=0x2148 16 bits MSB first -Send with: IrSender.sendLego(0x2, 0x14, <numberOfRepeats>); - -Protocol=Lego Address=0x2 Command=0x14 Auto-Repeat gap=180450us Raw-Data=0x2148 16 bits MSB first - -Protocol=Lego Address=0x2 Command=0x14 Auto-Repeat gap=179350us Raw-Data=0x2148 16 bits MSB first - -Protocol=Lego Address=0x2 Command=0x14 Auto-Repeat gap=179200us Raw-Data=0x2148 16 bits MSB first - -Protocol=Lego Address=0x2 Command=0x14 Auto-Repeat gap=179150us Raw-Data=0x2148 16 bits MSB first - -Overflow detected -Try to increase the "RAW_BUFFER_LENGTH" value of 600 in ../src/ReceiveDemo.cpp - -Protocol=NEC Address=0x3 Command=0x45 Raw-Data=0xBA45FC03 32 bits LSB first -Send with: IrSender.sendNEC(0x3, 0x45, <numberOfRepeats>); - -Protocol=NEC Address=0x3 Command=0x45 Repeat gap=43250us - -Protocol=NEC Address=0x203 Command=0x45 Raw-Data=0xBA450203 32 bits LSB first -Send with: IrSender.sendNEC(0x203, 0x45, <numberOfRepeats>); - -Protocol=NEC Address=0x203 Command=0x45 Repeat gap=47550us - -Protocol=NEC Address=0x203 Command=0x45 Raw-Data=0xBA450203 32 bits LSB first -Send with: IrSender.sendNEC(0x203, 0x45, <numberOfRepeats>); - -Protocol=NEC2 Address=0x203 Command=0x45 Repeat gap=46500us Raw-Data=0xBA450203 32 bits LSB first - -Protocol=Onkyo Address=0x203 Command=0x6745 Raw-Data=0x67450203 32 bits LSB first -Send with: IrSender.sendOnkyo(0x203, 0x6745, <numberOfRepeats>); - -Protocol=Onkyo Address=0x203 Command=0x6745 Repeat gap=46550us - -Protocol=Apple Address=0x3 Command=0x45 Raw-Data=0x34587EE 32 bits LSB first -Send with: IrSender.sendApple(0x3, 0x45, <numberOfRepeats>); - -Protocol=Apple Address=0x3 Command=0x45 Repeat gap=31550us - -Protocol=Panasonic Address=0x203 Command=0x45 Raw-Data=0x55452030 48 bits LSB first -Send with: IrSender.sendPanasonic(0x203, 0x45, <numberOfRepeats>); - -Protocol=Panasonic Address=0x203 Command=0x45 Repeat gap=72550us Raw-Data=0x55452030 48 bits LSB first - -Protocol=Kaseikyo Address=0x203 Command=0x45 Extra=0x4711 Raw-Data=0x56452033 48 bits LSB first -Send with: IrSender.sendKaseikyo(0x203, 0x45, <numberOfRepeats>, 0x4711); - -Protocol=Kaseikyo Address=0x203 Command=0x45 Extra=0x4711 Repeat gap=66750us Raw-Data=0x56452033 48 bits LSB first - -Protocol=Kaseikyo_Denon Address=0x203 Command=0x45 Raw-Data=0x55452030 48 bits LSB first -Send with: IrSender.sendKaseikyo_Denon(0x203, 0x45, <numberOfRepeats>); - -Protocol=Kaseikyo_Denon Address=0x203 Command=0x45 Repeat gap=68300us Raw-Data=0x55452030 48 bits LSB first \ No newline at end of file diff --git a/IRremote/examples/ReceiveDemo/PinDefinitionsAndMore.h b/IRremote/examples/ReceiveDemo/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveDemo/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/ReceiveDemo/ReceiveDemo.ino b/IRremote/examples/ReceiveDemo/ReceiveDemo.ino deleted file mode 100644 index e2659dec5f4305f3b73d774bca1eab3d090b9eab..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveDemo/ReceiveDemo.ino +++ /dev/null @@ -1,312 +0,0 @@ -/* - * ReceiveDemo.cpp - * - * Demonstrates receiving IR codes with the IRremote library and the use of the Arduino tone() function with this library. - * Long press of one IR button (receiving of multiple repeats for one command) is detected. - * If debug button is pressed (pin connected to ground) a long output is generated. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -//#define LOCAL_DEBUG // If defined, print timing for each received data set (the same as if DEBUG_BUTTON_PIN was connected to low) - -/* - * Specify which protocol(s) should be used for decoding. - * If no protocol is defined, all protocols (except Bang&Olufsen) are active. - * This must be done before the #include <IRremote.hpp> - */ -//#define DECODE_DENON // Includes Sharp -//#define DECODE_JVC -//#define DECODE_KASEIKYO -//#define DECODE_PANASONIC // alias for DECODE_KASEIKYO -//#define DECODE_LG -//#define DECODE_ONKYO // Decodes only Onkyo and not NEC or Apple -//#define DECODE_NEC // Includes Apple and Onkyo -//#define DECODE_SAMSUNG -//#define DECODE_SONY -//#define DECODE_RC5 -//#define DECODE_RC6 - -//#define DECODE_BOSEWAVE -//#define DECODE_LEGO_PF -//#define DECODE_MAGIQUEST -//#define DECODE_WHYNTER -//#define DECODE_FAST - -//#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols -//#define DECODE_HASH // special decoder for all protocols - -//#define DECODE_BEO // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined. It prevents decoding of SONY! - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc. -// !!! Enabling B&O disables detection of Sony, because the repeat gap for SONY is smaller than the B&O frame gap :-( !!! -//#define DECODE_BEO // Bang & Olufsen protocol always must be enabled explicitly. It has an IR transmit frequency of 455 kHz! It prevents decoding of SONY! -#endif -#if defined(DECODE_BEO) -#define RECORD_GAP_MICROS 16000 // always get the complete frame in the receive buffer, but this prevents decoding of SONY! -#endif -// etc. see IRremote.hpp -// - -#if !defined(RAW_BUFFER_LENGTH) -# if RAMEND <= 0x4FF || RAMSIZE < 0x4FF -#define RAW_BUFFER_LENGTH 130 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -#define EXCLUDE_EXOTIC_PROTOCOLS // saves around 650 bytes program memory if all other protocols are active -#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. -# elif RAMEND <= 0x8FF || RAMSIZE < 0x8FF -#define RAW_BUFFER_LENGTH 600 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# else -#define RAW_BUFFER_LENGTH 750 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# endif -#endif - -//#define NO_LED_FEEDBACK_CODE // saves 92 bytes program memory -//#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. -//#define EXCLUDE_EXOTIC_PROTOCOLS // saves around 650 bytes program memory if all other protocols are active - -// MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, -// to compensate for the signal forming of different IR receiver modules. See also IRremote.hpp line 142. -//#define MARK_EXCESS_MICROS 20 // Adapt it to your IR receiver module. 40 is taken for the cheap VS1838 module her, since we have high intensity. - -//#define RECORD_GAP_MICROS 12000 // Default is 5000. Activate it for some LG air conditioner protocols - -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. - -#include <IRremote.hpp> - -#if defined(APPLICATION_PIN) -#define DEBUG_BUTTON_PIN APPLICATION_PIN // if low, print timing for each received data set -#else -#define DEBUG_BUTTON_PIN 6 -#endif - -bool detectLongPress(uint16_t aLongPressDurationMillis); - -void setup() { -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc. - pinMode(DEBUG_BUTTON_PIN, INPUT_PULLUP); -#endif - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif -// Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - -// In case the interrupt driver crashes on setup, give a clue -// to the user what's going on. - Serial.println(F("Enabling IRin...")); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); -#if defined(IR_RECEIVE_PIN_STRING) - Serial.println(F("at pin " IR_RECEIVE_PIN_STRING)); -#else - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); -#endif - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc. - Serial.println(); - Serial.print(F("If you connect debug pin ")); -# if defined(APPLICATION_PIN_STRING) - Serial.print(APPLICATION_PIN_STRING); -# else - Serial.print(DEBUG_BUTTON_PIN); -# endif - Serial.println(F(" to ground, raw data is always printed")); - - // infos for receive - Serial.print(RECORD_GAP_MICROS); - Serial.println(F(" us is the (minimum) gap, after which the start of a new IR packet is assumed")); - Serial.print(MARK_EXCESS_MICROS); - Serial.println(F(" us are subtracted from all marks and added to all spaces for decoding")); -#endif - -} - -void loop() { - /* - * Check if received data is available and if yes, try to decode it. - * Decoded result is in the IrReceiver.decodedIRData structure. - * - * E.g. command is in IrReceiver.decodedIRData.command - * address is in command is in IrReceiver.decodedIRData.address - * and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData - * - * At 115200 baud, printing takes 40 ms for NEC protocol and 10 ms for NEC repeat - */ - if (IrReceiver.decode()) { - Serial.println(); -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_WAS_OVERFLOW) { - Serial.println(F("Overflow detected")); - Serial.println(F("Try to increase the \"RAW_BUFFER_LENGTH\" value of " STR(RAW_BUFFER_LENGTH) " in " __FILE__)); - // see also https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library -# if !defined(ESP8266) && !defined(NRF5) - /* - * do double beep - */ -# if !defined(ESP32) - IrReceiver.stop(); // ESP32 uses another timer for tone() -# endif - tone(TONE_PIN, 1100, 10); - delay(50); - tone(TONE_PIN, 1100, 10); - delay(50); -# if !defined(ESP32) - IrReceiver.start(100000); // to compensate for 100 ms stop of receiver. This enables a correct gap measurement. -# endif -# endif - - } else { - auto tStartMillis = millis(); -# if !defined(ESP32) - IrReceiver.stop(); // ESP32 uses another timer for tone() -# endif - tone(TONE_PIN, 2200); - - // No overflow, print a short summary of received data -# if defined(LOCAL_DEBUG) - IrReceiver.printIRResultShort(&Serial, true); -# else - IrReceiver.printIRResultShort(&Serial, true, digitalRead(DEBUG_BUTTON_PIN) == LOW); -# endif - // Guarantee at least 5 millis for tone. decode starts 5 millis (RECORD_GAP_MICROS) after end of frame - // so here we are 10 millis after end of frame. Sony20 has only a 12 ms repeat gap. - while ((millis() - tStartMillis) < 5) - ; - noTone(TONE_PIN); - -# if !defined(ESP32) - // Restore IR timer. millis() - tStartMillis to compensate for stop of receiver. This enables a correct gap measurement. - IrReceiver.startWithTicksToAdd((millis() - tStartMillis) * (MICROS_IN_ONE_MILLI / MICROS_PER_TICK)); -# endif - - IrReceiver.printIRSendUsage(&Serial); -# if defined(LOCAL_DEBUG) - IrReceiver.printIRResultRawFormatted(&Serial, true); -# else - if (IrReceiver.decodedIRData.protocol == UNKNOWN || digitalRead(DEBUG_BUTTON_PIN) == LOW) { - // We have an unknown protocol, print more info - if (IrReceiver.decodedIRData.protocol == UNKNOWN) { - Serial.println(F("Received noise or an unknown (or not yet enabled) protocol")); - } - IrReceiver.printIRResultRawFormatted(&Serial, true); - } -# endif - } - - // tone on esp8266 works once, then it disables the successful IrReceiver.start() / timerConfigForReceive(). -# if !defined(ESP8266) && !defined(NRF5) && !defined(LOCAL_DEBUG) - if ((IrReceiver.decodedIRData.protocol != SONY) && (IrReceiver.decodedIRData.protocol != PULSE_WIDTH) - && (IrReceiver.decodedIRData.protocol != PULSE_DISTANCE) && (IrReceiver.decodedIRData.protocol != UNKNOWN) - && digitalRead(DEBUG_BUTTON_PIN) != LOW) { - /* - * If no debug mode or a valid protocol was received, play tone, wait and restore IR timer. - * For SONY the tone prevents the detection of a repeat - * Otherwise do not play a tone to get exact gap time between transmissions and not running into repeat frames while wait for tone to end. - * This will give the next CheckForRecordGapsMicros() call a chance to eventually propose a change of the current RECORD_GAP_MICROS value. - */ -# if !defined(ESP32) - IrReceiver.stop(); // ESP32 uses another timer for tone() -# endif - tone(TONE_PIN, 2200, 8); -# if !defined(ESP32) - delay(8); - IrReceiver.start(8000); // Restore IR timer. 8000 to compensate for 8 ms stop of receiver. This enables a correct gap measurement. -# endif - } -# endif -#else // #if FLASHEND >= 0x3FFF - // Print a minimal summary of received data - IrReceiver.printIRResultMinimal(&Serial); -#endif // #if FLASHEND >= 0x3FFF - - /* - * !!!Important!!! Enable receiving of the next value, - * since receiving has stopped after the end of the current received data packet. - */ - IrReceiver.resume(); - - /* - * Finally check the received data and perform actions according to the received address and commands - */ - if (IrReceiver.decodedIRData.address == 0) { - if (IrReceiver.decodedIRData.command == 0x10) { - // do something - } else if (IrReceiver.decodedIRData.command == 0x11) { - // do something else - } - } - - // Check if the command was repeated for more than 1000 ms - if (detectLongPress(1000)) { - Serial.print(F("Command 0x")); - Serial.print(IrReceiver.decodedIRData.command, HEX); - Serial.println(F(" was repeated for more than 2 seconds")); - } - } // if (IrReceiver.decode()) - - /* - * Your code here - * For all users of the FastLed library, use this code for strip.show() to improve receiving performance (which is still not 100%): - * if (IrReceiver.isIdle()) { - * strip.show(); - * } - */ - -} - -unsigned long sMillisOfFirstReceive; -bool sLongPressJustDetected; -/** - * @return true once after the repeated command was received for longer than aLongPressDurationMillis milliseconds, false otherwise. - */ -bool detectLongPress(uint16_t aLongPressDurationMillis) { - if (!sLongPressJustDetected && (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) { - /* - * Here the repeat flag is set (which implies, that command is the same as the previous one) - */ - if (millis() - aLongPressDurationMillis > sMillisOfFirstReceive) { - sLongPressJustDetected = true; // Long press here - } - } else { - // No repeat here - sMillisOfFirstReceive = millis(); - sLongPressJustDetected = false; - } - return sLongPressJustDetected; // No long press here -} - diff --git a/IRremote/examples/ReceiveDump/PinDefinitionsAndMore.h b/IRremote/examples/ReceiveDump/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveDump/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/ReceiveDump/ReceiveDump.ino b/IRremote/examples/ReceiveDump/ReceiveDump.ino deleted file mode 100644 index 23b9b57592cde13f706e3c38154d4c920c71e68a..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveDump/ReceiveDump.ino +++ /dev/null @@ -1,149 +0,0 @@ -/* - * ReceiveDump.cpp - * - * Dumps the received signal in different flavors. - * Since the printing takes so much time (200 ms @115200 for NEC protocol, 70ms for NEC repeat), - * repeat signals may be skipped or interpreted as UNKNOWN. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -#if !defined(RAW_BUFFER_LENGTH) -# if RAMEND <= 0x4FF || RAMSIZE < 0x4FF -#define RAW_BUFFER_LENGTH 180 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# elif RAMEND <= 0x8FF || RAMSIZE < 0x8FF -#define RAW_BUFFER_LENGTH 600 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# else -#define RAW_BUFFER_LENGTH 750 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# endif -#endif - -/* - * MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, - * to compensate for the signal forming of different IR receiver modules. See also IRremote.hpp line 142. - * - * You can change this value accordingly to the receiver module you use. - * The required value can be derived from the timings printed here. - * Keep in mind that the timings may change with the distance - * between sender and receiver as well as with the ambient light intensity. - */ -#define MARK_EXCESS_MICROS 20 // Adapt it to your IR receiver module. 20 is recommended for the cheap VS1838 modules. - -//#define RECORD_GAP_MICROS 12000 // Default is 5000. Activate it for some LG air conditioner protocols -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. - -#include <IRremote.hpp> - -//+============================================================================= -// Configure the Arduino -// -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - - Serial.begin(115200); // Status message will be sent to PC at 9600 baud -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); - - // infos for receive - Serial.print(RECORD_GAP_MICROS); - Serial.println(F(" us is the (minimum) gap, after which the start of a new IR packet is assumed")); - Serial.print(MARK_EXCESS_MICROS); - Serial.println(); - Serial.println(F("Because of the verbose output (>200 ms at 115200), repeats are probably not dumped correctly!")); - Serial.println(); -} - -//+============================================================================= -// The repeating section of the code -// -void loop() { - if (IrReceiver.decode()) { // Grab an IR code - // At 115200 baud, printing takes 200 ms for NEC protocol and 70 ms for NEC repeat - Serial.println(); // blank line between entries - Serial.println(); // 2 blank lines between entries - IrReceiver.printIRResultShort(&Serial); - // Check if the buffer overflowed - if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_WAS_OVERFLOW) { - Serial.println(F("Try to increase the \"RAW_BUFFER_LENGTH\" value of " STR(RAW_BUFFER_LENGTH) " in " __FILE__)); - // see also https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library - } else { - if (IrReceiver.decodedIRData.protocol == UNKNOWN) { - Serial.println(F("Received noise or an unknown (or not yet enabled) protocol")); - } - Serial.println(); - IrReceiver.printIRSendUsage(&Serial); - Serial.println(); - Serial.println(F("Raw result in internal ticks (50 us) - with leading gap")); - IrReceiver.printIRResultRawFormatted(&Serial, false); // Output the results in RAW format - Serial.println(F("Raw result in microseconds - with leading gap")); - IrReceiver.printIRResultRawFormatted(&Serial, true); // Output the results in RAW format - Serial.println(); // blank line between entries - Serial.print(F("Result as internal 8bit ticks (50 us) array - compensated with MARK_EXCESS_MICROS=")); - Serial.println(MARK_EXCESS_MICROS); - IrReceiver.compensateAndPrintIRResultAsCArray(&Serial, false); // Output the results as uint8_t source code array of ticks - Serial.print(F("Result as microseconds array - compensated with MARK_EXCESS_MICROS=")); - Serial.println(MARK_EXCESS_MICROS); - IrReceiver.compensateAndPrintIRResultAsCArray(&Serial, true); // Output the results as uint16_t source code array of micros - IrReceiver.printIRResultAsCVariables(&Serial); // Output address and data as source code variables - - IrReceiver.compensateAndPrintIRResultAsPronto(&Serial); - - /* - * Example for using the compensateAndStorePronto() function. - * Creating this String requires 2210 bytes program memory and 10 bytes RAM for the String class. - * The String object itself requires additional 440 bytes RAM from the heap. - * This values are for an Arduino Uno. - */ -// Serial.println(); // blank line between entries -// String ProntoHEX = F("Pronto HEX contains: "); // Assign string to ProtoHex string object -// if (int size = IrReceiver.compensateAndStorePronto(&ProntoHEX)) { // Dump the content of the IReceiver Pronto HEX to the String object -// // Append compensateAndStorePronto() size information to the String object (requires 50 bytes heap) -// ProntoHEX += F("\r\nProntoHEX is "); // Add codes size information to the String object -// ProntoHEX += size; -// ProntoHEX += F(" characters long and contains "); // Add codes count information to the String object -// ProntoHEX += size / 5; -// ProntoHEX += F(" codes"); -// Serial.println(ProntoHEX.c_str()); // Print to the serial console the whole String object -// Serial.println(); // blank line between entries -// } - } - IrReceiver.resume(); // Prepare for the next value - } -} diff --git a/IRremote/examples/ReceiveDump/ReceiveDump.log b/IRremote/examples/ReceiveDump/ReceiveDump.log deleted file mode 100644 index ae16f33e9220e73d556cff350a54fac9a7366706..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveDump/ReceiveDump.log +++ /dev/null @@ -1,52 +0,0 @@ -START ../src/ReceiveDump.cpp from Nov 12 2022 -Using library version 4.0.0 -Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, Panasonic/Kaseikyo, Denon/Sharp, Sony, RC5, RC6, LG, JVC, Samsung, Whynter, Lego Power Functions, Bosewave , MagiQuest, Universal Pulse Distance Width, Hash at pin 2 -5000 us is the (minimum) gap, after which the start of a new IR packet is assumed -20 us are subtracted from all marks and added to all spaces for decoding - - -Protocol=Samsung Address=0x707 Command=0x4 Raw-Data=0xFB040707 32 bits LSB first - -Send with: IrSender.sendSamsung(0x707, 0x4, <numberOfRepeats>); - -Raw result in internal ticks (50 us) - with leading gap -rawData[68]: - -27948 - +90,-84 - +12,-32 +12,-32 +12,-32 +12,-11 - +11,-11 +11,-11 +11,-11 +11,-11 - +12,-32 +12,-32 +12,-32 +12,-10 - +12,-10 +12,-10 +12,-10 +12,-11 - +11,-11 +11,-11 +11,-33 +11,-11 - +11,-11 +11,-11 +11,-11 +11,-11 - +12,-32 +12,-32 +12,-10 +12,-32 - +12,-32 +12,-32 +12,-32 +12,-32 - +12 -Sum: 1200 -Raw result in microseconds - with leading gap -rawData[68]: - -1397400 - +4500,-4200 - + 600,-1600 + 600,-1600 + 600,-1600 + 600,- 550 - + 550,- 550 + 550,- 550 + 550,- 550 + 550,- 550 - + 600,-1600 + 600,-1600 + 600,-1600 + 600,- 500 - + 600,- 500 + 600,- 500 + 600,- 500 + 600,- 550 - + 550,- 550 + 550,- 550 + 550,-1650 + 550,- 550 - + 550,- 550 + 550,- 550 + 550,- 550 + 550,- 550 - + 600,-1600 + 600,-1600 + 600,- 500 + 600,-1600 - + 600,-1600 + 600,-1600 + 600,-1600 + 600,-1600 - + 600 -Sum: 60000 - -Result as internal ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20 -uint8_t rawTicks[67] = {90,84, 12,32, 12,32, 12,32, 12,11, 11,11, 11,11, 11,11, 11,11, 12,32, 12,32, 12,32, 12,10, 12,10, 12,10, 12,10, 12,11, 11,11, 11,11, 11,33, 11,11, 11,11, 11,11, 11,11, 11,11, 12,32, 12,32, 12,10, 12,32, 12,32, 12,32, 12,32, 12,32, 12}; // Protocol=Samsung Address=0x707 Command=0x4 Raw-Data=0xFB040707 32 bits LSB first - -Result as microseconds array - compensated with MARK_EXCESS_MICROS=20 -uint16_t rawData[67] = {4480,4220, 580,1620, 580,1620, 580,1620, 580,570, 530,570, 530,570, 530,570, 530,570, 580,1620, 580,1620, 580,1620, 580,520, 580,520, 580,520, 580,520, 580,570, 530,570, 530,570, 530,1670, 530,570, 530,570, 530,570, 530,570, 530,570, 580,1620, 580,1620, 580,520, 580,1620, 580,1620, 580,1620, 580,1620, 580,1620, 580}; // Protocol=Samsung Address=0x707 Command=0x4 Raw-Data=0xFB040707 32 bits LSB first - -uint16_t address = 0x707; -uint16_t command = 0x4; -uint32_t data = 0xFB040707; - -Pronto Hex as string -char prontoData[] = "0000 006D 0022 0000 00AE 00A1 0018 003D 0018 003D 0018 003D 0018 0014 0016 0014 0016 0014 0016 0014 0016 0014 0018 003D 0018 003D 0018 003D 0018 0012 0018 0012 0018 0012 0018 0012 0018 0014 0016 0014 0016 0014 0016 003F 0016 0014 0016 0014 0016 0014 0016 0014 0016 0014 0018 003D 0018 003D 0018 0012 0018 003D 0018 003D 0018 003D 0018 003D 0018 003D 0018 06C3 "; diff --git a/IRremote/examples/ReceiveOneAndSendMultiple/PinDefinitionsAndMore.h b/IRremote/examples/ReceiveOneAndSendMultiple/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveOneAndSendMultiple/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/ReceiveOneAndSendMultiple/ReceiveOneAndSendMultiple.ino b/IRremote/examples/ReceiveOneAndSendMultiple/ReceiveOneAndSendMultiple.ino deleted file mode 100644 index 34baa144e2b10368ab94630d931d4930cf8e3a7b..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiveOneAndSendMultiple/ReceiveOneAndSendMultiple.ino +++ /dev/null @@ -1,257 +0,0 @@ -/* - * ReceiveOneAndSendMultiple.cpp - * - * Serves as a IR remote macro expander - * Receives Samsung32 protocol and on receiving a specified input frame, - * it sends multiple Samsung32 frames with appropriate delays in between. - * This serves as a Netflix-key emulation for my old Samsung H5273 TV. - * - * Tested on a digispark ATTiny85 board using AttinyCore https://github.com/SpenceKonde/ATTinyCore - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -// Digispark ATMEL ATTINY85 -// Piezo speaker must have a 270 ohm resistor in series for USB programming and running at the Samsung TV. -// IR LED has a 270 ohm resistor in series. -// +-\/-+ -// !RESET (5) PB5 1| |8 Vcc -// USB+ 3.6V Z-Diode, 1.5kOhm to VCC Piezo (3) PB3 2| |7 PB2 (2) TX Debug output -// USB- 3.6V Z-Diode IR Output (4) PB4 3| |6 PB1 (1) Feedback LED -// GND 4| |5 PB0 (0) IR Input -// +----+ -/* SAUMSUMG REMOTE CODES (Model: BN59-01180A) - * Power Button - 0x2 - * Power Off - 0x98 - * 1 - 0x4 - * 2 - 0x5 - * 3 - 0x6 - * 4 - 0x8 - * 5 - 0x9 - * 6 - 0xa - * 7 - 0xc - * 8 - 0xd - * 9 - 0xe - * CH List - 0x6b - * Vol + - 0x7 - * Vol - - 0xb - * Mute - 0xf - * Source - 0x1 - * Ch + - 0x12 - * Ch - - 0x10 - * Menu - 0x1a - * Home - 0x79 - * MagicInfo Player - 0x30 - * Tools - 0x4b - * Info - 0x1f - * Up arrow - 0x60 - * Left arrow - 0x65 - * Right arrow - 0x62 - * Down arrow - 0x61 - * Return - 0x58 - * Exit - 0x2d - * A - 0x6c - * B - 0x14 - * C - 0x15 - * D - 0x16 - * Set - 0xab - * Unset - 0xac - * Lock - 0x77 - * Stop (square) - 0x46 - * Rewind (arrows) - 0x45 - * Play (triangle) - 0x47 - * Pause (bars) - 0x4a - * Fast Forward (arrows) - 0x48 - */ - -#include <Arduino.h> - -// select only Samsung protocol for sending and receiving -#define DECODE_SAMSUNG -#define ADDRESS_OF_SAMSUNG_REMOTE 0x0707 // The value you see as address in printIRResultShort() - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -#include <IRremote.hpp> - -void sendSamsungSmartHubMacro(bool aDoSelect); -void IRSendWithDelay(uint8_t aCommand, uint16_t aDelayMillis); - -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // tone before IR setup, since it kills the IR timer settings - tone(TONE_PIN, 2200, 400); - digitalWrite(LED_BUILTIN, HIGH); - delay(400); - digitalWrite(LED_BUILTIN, LOW); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); - - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin - Serial.println(F("Ready to send IR signals at pin " STR(IR_SEND_PIN))); -} - -void loop() { - /* - * Check if new data available and get them - */ - if (IrReceiver.decode()) { - // Print a short summary of received data - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); - Serial.println(); - - /* - * Here data is available -> evaluate IR command - */ - switch (IrReceiver.decodedIRData.command) { - case 0x47: // The play key on the bottom of my Samsung remote - Serial.println(F("Play key detected, open Netflix")); - sendSamsungSmartHubMacro(true); - break; - - case 0x4A: // The pause key on the bottom of my Samsung remote - Serial.println(F("Pause key detected, open SmartHub")); - sendSamsungSmartHubMacro(false); - break; - - default: - break; - } - - /* - * !!!Important!!! Enable receiving of the next value, - * since receiving has stopped after the end of the current received data packet. - */ - IrReceiver.restartAfterSend(); // Is a NOP if sending does not require a timer. - IrReceiver.resume(); // Enable receiving of the next value - } -} - -void IRSendWithDelay(uint8_t aCommand, uint16_t aDelayMillis) { - IrSender.sendSamsung(ADDRESS_OF_SAMSUNG_REMOTE, aCommand, 1); // send with one repeat - Serial.print(F("Send Samsung command 0x")); - Serial.println(aCommand); - delay(aDelayMillis); -} - -bool sMacroWasCalledBefore = false; -#define INITIAL_WAIT_TIME_APPS_READY_MILLIS 70000 // Time to let the TV load all software before Netflix can be started without an error -#define INITIAL_WAIT_TIME_SMARTHUB_READY_MILLIS 20000 // Time to let the TV load all software before SmartHub manu can be displayed - -/* - * This macro calls the last SmartHub application you selected manually - * - * @param aDoSelect - if true select the current app (needs longer initial wait time) else show smarthub menu - * - */ -void sendSamsungSmartHubMacro(bool aDoSelect) { - uint32_t tWaitTimeAfterBoot; - if (aDoSelect) { - tWaitTimeAfterBoot = INITIAL_WAIT_TIME_APPS_READY_MILLIS; - } else { - tWaitTimeAfterBoot = INITIAL_WAIT_TIME_SMARTHUB_READY_MILLIS; - } - -# if !defined(ESP32) - IrReceiver.stop(); // ESP32 uses another timer for tone() -# endif - if (millis() < tWaitTimeAfterBoot) { - // division by 1000 and printing requires much (8%) program memory - Serial.print(F("It is ")); - Serial.print(millis() / 1000); - Serial.print(F(" seconds after boot, Samsung H5273 TV requires ")); - Serial.print(tWaitTimeAfterBoot / 1000); - Serial.println(F(" seconds after boot to be ready for the command")); - - tone(TONE_PIN, 2200, 100); - delay(200); - tone(TONE_PIN, 2200, 100); - delay(100); - - if (millis() < tWaitTimeAfterBoot) { - Serial.print(F("Now do a blocking wait for ")); - Serial.print(tWaitTimeAfterBoot - millis()); - Serial.println(F(" milliseconds")); - delay(tWaitTimeAfterBoot - millis()); - } - } - - // Do beep feedback for special key to be received - tone(TONE_PIN, 2200, 200); - delay(200); - -# if !defined(ESP32) - IrReceiver.start(200000); // to compensate for 200 ms stop of receiver. This enables a correct gap measurement. -# endif - - Serial.println(F("Wait for \"not supported\" to disappear")); - delay(2000); - - Serial.println(F("Start sending of Samsung IR macro")); - - IRSendWithDelay(0x1A, 2000); // Menu and wait for the Menu to pop up - - Serial.println(F("Wait for the menu to pop up")); - if (!sMacroWasCalledBefore) { - delay(2000); // wait additional time for the Menu load - } - - for (uint_fast8_t i = 0; i < 4; ++i) { - IRSendWithDelay(0x61, 250); // Down arrow. For my Samsung, the high byte of the command is the inverse of the low byte - } - - IRSendWithDelay(0x62, 400); // Right arrow - for (uint_fast8_t i = 0; i < 2; ++i) { - IRSendWithDelay(0x61, 250); // Down arrow - } - - delay(250); - IRSendWithDelay(0x68, 1); // Enter for SmartHub - - if (aDoSelect) { - Serial.println(F("Wait for SmartHub to show up, before entering current application")); - delay(10000); // Wait not longer than 12 seconds, because smarthub menu then disappears - IRSendWithDelay(0x68, 1); // Enter for last application (e.g. Netflix or Amazon) - } - - sMacroWasCalledBefore = true; - Serial.println(F("Done")); - -} diff --git a/IRremote/examples/ReceiverTimingAnalysis/ReceiverTimingAnalysis.ino b/IRremote/examples/ReceiverTimingAnalysis/ReceiverTimingAnalysis.ino deleted file mode 100644 index 1ee2bf92be3c9df18b1f2c300cff18f3ec7b323b..0000000000000000000000000000000000000000 --- a/IRremote/examples/ReceiverTimingAnalysis/ReceiverTimingAnalysis.ino +++ /dev/null @@ -1,260 +0,0 @@ -/* - * ReceiverTimingAnalysis.cpp - * - * This program enables the pin change interrupt at pin 3 and waits for NEC (or other Pulse-Distance-Coding) IR Signal. - * It measures the pulse and pause times of the incoming signal and computes some statistics for it. - * - * Observed values: - * Delta of each signal type is around 50 up to 100 and at low signals up to 200. TSOP is better, especially at low IR signal level. - * VS1838 Mark Excess -50 to +50 us - * TSOP31238 Mark Excess 0 to +50 - * - * - * Copyright (C) 2019-2020 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * IRMP is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -#include <Arduino.h> - -#define IR_INPUT_PIN 2 -//#define IR_INPUT_PIN 3 - -/* - * Helper macro for getting a macro definition as string - */ -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) - -void measureTimingISR(void); - -void setup() -{ - pinMode(LED_BUILTIN, OUTPUT); - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__)); - -#if defined(EICRA) && defined(EIFR) && defined(EIMSK) -# if (IR_INPUT_PIN == 2) - EICRA |= _BV(ISC00); // interrupt on any logical change - EIFR |= _BV(INTF0); // clear interrupt bit - EIMSK |= _BV(INT0); // enable interrupt on next change -# elif (IR_INPUT_PIN == 3) - EICRA |= _BV(ISC10); // enable interrupt on pin3 on both edges for ATmega328 - EIFR |= _BV(INTF1); // clear interrupt bit - EIMSK |= _BV(INT1); // enable interrupt on next change -# endif -#else - attachInterrupt(digitalPinToInterrupt(IR_INPUT_PIN), measureTimingISR, CHANGE); -#endif - Serial.println(F("Ready to analyze NEC IR signal at pin " STR(IR_INPUT_PIN))); - Serial.println(); -} - -uint8_t ISREdgeCounter = 0; -volatile uint32_t LastMicros; -struct timingStruct -{ - uint16_t minimum; - uint8_t indexOfMinimum; - uint16_t maximum; - uint8_t indexOfMaximum; - uint16_t average; - - uint16_t SumForAverage; - uint8_t SampleCount; -// uint8_t LastPrintedCount; -}; - -struct timingStruct Mark; -struct timingStruct ShortSpace; -struct timingStruct LongSpace; - -/* - * Compute minimum, maximum and average - */ -void processTmingValue(struct timingStruct *aTimingStruct, uint16_t aValue) -{ - if (aTimingStruct->SampleCount == 0) - { - // initialize values - aTimingStruct->minimum = UINT16_MAX; - aTimingStruct->maximum = 0; - aTimingStruct->SumForAverage = 0; - } - - if (aTimingStruct->minimum > aValue) - { - aTimingStruct->minimum = aValue; - aTimingStruct->indexOfMinimum = aTimingStruct->SampleCount; - } - if (aTimingStruct->maximum < aValue) - { - aTimingStruct->maximum = aValue; - aTimingStruct->indexOfMaximum = aTimingStruct->SampleCount; - } - - aTimingStruct->SampleCount++; - aTimingStruct->SumForAverage += aValue; - aTimingStruct->average = (aTimingStruct->SumForAverage + (aTimingStruct->SampleCount / 2)) / aTimingStruct->SampleCount; - -} - -void printTimingValues(struct timingStruct *aTimingStruct, const char *aCaption) -{ -// if (aTimingStruct->LastPrintedCount != aTimingStruct->SampleCount) -// { -// aTimingStruct->LastPrintedCount = aTimingStruct->SampleCount; - Serial.print(aCaption); - Serial.print(F(": SampleCount=")); - Serial.print(aTimingStruct->SampleCount); - Serial.print(F(" Minimum=")); - Serial.print(aTimingStruct->minimum); - Serial.print(F(" @")); - Serial.print(aTimingStruct->indexOfMinimum); - Serial.print(F(" Maximum=")); - Serial.print(aTimingStruct->maximum); - Serial.print(F(" @")); - Serial.print(aTimingStruct->indexOfMaximum); - Serial.print(F(" Delta=")); - Serial.print(aTimingStruct->maximum - aTimingStruct->minimum); - Serial.print(F(" Average=")); - Serial.print(aTimingStruct->average); - - Serial.println(); -// } -} - -void loop() -{ - if (Mark.SampleCount >= 32) - { - /* - * This check enables statistics for longer protocols like Kaseikyo/Panasonics - */ -#if !defined(ARDUINO_ARCH_MBED) - noInterrupts(); -#endif - uint32_t tLastMicros = LastMicros; -#if !defined(ARDUINO_ARCH_MBED) - interrupts(); -#endif - uint32_t tMicrosDelta = micros() - tLastMicros; - - if (tMicrosDelta > 10000) - { - // NEC signal ended just now - Serial.println(); - printTimingValues(&Mark, "Mark "); - printTimingValues(&ShortSpace, "ShortSpace"); - printTimingValues(&LongSpace, "LongSpace "); - - /* - * Print analysis of mark and short spaces - */ - Serial.println(F("Analysis :")); - Serial.print(F(" (Average of mark + short space)/2 = ")); - int16_t MarkAndShortSpaceAverage = (Mark.average + ShortSpace.average) / 2; - Serial.print(MarkAndShortSpaceAverage); - Serial.print(F(" us\r\n Delta (to NEC standard 560) = ")); - Serial.print(MarkAndShortSpaceAverage - 560); - Serial.print(F("us\r\n MARK_EXCESS_MICROS = (Average of mark - Average of mark and short space) = ")); - Serial.print((int16_t) Mark.average - MarkAndShortSpaceAverage); - Serial.print(F("us")); - Serial.println(); - Serial.println(); - - Mark.SampleCount = 0; // used as flag for not printing the results more than once - } - } -} - -/* - * The interrupt handler. - * Just add to the appropriate timing structure. - */ -#if defined(ESP8266) || defined(ESP32) -void IRAM_ATTR measureTimingISR() -#else -# if defined(EICRA) && defined(EIFR) && defined(EIMSK) -# if (IR_INPUT_PIN == 2) -ISR(INT0_vect) -# elif (IR_INPUT_PIN == 3) -ISR(INT1_vect) -# endif -# else -void measureTimingISR() -# endif -#endif -{ - uint32_t tMicros = micros(); - uint32_t tMicrosDelta = tMicros - LastMicros; - LastMicros = tMicros; - /* - * read level and give feedback - */ - uint8_t tInputLevel = digitalRead(IR_INPUT_PIN); - digitalWrite(LED_BUILTIN, !tInputLevel); - - if (tMicrosDelta > 10000) - { - // gap > 10 ms detected, reset counter to first detected edge and initialize timing structures - ISREdgeCounter = 1; - LongSpace.SampleCount = 0; - ShortSpace.SampleCount = 0; - Mark.SampleCount = 0; - } - else - { - ISREdgeCounter++; - } - - /* - * Skip header mark and space and first bit mark and space - */ - if (ISREdgeCounter > 4) - { - if (tInputLevel != LOW) - { - // Mark ended - processTmingValue(&Mark, tMicrosDelta); -// Serial.print('M'); - } - else - { - // Space ended - if (tMicrosDelta > 1000) - { - // long space - logical 1 - processTmingValue(&LongSpace, tMicrosDelta); - Serial.print('1'); - } - else - { - // short space - logical 0 - processTmingValue(&ShortSpace, tMicrosDelta); - Serial.print('0'); - } - } - } -} diff --git a/IRremote/examples/SendAndReceive/PinDefinitionsAndMore.h b/IRremote/examples/SendAndReceive/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendAndReceive/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SendAndReceive/SendAndReceive.ino b/IRremote/examples/SendAndReceive/SendAndReceive.ino deleted file mode 100644 index 7303c1afc6f60b83ccb074aa3a75d5980dbcccc1..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendAndReceive/SendAndReceive.ino +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SendAndReceive.cpp - * - * Demonstrates sending IR codes and receiving it simultaneously - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2021-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -#include <Arduino.h> - -// select only NEC and the universal decoder for pulse distance protocols -#define DECODE_NEC // Includes Apple and Onkyo -#define DECODE_DISTANCE_WIDTH // In case NEC is not received correctly. Universal decoder for pulse distance width protocols - -//#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. -//#define EXCLUDE_EXOTIC_PROTOCOLS // saves around 650 bytes program memory if all other protocols are active -//#define NO_LED_FEEDBACK_CODE // saves 92 bytes program memory -//#define RECORD_GAP_MICROS 12000 // Default is 5000. Activate it for some LG air conditioner protocols -//#define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM. -//#define USE_NO_SEND_PWM // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition - -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -#include <IRremote.hpp> - -#define DELAY_AFTER_SEND 2000 -#define DELAY_AFTER_LOOP 5000 - -void setup() { - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin - Serial.println(F("Send IR signals at pin " STR(IR_SEND_PIN))); - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 -// For esp32 we use PWM generation by ledcWrite() for each pin. -# if !defined(SEND_PWM_BY_TIMER) && !defined(USE_NO_SEND_PWM) && !defined(ESP32) - /* - * Print internal software PWM generation info - */ - IrSender.enableIROut(38); // Call it with 38 kHz to initialize the values printed below - Serial.print(F("Send signal mark duration is ")); - Serial.print(IrSender.periodOnTimeMicros); - Serial.print(F(" us, pulse correction is ")); - Serial.print(IrSender.getPulseCorrectionNanos()); - Serial.print(F(" ns, total period is ")); - Serial.print(IrSender.periodTimeMicros); - Serial.println(F(" us")); -# endif - - // infos for receive - Serial.print(RECORD_GAP_MICROS); - Serial.println(F(" us is the (minimum) gap, after which the start of a new IR packet is assumed")); - Serial.print(MARK_EXCESS_MICROS); - Serial.println(F(" us are subtracted from all marks and added to all spaces for decoding")); -#endif -} - -uint16_t sAddress = 0x0102; -uint8_t sCommand = 0x34; -uint8_t sRepeats = 1; - -/* - * Send NEC IR protocol - */ -void send_ir_data() { - Serial.print(F("Sending: 0x")); - Serial.print(sAddress, HEX); - Serial.print(sCommand, HEX); - Serial.println(sRepeats, HEX); - Serial.flush(); // To avoid disturbing the software PWM generation by serial output interrupts - - // clip repeats at 4 - if (sRepeats > 4) { - sRepeats = 4; - } - // Results for the first loop to: Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 (32 bits) - IrSender.sendNEC(sAddress, sCommand, sRepeats); -} - -void receive_ir_data() { - if (IrReceiver.decode()) { - Serial.print(F("Decoded protocol: ")); - Serial.print(getProtocolString(IrReceiver.decodedIRData.protocol)); - Serial.print(F(", decoded raw data: ")); -#if (__INT_WIDTH__ < 32) - Serial.print(IrReceiver.decodedIRData.decodedRawData, HEX); -#else - PrintULL::print(&Serial, IrReceiver.decodedIRData.decodedRawData, HEX); -#endif - Serial.print(F(", decoded address: ")); - Serial.print(IrReceiver.decodedIRData.address, HEX); - Serial.print(F(", decoded command: ")); - Serial.println(IrReceiver.decodedIRData.command, HEX); - IrReceiver.resume(); - } -} - -void loop() { - /* - * Print loop values - */ - Serial.println(); - Serial.print(F("address=0x")); - Serial.print(sAddress, HEX); - Serial.print(F(" command=0x")); - Serial.print(sCommand, HEX); - Serial.print(F(" repeats=")); - Serial.println(sRepeats); - Serial.flush(); - - send_ir_data(); - IrReceiver.restartAfterSend(); // Is a NOP if sending does not require a timer. - - // wait for the receiver state machine to detect the end of a protocol - delay((RECORD_GAP_MICROS / 1000) + 5); - receive_ir_data(); - - // Prepare data for next loop - sAddress += 0x0101; - sCommand += 0x11; - sRepeats++; - - delay(100); // Loop delay -} diff --git a/IRremote/examples/SendAndReceive/SendAndReceive.log b/IRremote/examples/SendAndReceive/SendAndReceive.log deleted file mode 100644 index ec6dc73b77b0341930f2e9adf54ca54eb4ff3adf..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendAndReceive/SendAndReceive.log +++ /dev/null @@ -1,39 +0,0 @@ -START ../src/SendAndReceive.cpp from Feb 24 2023 -Using library version 4.1.0 -Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, Universal Pulse Distance Width, at pin 2 -Send IR signals at pin 3 -Send signal mark duration is 8 us, pulse correction is 3000 ns, total period is 26 us -5000 us is the (minimum) gap, after which the start of a new IR packet is assumed -20 us are subtracted from all marks and added to all spaces for decoding - -address=0x102 command=0x34 repeats=1 -Sending: 0x102341 -Decoded protocol: NEC2, decoded raw data: CB340102, decoded address: 102, decoded command: 34 - -address=0x203 command=0x45 repeats=2 -Sending: 0x203452 -Decoded protocol: NEC, decoded raw data: BA450203, decoded address: 203, decoded command: 45 - -address=0x304 command=0x56 repeats=3 -Sending: 0x304563 -Decoded protocol: NEC, decoded raw data: A9560304, decoded address: 304, decoded command: 56 - -address=0x405 command=0x67 repeats=4 -Sending: 0x405674 -Decoded protocol: NEC, decoded raw data: 98670405, decoded address: 405, decoded command: 67 - -address=0x506 command=0x78 repeats=5 -Sending: 0x506785 -Decoded protocol: NEC, decoded raw data: 87780506, decoded address: 506, decoded command: 78 - -address=0x607 command=0x89 repeats=5 -Sending: 0x607895 -Decoded protocol: NEC, decoded raw data: 76890607, decoded address: 607, decoded command: 89 - -address=0x708 command=0x9A repeats=5 -Sending: 0x7089A5 -Decoded protocol: NEC, decoded raw data: 659A0708, decoded address: 708, decoded command: 9A - -address=0x809 command=0xAB repeats=5 -Sending: 0x809AB5 -Decoded protocol: NEC, decoded raw data: 54AB0809, decoded address: 809, decoded command: AB diff --git a/IRremote/examples/SendBoseWaveDemo/PinDefinitionsAndMore.h b/IRremote/examples/SendBoseWaveDemo/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendBoseWaveDemo/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SendBoseWaveDemo/SendBoseWaveDemo.ino b/IRremote/examples/SendBoseWaveDemo/SendBoseWaveDemo.ino deleted file mode 100644 index 054c083c1acbe604688e72fb637de4dd55b82eea..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendBoseWaveDemo/SendBoseWaveDemo.ino +++ /dev/null @@ -1,198 +0,0 @@ -/* - * SendBoseWaveDemo.cpp - * - * Prompt user for a code to send. Make sure your 940-950nm IR LED is - * connected to the default digital output. Place your Bose Wave Radio - * CD in the line of sight of your LED, and send commands! - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020 Thomas Koch - 2022 AJ converted to inverted bits - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#define DISABLE_CODE_FOR_RECEIVER // Disables restarting receiver after each send. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not used. - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -#include <IRremote.hpp> - -//...................................................................... -// -// Bose Wave Radio CD Remote Control -// |-------------------------------------| -// | On/Off Sleep VolUp | -// | Play/Pause Stop VolDown | -// | FM AM Aux | -// | Tune Down Tune Up Mute | -// | 1 2 3 | -// | 4 5 6 | -// |-------------------------------------| -#define BOSE_CMD_ON_OFF 0x00 -#define BOSE_CMD_MUTE 0x01 -#define BOSE_CMD_VOL_UP 0x02 -#define BOSE_CMD_VOL_DOWN 0x03 -#define BOSE_CMD_PRESET_6 0x04 -#define BOSE_CMD_SLEEP 0x05 -#define BOSE_CMD_FM 0x06 -#define BOSE_CMD_AUX 0x07 -#define BOSE_CMD_AM 0x08 -#define BOSE_CMD_PLAY_PAUSE 0x09 -#define BOSE_CMD_STOP 0x0A -#define BOSE_CMD_TUNE_UP 0x0B -#define BOSE_CMD_TUNE_DOWN 0x0C -#define BOSE_CMD_PRESET_1 0x0D -#define BOSE_CMD_PRESET_2 0x0E -#define BOSE_CMD_PRESET_3 0x0F -#define BOSE_CMD_PRESET_4 0x10 -#define BOSE_CMD_PRESET_5 0x11 - -// Codes for Wave Music System -// https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/pictures/BoseWaveMusicSystem.jpg) -//#define BOSE_CMD_ON_OFF 0x4C -//#define BOSE_CMD_MUTE 0x01 -//#define BOSE_CMD_VOL_UP 0x03 -//#define BOSE_CMD_VOL_DOWN 0x02 -//#define BOSE_CMD_SLEEP 0x54 -//#define BOSE_CMD_FM_AM 0x06 -//#define BOSE_CMD_CD 0x53 -//#define BOSE_CMD_AUX 0x0F -//#define BOSE_CMD_TRACK_BW 0x18 -//#define BOSE_CMD_TRACK_FW 0x19 -//#define BOSE_CMD_PLAY_PAUSE 0x1B -//#define BOSE_CMD_STOP_EJECT 0x1A -//#define BOSE_CMD_TUNE_UP 0x58 -//#define BOSE_CMD_TUNE_DOWN 0x57 -//#define BOSE_CMD_PRESET_1 0x07 -//#define BOSE_CMD_PRESET_2 0x08 -//#define BOSE_CMD_PRESET_3 0x09 -//#define BOSE_CMD_PRESET_4 0x0A -//#define BOSE_CMD_PRESET_5 0x0B -//#define BOSE_CMD_PRESET_6 0x0C -//#define BOSE_CMD_TIME_MINUS 0x9E -//#define BOSE_CMD_TIME_PLUS 0x24 -//#define BOSE_CMD_PLAY_MODE 0x21 -//#define BOSE_CMD_ALARM_ON_OFF 0x22 -//#define BOSE_CMD_ALARM_WAKE_TO 0x70 -//#define BOSE_CMD_ALARM_TIME 0x23 - -bool sPrintMenu; -void printMenu(); - -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - -#if defined(IR_SEND_PIN) - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin - Serial.println(F("Send IR signals at pin " STR(IR_SEND_PIN))); -#else - IrSender.begin(3, ENABLE_LED_FEEDBACK, USE_DEFAULT_FEEDBACK_LED_PIN); // Specify send pin and enable feedback LED at default feedback LED pin - Serial.println(F("Send IR signals at pin 3")); -#endif - - sPrintMenu = true; -} - -void loop() { - if (sPrintMenu) { - sPrintMenu = false; - printMenu(); - } - int tSerialCommandCharacter; - - if (Serial.available()) { - tSerialCommandCharacter = Serial.read(); - sPrintMenu = true; - if (tSerialCommandCharacter == -1) { - Serial.print(F("available() was true, but no character read")); // should not happen - } else if (tSerialCommandCharacter == 48) { // 0 - IrSender.sendBoseWave(BOSE_CMD_ON_OFF); // On/Off - } else if (tSerialCommandCharacter == 49) { // 1 - IrSender.sendBoseWave(BOSE_CMD_VOL_UP); // Volume Up - } else if (tSerialCommandCharacter == 50) { // 2 - IrSender.sendBoseWave(BOSE_CMD_VOL_DOWN); // Volume Down - } else if (tSerialCommandCharacter == 51) { // 3 - IrSender.sendBoseWave(BOSE_CMD_TUNE_UP); // Tune Up - } else if (tSerialCommandCharacter == 52) { // 4 - IrSender.sendBoseWave(BOSE_CMD_TUNE_DOWN); // Tune Down - } else if (tSerialCommandCharacter == 53) { // 5 - IrSender.sendBoseWave(BOSE_CMD_AM); // AM - } else if (tSerialCommandCharacter == 54) { // 6 - IrSender.sendBoseWave(BOSE_CMD_FM); // FM - } else if (tSerialCommandCharacter == 55) { // 7 - IrSender.sendBoseWave(BOSE_CMD_PRESET_1); // Preset 1 - } else if (tSerialCommandCharacter == 56) { // 8 - IrSender.sendBoseWave(BOSE_CMD_PRESET_2); // Preset 2 - } else if (tSerialCommandCharacter == 57) { // 9 - IrSender.sendBoseWave(BOSE_CMD_PRESET_3); // Preset 3 - } else if (tSerialCommandCharacter == 97) { // a - IrSender.sendBoseWave(BOSE_CMD_PRESET_4); // Preset 4 - } else if (tSerialCommandCharacter == 98) { // b - IrSender.sendBoseWave(BOSE_CMD_PRESET_5); // Preset 5 - } else if (tSerialCommandCharacter == 99) { // c - IrSender.sendBoseWave(BOSE_CMD_PRESET_6); // Preset 6 - } else if (tSerialCommandCharacter == 100) { // d - IrSender.sendBoseWave(BOSE_CMD_MUTE); // Mute - } else if (tSerialCommandCharacter == 101) { // e - IrSender.sendBoseWave(BOSE_CMD_PLAY_PAUSE); // Pause - } else if (tSerialCommandCharacter == 102) { // f - IrSender.sendBoseWave(BOSE_CMD_STOP); // Stop - } else if (tSerialCommandCharacter == 103) { // g - IrSender.sendBoseWave(BOSE_CMD_AUX); // Aux - } else if (tSerialCommandCharacter == 104) { // h - IrSender.sendBoseWave(BOSE_CMD_SLEEP); // Sleep - } else { - sPrintMenu = false; - } - delay(300); - } -} - -void printMenu() { - Serial.println("0: On / Off"); - Serial.println("1: Volume Up"); - Serial.println("2: Volume Down"); - Serial.println("3: Tune Up"); - Serial.println("4: Tune Down"); - Serial.println("5: AM"); - Serial.println("6: FM"); - Serial.println("7: Preset 1"); - Serial.println("8: Preset 2"); - Serial.println("9: Preset 3"); - Serial.println("a: Preset 4"); - Serial.println("b: Preset 5"); - Serial.println("c: Preset 6"); - Serial.println("d: Mute"); - Serial.println("e: Play/Pause"); - Serial.println("f: Stop"); - Serial.println("g: Aux"); - Serial.println("h: Sleep"); -} diff --git a/IRremote/examples/SendDemo/IRremote_SendDemo_ReceiveDemo.log b/IRremote/examples/SendDemo/IRremote_SendDemo_ReceiveDemo.log deleted file mode 100644 index d56a9481fc94cb187648b2523f5960c108405415..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendDemo/IRremote_SendDemo_ReceiveDemo.log +++ /dev/null @@ -1,178 +0,0 @@ -START ../src/ReceiveDemo.cpp from Feb 24 2023 -Using library version 4.1.0 -Enabling IRin... -Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, Panasonic/Kaseikyo, Denon/Sharp, Sony, RC5, RC6, LG, JVC, Samsung, FAST, Whynter, Lego Power Functions, Bosewave , MagiQuest, Universal Pulse Distance Width, Hash at pin 2 - -If you connect debug pin 5 to ground, raw data is always printed -5000 us is the (minimum) gap, after which the start of a new IR packet is assumed -20 us are subtracted from all marks and added to all spaces for decoding - -Protocol=NEC Address=0x2 Command=0x34 Raw-Data=0xCB34FD02 32 bits LSB first -Send with: IrSender.sendNEC(0x2, 0x34, <numberOfRepeats>); - -Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendNEC(0x102, 0x34, <numberOfRepeats>); - -Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendNEC(0x102, 0x34, <numberOfRepeats>); - -Protocol=NEC Address=0x80 Command=0x45 Raw-Data=0xBA457F80 32 bits LSB first -Send with: IrSender.sendNEC(0x80, 0x45, <numberOfRepeats>); - -Protocol=NEC Address=0x4 Command=0x8 Raw-Data=0xF708FB04 32 bits LSB first -Send with: IrSender.sendNEC(0x4, 0x8, <numberOfRepeats>); - -Protocol=Onkyo Address=0x102 Command=0x304 Raw-Data=0x3040102 32 bits LSB first -Send with: IrSender.sendOnkyo(0x102, 0x304, <numberOfRepeats>); - -Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendNEC(0x102, 0x34, <numberOfRepeats>); - -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); - -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); - -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); - -Protocol=PulseDistance Raw-Data=0x5A 72 bits LSB first -Send with: - uint32_t tRawData[]={0x87654321, 0xAFEDCBA9, 0x5A}; - IrSender.sendPulseDistanceWidthFromArray(38, 8850, 4400, 550, 1700, 550, 600, &tRawData[0], 72, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); - -Protocol=PulseWidth Raw-Data=0xDCBA9 52 bits LSB first -Send with: - uint32_t tRawData[]={0x87654321, 0xDCBA9}; - IrSender.sendPulseDistanceWidthFromArray(38, 300, 600, 600, 300, 350, 600, &tRawData[0], 52, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); - -Protocol=PulseWidth Raw-Data=0x87654321 32 bits LSB first -Send with: IrSender.sendPulseDistanceWidth(38, 1000, 500, 600, 300, 350, 300, 0x87654321, 32, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); - -Protocol=Onkyo Address=0x102 Command=0x5634 Raw-Data=0x56340102 32 bits LSB first -Send with: IrSender.sendOnkyo(0x102, 0x5634, <numberOfRepeats>); - -Protocol=Apple Address=0x2 Command=0x34 Raw-Data=0x23487EE 32 bits LSB first -Send with: IrSender.sendApple(0x2, 0x34, <numberOfRepeats>); - -Protocol=Panasonic Address=0x102 Command=0x34 Raw-Data=0x4341020 48 bits LSB first -Send with: IrSender.sendPanasonic(0x102, 0x34, <numberOfRepeats>); - -Protocol=Kaseikyo Address=0x102 Command=0x34 Extra=0x4711 Raw-Data=0x7341023 48 bits LSB first -Send with: IrSender.sendKaseikyo(0x102, 0x34, <numberOfRepeats>, 0x4711); - -Protocol=Kaseikyo_Denon Address=0x102 Command=0x34 Raw-Data=0x4341020 48 bits LSB first -Send with: IrSender.sendKaseikyo_Denon(0x102, 0x34, <numberOfRepeats>); - -Protocol=Denon Address=0x2 Command=0x34 Raw-Data=0x682 15 bits LSB first -Send with: IrSender.sendDenon(0x2, 0x34, <numberOfRepeats>); - -Protocol=Denon Address=0x2 Command=0x34 Auto-Repeat gap=45650us Raw-Data=0x7962 15 bits LSB first - -Protocol=Sharp Address=0x2 Command=0x34 Raw-Data=0x4682 15 bits LSB first -Send with: IrSender.sendSharp(0x2, 0x34, <numberOfRepeats>); - -Protocol=Sharp Address=0x2 Command=0x34 Auto-Repeat gap=46400us Raw-Data=0x3962 15 bits LSB first - -Protocol=Sony Address=0x2 Command=0x34 Raw-Data=0x134 12 bits LSB first -Send with: IrSender.sendSony(0x2, 0x34, 2, 12); - -Protocol=Sony Address=0x2 Command=0x34 Raw-Data=0x134 15 bits LSB first -Send with: IrSender.sendSony(0x2, 0x34, 2, 15); - -Protocol=Sony Address=0x102 Command=0x34 Raw-Data=0x8134 20 bits LSB first -Send with: IrSender.sendSony(0x102, 0x34, 2, 20); - -Protocol=Samsung Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendSamsung(0x102, 0x34, <numberOfRepeats>); - -Protocol=Samsung Address=0x102 Command=0x5634 Raw-Data=0x56340102 32 bits LSB first -Send with: IrSender.sendSamsung(0x102, 0x5634, <numberOfRepeats>); - -Protocol=Samsung48 Address=0x102 Command=0x5634 Raw-Data=0xA956 48 bits LSB first -Send with: IrSender.sendSamsung48(0x102, 0x5634, <numberOfRepeats>); - -Protocol=RC5 Address=0x2 Command=0x34 Raw-Data=0x10B4 13 bits MSB first -Send with: IrSender.sendRC5(0x2, 0x34, <numberOfRepeats>); - -Protocol=RC5 Address=0x2 Command=0x74 Toggle=1 Raw-Data=0x8B4 13 bits MSB first -Send with: IrSender.sendRC5(0x2, 0x74, <numberOfRepeats>); - -Protocol=RC6 Address=0x2 Command=0x34 Raw-Data=0x234 20 bits MSB first -Send with: IrSender.sendRC6(0x2, 0x34, <numberOfRepeats>); - -Protocol=Samsung Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendSamsung(0x102, 0x34, <numberOfRepeats>); - -Protocol=JVC Address=0x2 Command=0x34 Raw-Data=0x3402 16 bits LSB first -Send with: IrSender.sendJVC(0x2, 0x34, <numberOfRepeats>); - -Protocol=Samsung Address=0x102 Command=0x5634 Raw-Data=0x56340102 32 bits LSB first -Send with: IrSender.sendSamsung(0x102, 0x5634, <numberOfRepeats>); - -Protocol=LG Address=0x2 Command=0x5634 Raw-Data=0x256342 28 bits MSB first -Send with: IrSender.sendLG(0x2, 0x5634, <numberOfRepeats>); - -Protocol=MagiQuest Address=0x102 Command=0x34 Raw-Data=0x6BCD0102 56 bits MSB first -Send with: IrSender.sendMagiQuest(0x6BCD0102, 0x34, <numberOfRepeats>); - -Protocol=BoseWave Address=0x0 Command=0x34 Raw-Data=0xCB34 16 bits LSB first -Send with: IrSender.sendBoseWave(0x0, 0x34, <numberOfRepeats>); - -Protocol=FAST Address=0x0 Command=0x34 Raw-Data=0xCB34 16 bits LSB first -Send with: IrSender.sendFAST(0x0, 0x34, <numberOfRepeats>); - -Protocol=Lego Address=0x2 Command=0x14 Raw-Data=0x2148 16 bits MSB first -Send with: IrSender.sendLego(0x2, 0x14, <numberOfRepeats>); - -Protocol=Lego Address=0x2 Command=0x14 Auto-Repeat gap=180450us Raw-Data=0x2148 16 bits MSB first - -Protocol=Lego Address=0x2 Command=0x14 Auto-Repeat gap=179350us Raw-Data=0x2148 16 bits MSB first - -Protocol=Lego Address=0x2 Command=0x14 Auto-Repeat gap=179200us Raw-Data=0x2148 16 bits MSB first - -Protocol=Lego Address=0x2 Command=0x14 Auto-Repeat gap=179150us Raw-Data=0x2148 16 bits MSB first - -Overflow detected -Try to increase the "RAW_BUFFER_LENGTH" value of 600 in ../src/ReceiveDemo.cpp - -Protocol=NEC Address=0x3 Command=0x45 Raw-Data=0xBA45FC03 32 bits LSB first -Send with: IrSender.sendNEC(0x3, 0x45, <numberOfRepeats>); - -Protocol=NEC Address=0x3 Command=0x45 Repeat gap=43250us - -Protocol=NEC Address=0x203 Command=0x45 Raw-Data=0xBA450203 32 bits LSB first -Send with: IrSender.sendNEC(0x203, 0x45, <numberOfRepeats>); - -Protocol=NEC Address=0x203 Command=0x45 Repeat gap=47550us - -Protocol=NEC Address=0x203 Command=0x45 Raw-Data=0xBA450203 32 bits LSB first -Send with: IrSender.sendNEC(0x203, 0x45, <numberOfRepeats>); - -Protocol=NEC2 Address=0x203 Command=0x45 Repeat gap=46500us Raw-Data=0xBA450203 32 bits LSB first - -Protocol=Onkyo Address=0x203 Command=0x6745 Raw-Data=0x67450203 32 bits LSB first -Send with: IrSender.sendOnkyo(0x203, 0x6745, <numberOfRepeats>); - -Protocol=Onkyo Address=0x203 Command=0x6745 Repeat gap=46550us - -Protocol=Apple Address=0x3 Command=0x45 Raw-Data=0x34587EE 32 bits LSB first -Send with: IrSender.sendApple(0x3, 0x45, <numberOfRepeats>); - -Protocol=Apple Address=0x3 Command=0x45 Repeat gap=31550us - -Protocol=Panasonic Address=0x203 Command=0x45 Raw-Data=0x55452030 48 bits LSB first -Send with: IrSender.sendPanasonic(0x203, 0x45, <numberOfRepeats>); - -Protocol=Panasonic Address=0x203 Command=0x45 Repeat gap=72550us Raw-Data=0x55452030 48 bits LSB first - -Protocol=Kaseikyo Address=0x203 Command=0x45 Extra=0x4711 Raw-Data=0x56452033 48 bits LSB first -Send with: IrSender.sendKaseikyo(0x203, 0x45, <numberOfRepeats>, 0x4711); - -Protocol=Kaseikyo Address=0x203 Command=0x45 Extra=0x4711 Repeat gap=66750us Raw-Data=0x56452033 48 bits LSB first - -Protocol=Kaseikyo_Denon Address=0x203 Command=0x45 Raw-Data=0x55452030 48 bits LSB first -Send with: IrSender.sendKaseikyo_Denon(0x203, 0x45, <numberOfRepeats>); - -Protocol=Kaseikyo_Denon Address=0x203 Command=0x45 Repeat gap=68300us Raw-Data=0x55452030 48 bits LSB first \ No newline at end of file diff --git a/IRremote/examples/SendDemo/PinDefinitionsAndMore.h b/IRremote/examples/SendDemo/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendDemo/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SendDemo/SendDemo.ino b/IRremote/examples/SendDemo/SendDemo.ino deleted file mode 100644 index 97e7fa29aa068a345788bc58734219e53eeeaf86..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendDemo/SendDemo.ino +++ /dev/null @@ -1,429 +0,0 @@ -/* - * SendDemo.cpp - * - * Demonstrates sending IR codes in standard format with address and command - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -#define DISABLE_CODE_FOR_RECEIVER // Disables restarting receiver after each send. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not used. - -//#define EXCLUDE_EXOTIC_PROTOCOLS // Saves around 240 bytes program memory if IrSender.write is used -//#define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM. -//#define USE_NO_SEND_PWM // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition -//#define NO_LED_FEEDBACK_CODE // Saves 566 bytes program memory -//#define USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN // Use or simulate open drain output mode at send pin. Attention, active state of open drain is LOW, so connect the send LED between positive supply and send pin! - -#include <IRremote.hpp> - -#define DELAY_AFTER_SEND 2000 -#define DELAY_AFTER_LOOP 5000 - -void setup() { - Serial.begin(115200); - -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - -#if defined(IR_SEND_PIN) - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin -# if defined(IR_SEND_PIN_STRING) - Serial.println(F("Send IR signals at pin " IR_SEND_PIN_STRING)); -# else - Serial.println(F("Send IR signals at pin " STR(IR_SEND_PIN))); -# endif -#else - IrSender.begin(3, ENABLE_LED_FEEDBACK, USE_DEFAULT_FEEDBACK_LED_PIN); // Specify send pin and enable feedback LED at default feedback LED pin - Serial.println(F("Send IR signals at pin 3")); -#endif - -#if !defined(SEND_PWM_BY_TIMER) - /* - * Print internal software PWM signal generation info - */ - IrSender.enableIROut(38); // Call it with 38 kHz just to initialize the values printed below - Serial.print(F("Send signal mark duration is ")); - Serial.print(IrSender.periodOnTimeMicros); - Serial.print(F(" us, pulse narrowing correction is ")); - Serial.print(IrSender.getPulseCorrectionNanos()); - Serial.print(F(" ns, total period is ")); - Serial.print(IrSender.periodTimeMicros); - Serial.println(F(" us")); -#endif -} - -/* - * Set up the data to be sent. - * For most protocols, the data is build up with a constant 8 (or 16 byte) address - * and a variable 8 bit command. - * There are exceptions like Sony and Denon, which have 5 bit address. - */ -uint16_t sAddress = 0x0102; -uint8_t sCommand = 0x34; -uint16_t s16BitCommand = 0x5634; -uint8_t sRepeats = 0; - -void loop() { - /* - * Print values - */ - Serial.println(); - Serial.print(F("address=0x")); - Serial.print(sAddress, HEX); - Serial.print(F(" command=0x")); - Serial.print(sCommand, HEX); - Serial.print(F(" repeats=")); - Serial.println(sRepeats); - Serial.println(); - Serial.println(); - Serial.flush(); - - Serial.println(F("Send NEC with 8 bit address")); - Serial.flush(); - IrSender.sendNEC(sAddress & 0xFF, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal - - Serial.println(F("Send NEC with 16 bit address")); - Serial.flush(); - IrSender.sendNEC(sAddress, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send NEC2 with 16 bit address")); - Serial.flush(); - IrSender.sendNEC2(sAddress, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - if (sRepeats == 0) { -#if FLASHEND >= 0x3FFF && (RAMEND >= 0x4FF || RAMSIZE >= 0x4FF) // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc. - /* - * Send constant values only once in this demo - */ - Serial.println(F("Sending NEC Pronto data with 8 bit address 0x80 and command 0x45 and no repeats")); - Serial.flush(); - IrSender.sendPronto(F("0000 006D 0022 0000 015E 00AB " /* Pronto header + start bit */ - "0017 0015 0017 0015 0017 0017 0015 0017 0017 0015 0017 0015 0017 0015 0017 003F " /* Lower address byte */ - "0017 003F 0017 003E 0017 003F 0015 003F 0017 003E 0017 003F 0017 003E 0017 0015 " /* Upper address byte (inverted at 8 bit mode) */ - "0017 003E 0017 0015 0017 003F 0017 0015 0017 0015 0017 0015 0017 003F 0017 0015 " /* command byte */ - "0019 0013 0019 003C 0017 0015 0017 003F 0017 003E 0017 003F 0017 0015 0017 003E " /* inverted command byte */ - "0017 0806"), 0); //stop bit, no repeat possible, because of missing repeat pattern - delay(DELAY_AFTER_SEND); - - /* - * !!! The next data occupies 136 bytes RAM !!! - */ - Serial.println( - F("Send NEC sendRaw data with 8 bit address=0xFB04 and command 0x08 and exact timing (16 bit array format)")); - Serial.flush(); - const uint16_t irSignal[] = { 9000, 4500/*Start bit*/, 560, 560, 560, 560, 560, 1690, 560, - 560/*0010 0x4 of 16 bit address LSB first*/, 560, 560, 560, 560, 560, 560, 560, 560/*0000*/, 560, 1690, 560, 1690, - 560, 560, 560, 1690/*1101 0xB*/, 560, 1690, 560, 1690, 560, 1690, 560, 1690/*1111*/, 560, 560, 560, 560, 560, 560, - 560, 1690/*0001 0x08 of command LSB first*/, 560, 560, 560, 560, 560, 560, 560, 560/*0000 0x00*/, 560, 1690, 560, - 1690, 560, 1690, 560, 560/*1110 Inverted 8 of command*/, 560, 1690, 560, 1690, 560, 1690, 560, - 1690/*1111 inverted 0 of command*/, 560 /*stop bit*/}; // Using exact NEC timing - IrSender.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), NEC_KHZ); // Note the approach used to automatically calculate the size of the array. - delay(DELAY_AFTER_SEND); - - /* - * With sendNECRaw() you can send 32 bit combined codes - */ - Serial.println(F("Send ONKYO with 16 bit address 0x0102 and 16 bit command 0x0304 with NECRaw(0x03040102)")); - Serial.flush(); - IrSender.sendNECRaw(0x03040102, sRepeats); - delay(DELAY_AFTER_SEND); - - /* - * With Send sendNECMSB() you can send your old 32 bit codes. - * To convert one into the other, you must reverse the byte positions and then reverse all positions of each byte. - * Example: - * 0xCB340102 byte reverse -> 0x020134CB bit reverse-> 40802CD3 - */ - Serial.println(F("Send ONKYO with 16 bit address 0x0102 and command 0x34 with old 32 bit format MSB first (0x40802CD3)")); - Serial.flush(); - IrSender.sendNECMSB(0x40802CD3, 32, false); - delay(DELAY_AFTER_SEND); -#endif - - Serial.println(F("Send Panasonic 0xB, 0x10 as 48 bit PulseDistance using ProtocolConstants")); - Serial.flush(); -#if __INT_WIDTH__ < 32 - IRRawDataType tRawData[] = { 0xB02002, 0xA010 }; // LSB of tRawData[0] is sent first - IrSender.sendPulseDistanceWidthFromArray(&KaseikyoProtocolConstants, &tRawData[0], 48, NO_REPEATS); // Panasonic is a Kaseikyo variant -#else - IrSender.sendPulseDistanceWidth(&KaseikyoProtocolConstants, 0xA010B02002, 48, NO_REPEATS); // Panasonic is a Kaseikyo variant -#endif - - delay(DELAY_AFTER_SEND); - - /* - * Send 2 Panasonic 48 bit codes as generic Pulse Distance data, once with LSB and once with MSB first - */ - Serial.println(F("Send Panasonic 0xB, 0x10 as generic 48 bit PulseDistance")); - Serial.println(F(" LSB first")); - Serial.flush(); -#if __INT_WIDTH__ < 32 - IrSender.sendPulseDistanceWidthFromArray(38, 3450, 1700, 450, 1250, 450, 400, &tRawData[0], 48, - PROTOCOL_IS_LSB_FIRST, 0, NO_REPEATS); -#else - IrSender.sendPulseDistanceWidth(38, 3450, 1700, 450, 1250, 450, 400, 0xA010B02002, 48, PROTOCOL_IS_LSB_FIRST, - 0, NO_REPEATS); -#endif - delay(DELAY_AFTER_SEND); - - // The same with MSB first. Use bit reversed raw data of LSB first part - Serial.println(F(" MSB first")); -#if __INT_WIDTH__ < 32 - tRawData[0] = 0x40040D00; // MSB of tRawData[0] is sent first - tRawData[1] = 0x805; - IrSender.sendPulseDistanceWidthFromArray(38, 3450, 1700, 450, 1250, 450, 400, &tRawData[0], 48, - PROTOCOL_IS_MSB_FIRST, 0, NO_REPEATS); -#else - IrSender.sendPulseDistanceWidth(38, 3450, 1700, 450, 1250, 450, 400, 0x40040D000805, 48, PROTOCOL_IS_MSB_FIRST, - 0, NO_REPEATS); -#endif - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send generic 72 bit PulseDistance 0x5A AFEDCBA9 87654321 LSB first")); - Serial.flush(); -# if __INT_WIDTH__ < 32 - tRawData[0] = 0x87654321; // LSB of tRawData[0] is sent first - tRawData[1] = 0xAFEDCBA9; - tRawData[2] = 0x5A; - IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1700, 550, 600, &tRawData[0], 72, PROTOCOL_IS_LSB_FIRST, 0, - NO_REPEATS); -# else - IRRawDataType tRawData[] = { 0xAFEDCBA987654321, 0x5A }; // LSB of tRawData[0] is sent first - IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1700, 550, 600, &tRawData[0], 72, PROTOCOL_IS_LSB_FIRST, 0, NO_REPEATS); -# endif - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send generic 52 bit PulseDistanceWidth 0xDCBA9 87654321 LSB first")); - Serial.flush(); - // Real PulseDistanceWidth (constant bit length) does not require a stop bit -#if __INT_WIDTH__ < 32 - IrSender.sendPulseDistanceWidthFromArray(38, 300, 600, 600, 300, 300, 600, &tRawData[0], 52, - PROTOCOL_IS_LSB_FIRST, 0, 0); -#else - IrSender.sendPulseDistanceWidth(38, 300, 600, 600, 300, 300, 600, 0xDCBA987654321, 52, PROTOCOL_IS_LSB_FIRST, - 0, 0); -#endif - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send generic 32 bit PulseWidth 0x87654321 LSB first")); - Serial.flush(); - // Real PulseDistanceWidth (constant bit length) does not require a stop bit - IrSender.sendPulseDistanceWidth(38, 1000, 500, 600, 300, 300, 300, 0x87654321, 32, PROTOCOL_IS_LSB_FIRST, 0, 0); - delay(DELAY_AFTER_SEND); - } - - Serial.println(F("Send Onkyo (NEC with 16 bit command)")); - Serial.flush(); - IrSender.sendOnkyo(sAddress, s16BitCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Apple")); - Serial.flush(); - IrSender.sendApple(sAddress & 0xFF, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Panasonic")); - Serial.flush(); - IrSender.sendPanasonic(sAddress & 0xFFF, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Kaseikyo with 0x4711 as Vendor ID")); - Serial.flush(); - IrSender.sendKaseikyo(sAddress & 0xFFF, sCommand, sRepeats, 0x4711); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Kaseikyo_Denon variant")); - Serial.flush(); - IrSender.sendKaseikyo_Denon(sAddress & 0xFFF, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Denon")); - Serial.flush(); - IrSender.sendDenon(sAddress & 0x1F, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Denon/Sharp variant")); - Serial.flush(); - IrSender.sendSharp(sAddress & 0x1F, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Sony/SIRCS with 7 command and 5 address bits")); - Serial.flush(); - IrSender.sendSony(sAddress & 0x1F, sCommand & 0x7F, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Sony/SIRCS with 7 command and 8 address bits")); - Serial.flush(); - IrSender.sendSony(sAddress & 0xFF, sCommand, sRepeats, SIRCS_15_PROTOCOL); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Sony/SIRCS with 7 command and 13 address bits")); - Serial.flush(); - IrSender.sendSony(sAddress & 0x1FFF, sCommand & 0x7F, sRepeats, SIRCS_20_PROTOCOL); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Samsung 8 bit command")); - Serial.flush(); - IrSender.sendSamsung(sAddress, sCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Samsung 16 bit command")); - Serial.flush(); - IrSender.sendSamsung(sAddress, s16BitCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Samsung48 16 bit command")); - Serial.flush(); - IrSender.sendSamsung48(sAddress, s16BitCommand, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send RC5")); - Serial.flush(); - IrSender.sendRC5(sAddress & 0x1F, sCommand & 0x3F, sRepeats, true); // 5 address, 6 command bits - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send RC5X with 7.th MSB of command set")); - Serial.flush(); - IrSender.sendRC5(sAddress & 0x1F, (sCommand & 0x3F) + 0x40, sRepeats, true); // 5 address, 7 command bits - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send RC6")); - Serial.flush(); - IrSender.sendRC6(sAddress, sCommand, sRepeats, true); - delay(DELAY_AFTER_SEND); - -#if FLASHEND >= 0x3FFF && (RAMEND >= 0x4FF || RAMSIZE >= 0x4FF) // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc. - /* - * Next example how to use the IrSender.write function - */ - IRData IRSendData; - // prepare data - IRSendData.address = sAddress; - IRSendData.command = sCommand; - IRSendData.flags = IRDATA_FLAGS_EMPTY; - - IRSendData.protocol = SAMSUNG; - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - delay(DELAY_AFTER_SEND); - - IRSendData.protocol = JVC; // switch protocol - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - delay(DELAY_AFTER_SEND); - - IRSendData.command = s16BitCommand; // LG support more than 8 bit command - - IRSendData.protocol = SAMSUNG; - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - delay(DELAY_AFTER_SEND); - - IRSendData.protocol = LG; - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send MagiQuest")); - Serial.flush(); - IrSender.sendMagiQuest(0x6BCD0000 | (uint32_t) sAddress, s16BitCommand); // we have 31 bit address - delay(DELAY_AFTER_SEND); - - // Bang&Olufsen must be sent with 455 kHz -// Serial.println(F("Send Bang&Olufsen")); -// Serial.flush(); -// IrSender.sendBangOlufsen(sAddress, sCommand, sRepeats); -// delay(DELAY_AFTER_SEND); - - IRSendData.protocol = BOSEWAVE; - Serial.println(F("Send Bosewave with no address and 8 command bits")); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - delay(DELAY_AFTER_SEND); - - IRSendData.protocol = FAST; - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - delay(DELAY_AFTER_SEND); - - /* - * LEGO is difficult to receive because of its short marks and spaces - */ - Serial.println(F("Send Lego with 2 channel and with 4 command bits")); - Serial.flush(); - IrSender.sendLegoPowerFunctions(sAddress, sCommand, LEGO_MODE_COMBO, true); - delay(DELAY_AFTER_SEND); - -#endif // FLASHEND - /* - * Force buffer overflow - */ - Serial.println(F("Force buffer overflow by sending 700 marks and spaces")); - for (unsigned int i = 0; i < 350; ++i) { - // 400 + 400 should be received as 8/8 and sometimes as 9/7 or 7/9 if compensation by MARK_EXCESS_MICROS is optimal. - // 210 + 540 = 750 should be received as 5/10 or 4/11 if compensation by MARK_EXCESS_MICROS is optimal. - IrSender.mark(210); // 8 pulses at 38 kHz - IrSender.space(540); // to fill up to 750 us - } - delay(DELAY_AFTER_SEND); - - /* - * Increment values - * Also increment address just for demonstration, which normally makes no sense - */ - sAddress += 0x0101; - sCommand += 0x11; - s16BitCommand += 0x1111; - sRepeats++; - // clip repeats at 4 - if (sRepeats > 4) { - sRepeats = 4; - } - - delay(DELAY_AFTER_LOOP); // additional delay at the end of each loop -} - diff --git a/IRremote/examples/SendLGAirConditionerDemo/PinDefinitionsAndMore.h b/IRremote/examples/SendLGAirConditionerDemo/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendLGAirConditionerDemo/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SendLGAirConditionerDemo/Readme.md b/IRremote/examples/SendLGAirConditionerDemo/Readme.md deleted file mode 100644 index ad16367c00cb6c7a21d886819e2ee424ad478b1c..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendLGAirConditionerDemo/Readme.md +++ /dev/null @@ -1,93 +0,0 @@ -=== decoding for LG A/C ==== -- 1) remote of LG AC has two type of HDR mark/space, 8000/4000 and 3100/10000 -- 2) HDR 8000/4000 is decoded using decodeLG(IRrecvDumpV2) without problem -- 3) for HDR 3100/10000, use AnalysIR's code : http://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino/ -- 4) for bin output based on AnalysIR's code : https://gist.github.com/chaeplin/a3a4b4b6b887c663bfe8 -- 5) remove first two byte(11) -- 6) sample rawcode with bin output : https://gist.github.com/chaeplin/134d232e0b8cfb898860 - - -=== *** === -- 1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d -- 2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4 - - -=== *** === -- (0) : Cooling or Heating -- (1) : fixed address -- (2) : fixed address -- (3) : special(power, swing, air clean) -- (4) : change air flow, temperature, cooling(0)/heating(4) -- (5) : temperature ( 15 + (5) = ) -- (6) : air flow -- (7) : checksum ( 3 + 4 + 5 + 6 ) & B00001111 - - -°F = °C × 1.8 + 32<br/> -°C = (°F - 32) / 1.8 - - -=== *** === -* remote / Korea / without heating - -| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) -|----------------|---|----|----|----|----|----|----|---- -| on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100 -| on / 26 / mid | C |1000|1000|0000|0000|1011|0010|1101 -| on / 27 / mid | C |1000|1000|0000|0000|1100|0010|1110 -| on / 28 / mid | C |1000|1000|0000|0000|1101|0010|1111 -| on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110 -| on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111 -| on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 -| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 -|----------------|---|----|----|----|----|----|----|---- -| 1 up | C |1000|1000|0000|1000|1101|0100|1001 -|----------------|---|----|----|----|----|----|----|---- -| Cool power | C |1000|1000|0001|0000|0000|1100|1101 -| energy saving | C |1000|1000|0001|0000|0000|0100|0101 -| power | C |1000|1000|0001|0000|0000|1000|1001 -| flow/up/down | C |1000|1000|0001|0011|0001|0100|1001 -| up/down off | C |1000|1000|0001|0011|0001|0101|1010 -| flow/left/right| C |1000|1000|0001|0011|0001|0110|1011 -| left/right off | C |1000|1000|0001|0011|0001|0111|1100 -|----------------|---|----|----|----|----|----|----|---- -| Air clean | C |1000|1000|1100|0000|0000|0000|1100 -|----------------|---|----|----|----|----|----|----|---- -| off | C |1000|1000|1100|0000|0000|0101|0001 - - - -* remote / with heating -* converted using raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf - -| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) -|----------------|---|----|----|----|----|----|----|---- -| on | C |1000|1000|0000|0000|1011|0010|1101 -|----------------|---|----|----|----|----|----|----|---- -| off | C |1000|1000|1100|0000|0000|0101|0001 -|----------------|---|----|----|----|----|----|----|---- -| 64 / 18 | C |1000|1000|0000|0000|0011|0100|0111 -| 66 / 19 | C |1000|1000|0000|0000|0100|0100|1000 -| 68 / 20 | C |1000|1000|0000|0000|0101|0100|1001 -| 70 / 21 | C |1000|1000|0000|0000|0110|0100|1010 -| 72 / 22 | C |1000|1000|0000|0000|0111|0100|1011 -| 74 / 23 | C |1000|1000|0000|0000|1000|0100|1100 -| 76 / 25 | C |1000|1000|0000|0000|1010|0100|1110 -| 78 / 26 | C |1000|1000|0000|0000|1011|0100|1111 -| 80 / 27 | C |1000|1000|0000|0000|1100|0100|0000 -| 82 / 28 | C |1000|1000|0000|0000|1101|0100|0001 -| 84 / 29 | C |1000|1000|0000|0000|1110|0100|0010 -| 86 / 30 | C |1000|1000|0000|0000|1111|0100|0011 -|----------------|---|----|----|----|----|----|----|---- -| heat64 | H |1000|1000|0000|0100|0011|0100|1011 -| heat66 | H |1000|1000|0000|0100|0100|0100|1100 -| heat68 | H |1000|1000|0000|0100|0101|0100|1101 -| heat70 | H |1000|1000|0000|0100|0110|0100|1110 -| heat72 | H |1000|1000|0000|0100|0111|0100|1111 -| heat74 | H |1000|1000|0000|0100|1000|0100|0000 -| heat76 | H |1000|1000|0000|0100|1001|0100|0001 -| heat78 | H |1000|1000|0000|0100|1011|0100|0011 -| heat80 | H |1000|1000|0000|0100|1100|0100|0100 -| heat82 | H |1000|1000|0000|0100|1101|0100|0101 -| heat84 | H |1000|1000|0000|0100|1110|0100|0110 -| heat86 | H |1000|1000|0000|0100|1111|0100|0111 diff --git a/IRremote/examples/SendLGAirConditionerDemo/SendLGAirConditionerDemo.ino b/IRremote/examples/SendLGAirConditionerDemo/SendLGAirConditionerDemo.ino deleted file mode 100644 index 9697745e1eb37d8fe8a3883f9e296c55603b998b..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendLGAirConditionerDemo/SendLGAirConditionerDemo.ino +++ /dev/null @@ -1,149 +0,0 @@ -/* - * SendLGAirConditionerDemo.cpp - * - * Sending LG air conditioner IR codes controlled by Serial input - * Based on he old IRremote source from https://github.com/chaeplin - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -/* - * LG2 has different header timing and a shorter bit time - * Known LG remote controls, which uses LG2 protocol are: - * AKB75215403 - * AKB74955603 - * AKB73757604: - */ -//#define USE_LG2_PROTOCOL // Try it if you do not have success with the default LG protocol -#define NUMBER_OF_COMMANDS_BETWEEN_PRINT_OF_MENU 5 - -#define DISABLE_CODE_FOR_RECEIVER // Disables restarting receiver after each send. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not used. - -#define INFO // Deactivate this to save program memory and suppress info output from the LG-AC driver. -//#define DEBUG // Activate this for more output from the LG-AC driver. - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -#include <IRremote.hpp> - -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -#endif - -#include "ac_LG.hpp" - -#define SIZE_OF_RECEIVE_BUFFER 10 -char sRequestString[SIZE_OF_RECEIVE_BUFFER]; - -Aircondition_LG MyLG_Aircondition; - -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) -delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif -// Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - Serial.println(F("Send IR signals at pin " STR(IR_SEND_PIN))); - - /* - * The IR library setup. That's all! - */ - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin - - - Serial.println(); - MyLG_Aircondition.setType(LG_IS_WALL_TYPE); - MyLG_Aircondition.printMenu(&Serial); - - delay(1000); - -// test -// MyLG_Aircondition.sendCommandAndParameter('j', 1); -// delay(5000); -// MyLG_Aircondition.sendCommandAndParameter('f', 3); -// delay(5000); - -} - -void loop() { - static uint8_t sShowmenuConter = 0; - - if (Serial.available()) { - /* - * Get parameters from serial - */ - uint8_t tNumberOfBytesReceived = Serial.readBytesUntil('\n', sRequestString, SIZE_OF_RECEIVE_BUFFER - 1); - // handle CR LF - if (sRequestString[tNumberOfBytesReceived - 1] == '\r') { - tNumberOfBytesReceived--; - } - sRequestString[tNumberOfBytesReceived] = '\0'; // terminate as string - char tCommand = sRequestString[0]; - - /* - * Handle parameter numbers which can be greater 9 - */ - int tParameter = 0; - if (tNumberOfBytesReceived >= 2) { - tParameter = sRequestString[1] - '0'; - if (tCommand == LG_COMMAND_TEMPERATURE || tCommand == LG_COMMAND_SWING || tCommand == LG_COMMAND_SLEEP - || tCommand == LG_COMMAND_TIMER_ON || tCommand == LG_COMMAND_TIMER_OFF) { - tParameter = atoi(&sRequestString[1]); - } - } - - /* - * Print command to send - */ - Serial.println(); - Serial.print(F("Command=")); - Serial.print(tCommand); - if (tParameter != 0) { - Serial.print(F(" Parameter=")); - Serial.print(tParameter); - } - Serial.println(); - - if (!MyLG_Aircondition.sendCommandAndParameter(tCommand, tParameter)) { - Serial.print(F("Error: unknown command or invalid parameter in \"")); - Serial.print(sRequestString); - Serial.println('\"'); - } - - if (sShowmenuConter == 0) { - MyLG_Aircondition.printMenu(&Serial); - sShowmenuConter = NUMBER_OF_COMMANDS_BETWEEN_PRINT_OF_MENU; - } else { - sShowmenuConter--; - } - } - delay(100); -} - diff --git a/IRremote/examples/SendProntoDemo/PinDefinitionsAndMore.h b/IRremote/examples/SendProntoDemo/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendProntoDemo/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SendProntoDemo/SendProntoDemo.ino b/IRremote/examples/SendProntoDemo/SendProntoDemo.ino deleted file mode 100644 index ba92eff214a0c94255d2ef0dea0715d1e26c9b30..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendProntoDemo/SendProntoDemo.ino +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SendProntoDemo.cpp - * - * Example for sending pronto codes with the IRremote library. - * The code used here, sends NEC protocol data. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#define DISABLE_CODE_FOR_RECEIVER // Disables restarting receiver after each send. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not used. - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -#include <IRremote.hpp> - -#define NUMBER_OF_REPEATS 3U - -// The first number, here 0000, denotes the type of the signal. 0000 denotes a raw IR signal with modulation. -// The second number, here 006C, denotes a frequency code. 006C corresponds to 1000000/(0x006c * 0.241246) = 38381 Hertz. -// The third and the forth number denote the number of pairs (= half the number of durations) in the start- and the repeat sequence respectively. -const char yamahaVolDown[] -#if defined(__AVR__) -PROGMEM -#endif -= "0000 006C 0022 0002 015B 00AD " /* Pronto header + start bit */ - "0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0016 " /* Lower address byte */ - "0016 0041 0016 0016 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 " /* Upper address byte (inverted at 8 bit mode) */ - "0016 0041 0016 0041 0016 0016 0016 0041 0016 0041 0016 0016 0016 0016 0016 0016 " /* command byte */ - "0016 0016 0016 0016 0016 0041 0016 0016 0016 0016 0016 0041 0016 0041 0016 0041 0016 05F7 " /* inverted command byte + stop bit */ - "015B 0057 0016 0E6C"; /* NEC repeat pattern*/ - -IRsend irsend; - -void setup() { - Serial.begin(115200); - while (!Serial) - ; - - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - Serial.println(F("Send IR signals at pin " STR(IR_SEND_PIN))); - - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin -} - -void loop() { - -#if defined(__AVR__) - Serial.println(F("Sending NEC from PROGMEM: address 0x85, data 0x1B")); - irsend.sendPronto_P(yamahaVolDown, NUMBER_OF_REPEATS); -#else - Serial.println(F("Sending from normal memory")); - irsend.sendPronto(yamahaVolDown, NUMBER_OF_REPEATS); -#endif - - delay(2000); - Serial.println(F("Sending the NEC from PROGMEM using the F()-form: address 0x5, data 0x1A")); - irsend.sendPronto(F("0000 006C 0022 0002 015B 00AD " /* Pronto header + start bit */ - "0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 " /* Lower address byte */ - "0016 0041 0016 0016 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 " /* Upper address byte (inverted at 8 bit mode) */ - "0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0016 0016 0016 0016 0016 " /* command byte */ - "0016 0041 0016 0016 0016 0041 0016 0016 0016 0016 0016 0041 0016 0041 0016 0041 0016 05F7 " /* inverted command byte + stop bit */ - "015B 0057 0016 0E6C"), /* NEC repeat pattern*/ - NUMBER_OF_REPEATS); - delay(2000); - - // send Nec code acquired by IRreceiveDump.cpp - Serial.println(F("Sending NEC from RAM: address 0xFF00, data 0x15")); - // 006D -> 38029 Hz - irsend.sendPronto("0000 006D 0022 0000 015C 00AB " /* Pronto header + start bit */ - "0017 0015 0017 0015 0017 0015 0017 0015 0017 0015 0017 0015 0017 0015 0017 0015 " /* Lower address byte */ - "0017 003F 0017 003E 0017 003F 0017 003E 0017 003F 0015 003F 0017 003F 0015 003F " /* Upper address byte (inverted at 8 bit mode) */ - "0017 003E 0017 0015 0017 003F 0017 0015 0017 003E 0017 0015 0017 0017 0015 0017 " /* command byte */ - "0017 0015 0017 003E 0017 0015 0017 003F 0015 0017 0017 003E 0017 003F 0015 003F 0017 0806" /* inverted command byte + stop bit */ - , 0); // No repeat possible, because of missing repeat pattern - - delay(5000); -} diff --git a/IRremote/examples/SendRawDemo/PinDefinitionsAndMore.h b/IRremote/examples/SendRawDemo/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendRawDemo/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SendRawDemo/SendRawDemo.ino b/IRremote/examples/SendRawDemo/SendRawDemo.ino deleted file mode 100644 index 351148adaedeccd9fca067afac2d1d339ae4074f..0000000000000000000000000000000000000000 --- a/IRremote/examples/SendRawDemo/SendRawDemo.ino +++ /dev/null @@ -1,120 +0,0 @@ -/* - * SendRawDemo.cpp - demonstrates sending IR codes with sendRaw - * - * This example shows how to send a RAW signal using the IRremote library. - * The example signal is actually a 32 bit NEC signal. - * Remote Control button: LGTV Power On/Off. - * Hex Value: 0x20DF10EF, 32 bits - * - * If it is a supported protocol, it is more efficient to use the protocol send function - * (here sendNEC) to send the signal. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -#define DISABLE_CODE_FOR_RECEIVER // Disables restarting receiver after each send. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not used. - -//#define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM. -//#define USE_NO_SEND_PWM // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition -//#define NO_LED_FEEDBACK_CODE // Saves 566 bytes program memory -//#define USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN // Use or simulate open drain output mode at send pin. Attention, active state of open drain is LOW, so connect the send LED between positive supply and send pin! - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -#include <IRremote.hpp> - -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - Serial.println(F("Send IR signals at pin " STR(IR_SEND_PIN))); - - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin -} - -/* - * NEC address=0xFB0C, command=0x18 - * - * This is data in byte format. - * The uint8_t/byte elements contain the number of ticks in 50 us. - * The uint16_t format contains the (number of ticks * 50) if generated by IRremote, - * so the uint16_t format has exact the same resolution but requires double space. - * With the uint16_t format, you are able to modify the timings to meet the standards, - * e.g. use 560 (instead of 11 * 50) for NEC or use 432 for Panasonic. But in this cases, - * you better use the timing generation functions e.g. sendNEC() directly. - */ -const uint8_t rawDataP[] -#if defined(__AVR__) -PROGMEM -#endif -= { 180, 90 /*Start bit*/, 11, 11, 11, 11, 11, 34, 11, 34/*0011 0xC of 16 bit address LSB first*/, 11, 11, 11, 11, 11, 11, 11, - 11/*0000*/, 11, 34, 11, 34, 11, 11, 11, 34/*1101 0xB*/, 11, 34, 11, 34, 11, 34, 11, 34/*1111*/, 11, 11, 11, 11, 11, 11, 11, - 34/*0001 0x08 of command LSB first*/, 11, 34, 11, 11, 11, 11, 11, 11/*1000 0x01*/, 11, 34, 11, 34, 11, 34, 11, - 11/*1110 Inverted 8 of command*/, 11, 11, 11, 34, 11, 34, 11, 34/*0111 inverted 1 of command*/, 11 /*stop bit*/}; - -void loop() { - -#if !(defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)) - /* - * Send hand crafted data from RAM - * The values are NOT multiple of 50, but are taken from the NEC timing definitions - */ - Serial.println(F("Send NEC 16 bit address=0xFB04 and command 0x08 with exact timing (16 bit array format)")); - Serial.flush(); - - const uint16_t rawData[] = { 9000, 4500/*Start bit*/, 560, 560, 560, 560, 560, 1690, 560, - 560/*0010 0x4 of 16 bit address LSB first*/, 560, 560, 560, 560, 560, 560, 560, 560/*0000*/, 560, 1690, 560, 1690, 560, - 560, 560, 1690/*1101 0xB*/, 560, 1690, 560, 1690, 560, 1690, 560, 1690/*1111*/, 560, 560, 560, 560, 560, 560, 560, - 1690/*0001 0x08 of command LSB first*/, 560, 560, 560, 560, 560, 560, 560, 560/*0000 0x00*/, 560, 1690, 560, 1690, 560, - 1690, 560, 560/*1110 Inverted 8 of command*/, 560, 1690, 560, 1690, 560, 1690, 560, 1690/*1111 inverted 0 of command*/, - 560 /*stop bit*/}; // Using exact NEC timing - IrSender.sendRaw(rawData, sizeof(rawData) / sizeof(rawData[0]), NEC_KHZ); // Note the approach used to automatically calculate the size of the array. - - delay(1000); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal -#endif - - /* - * Send byte data direct from FLASH - * Note the approach used to automatically calculate the size of the array. - */ - Serial.println(F("Send NEC 16 bit address 0xFB0C and data 0x18 with (50 us) tick resolution timing (8 bit array format) ")); - Serial.flush(); - IrSender.sendRaw_P(rawDataP, sizeof(rawDataP) / sizeof(rawDataP[0]), NEC_KHZ); - - delay(1000); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal - - Serial.println(F("Send NEC 16 bit address 0x0102, 8 bit data 0x34 with generated timing")); - Serial.flush(); - IrSender.sendNEC(0x0102, 0x34, 0); - - delay(3000); -} diff --git a/IRremote/examples/SimpleReceiver/PinDefinitionsAndMore.h b/IRremote/examples/SimpleReceiver/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SimpleReceiver/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SimpleReceiver/SimpleReceiver.ino b/IRremote/examples/SimpleReceiver/SimpleReceiver.ino deleted file mode 100644 index 12b950b2c4970338d4174f8c4e5e020abe0bef3a..0000000000000000000000000000000000000000 --- a/IRremote/examples/SimpleReceiver/SimpleReceiver.ino +++ /dev/null @@ -1,123 +0,0 @@ -/* - * SimpleReceiver.cpp - * - * Demonstrates receiving NEC IR codes with IRremote - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -/* - * Specify which protocol(s) should be used for decoding. - * If no protocol is defined, all protocols (except Bang&Olufsen) are active. - * This must be done before the #include <IRremote.hpp> - */ -//#define DECODE_DENON // Includes Sharp -//#define DECODE_JVC -//#define DECODE_KASEIKYO -//#define DECODE_PANASONIC // alias for DECODE_KASEIKYO -//#define DECODE_LG -#define DECODE_NEC // Includes Apple and Onkyo -//#define DECODE_SAMSUNG -//#define DECODE_SONY -//#define DECODE_RC5 -//#define DECODE_RC6 - -//#define DECODE_BOSEWAVE -//#define DECODE_LEGO_PF -//#define DECODE_MAGIQUEST -//#define DECODE_WHYNTER -//#define DECODE_FAST - -//#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols -//#define DECODE_HASH // special decoder for all protocols - -//#define DECODE_BEO // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined. It prevents decoding of SONY! - -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. - -//#define RAW_BUFFER_LENGTH 180 // Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. - -#include <Arduino.h> - -/* - * This include defines the actual pin number for pins like IR_RECEIVE_PIN, IR_SEND_PIN for many different boards and architectures - */ -#include "PinDefinitionsAndMore.h" -#include <IRremote.hpp> // include the library - -void setup() { - Serial.begin(115200); - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); -} - -void loop() { - /* - * Check if received data is available and if yes, try to decode it. - * Decoded result is in the IrReceiver.decodedIRData structure. - * - * E.g. command is in IrReceiver.decodedIRData.command - * address is in command is in IrReceiver.decodedIRData.address - * and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData - */ - if (IrReceiver.decode()) { - - /* - * Print a short summary of received data - */ - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); - if (IrReceiver.decodedIRData.protocol == UNKNOWN) { - Serial.println(F("Received noise or an unknown (or not yet enabled) protocol")); - // We have an unknown protocol here, print more info - IrReceiver.printIRResultRawFormatted(&Serial, true); - } - Serial.println(); - - /* - * !!!Important!!! Enable receiving of the next value, - * since receiving has stopped after the end of the current received data packet. - */ - IrReceiver.resume(); // Enable receiving of the next value - - /* - * Finally, check the received data and perform actions according to the received command - */ - if (IrReceiver.decodedIRData.command == 0x10) { - // do something - } else if (IrReceiver.decodedIRData.command == 0x11) { - // do something else - } - } -} diff --git a/IRremote/examples/SimpleReceiverWithCallback/PinDefinitionsAndMore.h b/IRremote/examples/SimpleReceiverWithCallback/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SimpleReceiverWithCallback/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SimpleReceiverWithCallback/SimpleReceiverWithCallback.ino b/IRremote/examples/SimpleReceiverWithCallback/SimpleReceiverWithCallback.ino deleted file mode 100644 index 3c1a3f40a876fdce474005ec16c3aa4d4fb09204..0000000000000000000000000000000000000000 --- a/IRremote/examples/SimpleReceiverWithCallback/SimpleReceiverWithCallback.ino +++ /dev/null @@ -1,158 +0,0 @@ -/* - * SimpleReceiverWithCallback.cpp - * - * Demonstrates receiving NEC IR codes with IRrecv - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -/* - * Specify which protocol(s) should be used for decoding. - * If no protocol is defined, all protocols (except Bang&Olufsen) are active. - * This must be done before the #include <IRremote.hpp> - */ -//#define DECODE_DENON // Includes Sharp -//#define DECODE_JVC -//#define DECODE_KASEIKYO -//#define DECODE_PANASONIC // alias for DECODE_KASEIKYO -//#define DECODE_LG -#define DECODE_NEC // Includes Apple and Onkyo -//#define DECODE_SAMSUNG -//#define DECODE_SONY -//#define DECODE_RC5 -//#define DECODE_RC6 - -//#define DECODE_BOSEWAVE -//#define DECODE_LEGO_PF -//#define DECODE_MAGIQUEST -//#define DECODE_WHYNTER -//#define DECODE_FAST - -//#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols -//#define DECODE_HASH // special decoder for all protocols - -//#define DECODE_BEO // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined. It prevents decoding of SONY! - -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. - -//#define RAW_BUFFER_LENGTH 180 // Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. - -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. -#include <IRremote.hpp> - -/* - * For callback - */ -#define PROCESS_IR_RESULT_IN_MAIN_LOOP -#if defined(PROCESS_IR_RESULT_IN_MAIN_LOOP) || defined(ARDUINO_ARCH_MBED) || defined(ESP32) -volatile bool sIRDataJustReceived = false; -#endif -void ReceiveCompleteCallbackHandler(); - -void setup() { - Serial.begin(115200); - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - IrReceiver.registerReceiveCompleteCallback(ReceiveCompleteCallbackHandler); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols (&Serial); - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); -} - -void loop() { - /* - * Print in loop (interrupts are enabled here) if received data is available. - */ - if (sIRDataJustReceived) { - // Print a short summary of received data - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); - if (IrReceiver.decodedIRData.protocol == UNKNOWN) { - Serial.println(F("Received noise or an unknown (or not yet enabled) protocol")); - /* - * We have an unknown protocol here, print more info. - * !!!Attention!!! This prints incorrect values, if we are late (not in this simple example :-)) - * and the the first mark of the next (repeat) data was yet received - */ - IrReceiver.printIRResultRawFormatted(&Serial, true); // - } - Serial.println(); - } -} - -/* - * Callback function - * Here we know, that data is available. - * This function is executed in ISR (Interrupt Service Routine) context (interrupts are blocked here). - * Make it short and fast and keep in mind, that you can not use delay(), prints longer than print buffer size etc., - * because they require interrupts enabled to return. - * In order to enable other interrupts you can call sei() (enable interrupt again) after evaluating/copying data. - * Good practice, but somewhat more complex, is to copy relevant data and signal receiving to main loop. - */ -#if defined(ESP32) || defined(ESP8266) -IRAM_ATTR -# endif -void ReceiveCompleteCallbackHandler() { - IrReceiver.decode(); // fill IrReceiver.decodedIRData - - /* - * Check the received data and perform actions according to the received command - * Decoded result is in the IrReceiver.decodedIRData structure. - * - * E.g. command is in IrReceiver.decodedIRData.command, - * address is in command is in IrReceiver.decodedIRData.address - * and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData - */ - if (IrReceiver.decodedIRData.command == 0x10) { - // do something SHORT here - } else if (IrReceiver.decodedIRData.command == 0x11) { - // do something SHORT here too - } - - /* - * Set flag to trigger printing of results in main loop, - * since printing should not be done in a callback function - * running in ISR (Interrupt Service Routine) context where interrupts are disabled. - */ - sIRDataJustReceived = true; - - /* - * Enable receiving of the next value. - * !!!Attention!!! - * After receiving the first mark of the next (repeat) data, 3 variables required for printing are reset/overwritten. - * - IrReceiver.irparams.rawlen - * - IrReceiver.irparams.rawbuf[0] - * - IrReceiver.irparams.OverflowFlag) - */ - IrReceiver.resume(); -} diff --git a/IRremote/examples/SimpleSender/PinDefinitionsAndMore.h b/IRremote/examples/SimpleSender/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/SimpleSender/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/SimpleSender/SimpleSender.ino b/IRremote/examples/SimpleSender/SimpleSender.ino deleted file mode 100644 index 0ea7ece3c7d4b4378ec1006420572e1f14e41518..0000000000000000000000000000000000000000 --- a/IRremote/examples/SimpleSender/SimpleSender.ino +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SimpleSender.cpp - * - * Demonstrates sending IR codes in standard format with address and command - * An extended example for sending can be found as SendDemo. - * - * Copyright (C) 2020-2022 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * MIT License - */ -#include <Arduino.h> - -#define DISABLE_CODE_FOR_RECEIVER // Disables restarting receiver after each send. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not used. -//#define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM. -//#define USE_NO_SEND_PWM // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition - -/* - * This include defines the actual pin number for pins like IR_RECEIVE_PIN, IR_SEND_PIN for many different boards and architectures - */ -#include "PinDefinitionsAndMore.h" -#include <IRremote.hpp> // include the library - -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - - Serial.begin(115200); - - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - Serial.print(F("Send IR signals at pin ")); - Serial.println(IR_SEND_PIN); - - /* - * The IR library setup. That's all! - */ -// IrSender.begin(); // Start with IR_SEND_PIN as send pin and if NO_LED_FEEDBACK_CODE is NOT defined, enable feedback LED at default feedback LED pin - IrSender.begin(DISABLE_LED_FEEDBACK); // Start with IR_SEND_PIN as send pin and disable feedback LED at default feedback LED pin -} - -/* - * Set up the data to be sent. - * For most protocols, the data is build up with a constant 8 (or 16 byte) address - * and a variable 8 bit command. - * There are exceptions like Sony and Denon, which have 5 bit address. - */ -uint8_t sCommand = 0x34; -uint8_t sRepeats = 0; - -void loop() { - /* - * Print current send values - */ - Serial.println(); - Serial.print(F("Send now: address=0x00, command=0x")); - Serial.print(sCommand, HEX); - Serial.print(F(", repeats=")); - Serial.print(sRepeats); - Serial.println(); - - Serial.println(F("Send standard NEC with 8 bit address")); - Serial.flush(); - - // Receiver output for the first loop must be: Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 (32 bits) - IrSender.sendNEC(0x00, sCommand, sRepeats); - - /* - * Increment send values - */ - sCommand += 0x11; - sRepeats++; - // clip repeats at 4 - if (sRepeats > 4) { - sRepeats = 4; - } - - delay(1000); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal -} diff --git a/IRremote/examples/TinyReceiver/TinyReceiver.ino b/IRremote/examples/TinyReceiver/TinyReceiver.ino deleted file mode 100644 index cbf6188f33f1d4606d73680bdf227cf7a991d15b..0000000000000000000000000000000000000000 --- a/IRremote/examples/TinyReceiver/TinyReceiver.ino +++ /dev/null @@ -1,190 +0,0 @@ -/* - * TinyReceiver.cpp - * - * Small memory footprint and no timer usage! - * - * Receives IR protocol data of NEC protocol using pin change interrupts. - * On complete received IR command the function handleReceivedIRData(uint16_t aAddress, uint8_t aCommand, uint8_t aFlags) - * is called in Interrupt context but with interrupts being enabled to enable use of delay() etc. - * !!!!!!!!!!!!!!!!!!!!!! - * Functions called in interrupt context should be running as short as possible, - * so if you require longer action, save the data (address + command) and handle it in the main loop. - * !!!!!!!!!!!!!!!!!!!!! - * - * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header. - * FAST Protocol characteristics: - * - Bit timing is like NEC or JVC - * - The header is shorter, 3156 vs. 12500 - * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command, - * leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms. - * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance. - * - * - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -#include <Arduino.h> - -/* - * Set sensible receive pin for different CPU's - */ -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -/* - * This program runs on 1 MHz CPU clock :-) and is requires only 1550 bytes program memory using ATTiny core - */ -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut" - Saves up to 700 bytes program memory and 70 bytes RAM for ATtinyCore -# if defined(ARDUINO_AVR_DIGISPARKPRO) -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -# else -#define IR_RECEIVE_PIN 0 // PCINT0 -# endif -#elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) -#define IR_RECEIVE_PIN 10 -#elif (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)) -#define IR_RECEIVE_PIN 21 // INT0 -#elif defined(ESP8266) -#define IR_RECEIVE_PIN 14 // D5 -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_RECEIVE_PIN 8 -#elif defined(ESP32) -#define IR_RECEIVE_PIN 15 -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) -#define IR_RECEIVE_PIN 3 // GPIO15 Use pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // to be compatible with the Arduino Nano RP2040 Connect (pin3) -#else -#define IR_RECEIVE_PIN 2 // INT0 -//#define NO_LED_FEEDBACK_CODE // Activate this if you want to suppress LED feedback or if you do not have a LED. This saves 14 bytes code and 2 clock cycles per interrupt. -#endif - -//#define DEBUG // to see if attachInterrupt is used -//#define TRACE // to see the state of the ISR state machine - -/* - * Second: include the code and compile it. - */ -//#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory. -//#define USE_ONKYO_PROTOCOL // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. -//#define USE_FAST_PROTOCOL // Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC / ONKYO. -//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. -#include "TinyIRReceiver.hpp" - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif - -volatile struct TinyIRReceiverCallbackDataStruct sCallbackData; - -void setup() { - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino -#if defined(ESP8266) || defined(ESP32) - Serial.println(); -#endif - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_TINYIR)); - - // Enables the interrupt generation on change of IR input signal - if (!initPCIInterruptForTinyReceiver()) { - Serial.println(F("No interrupt available for pin " STR(IR_RECEIVE_PIN))); // optimized out by the compiler, if not required :-) - } -#if defined(USE_FAST_PROTOCOL) - Serial.println(F("Ready to receive Fast IR signals at pin " STR(IR_RECEIVE_PIN))); -#else - Serial.println(F("Ready to receive NEC IR signals at pin " STR(IR_RECEIVE_PIN))); -#endif -} - -void loop() { - if (sCallbackData.justWritten) { - sCallbackData.justWritten = false; -#if defined(USE_FAST_PROTOCOL) - Serial.print(F("Command=0x")); -#else - Serial.print(F("Address=0x")); - Serial.print(sCallbackData.Address, HEX); - Serial.print(F(" Command=0x")); -#endif - Serial.print(sCallbackData.Command, HEX); - if (sCallbackData.Flags == IRDATA_FLAGS_IS_REPEAT) { - Serial.print(F(" Repeat")); - } - if (sCallbackData.Flags == IRDATA_FLAGS_PARITY_FAILED) { - Serial.print(F(" Parity failed")); - } - Serial.println(); - } - /* - * Put your code here - */ -} - -/* - * This is the function, which is called if a complete command was received - * It runs in an ISR context with interrupts enabled, so functions like delay() etc. should work here - */ -#if defined(ESP8266) || defined(ESP32) -IRAM_ATTR -#endif - -#if defined(USE_FAST_PROTOCOL) -void handleReceivedTinyIRData(uint8_t aCommand, uint8_t aFlags) -#elif defined(USE_ONKYO_PROTOCOL) -void handleReceivedTinyIRData(uint16_t aAddress, uint16_t aCommand, uint8_t aFlags) -#else -void handleReceivedTinyIRData(uint8_t aAddress, uint8_t aCommand, uint8_t aFlags) -#endif - { -#if defined(ARDUINO_ARCH_MBED) || defined(ESP32) - // Copy data for main loop, this is the recommended way for handling a callback :-) -# if !defined(USE_FAST_PROTOCOL) - sCallbackData.Address = aAddress; -# endif - sCallbackData.Command = aCommand; - sCallbackData.Flags = aFlags; - sCallbackData.justWritten = true; -#else - /* - * Printing is not allowed in ISR context for any kind of RTOS - * For Mbed we get a kernel panic and "Error Message: Semaphore: 0x0, Not allowed in ISR context" for Serial.print() - * for ESP32 we get a "Guru Meditation Error: Core 1 panic'ed" (we also have an RTOS running!) - */ - // Print only very short output, since we are in an interrupt context and do not want to miss the next interrupts of the repeats coming soon -# if defined(USE_FAST_PROTOCOL) - printTinyReceiverResultMinimal(&Serial, aCommand, aFlags); -# else - printTinyReceiverResultMinimal(&Serial, aAddress, aCommand, aFlags); -# endif -#endif -} diff --git a/IRremote/examples/TinySender/TinySender.ino b/IRremote/examples/TinySender/TinySender.ino deleted file mode 100644 index 39ff3c4d721473cd45b62c0b3a2db2bc3fab717b..0000000000000000000000000000000000000000 --- a/IRremote/examples/TinySender/TinySender.ino +++ /dev/null @@ -1,121 +0,0 @@ -/* - * TinySender.cpp - * - * Example for sending FAST or NEC protocol using TinyIR. - * - * NEC protocol codes are sent in standard format with 8bit address and 8 bit command as in SimpleSender example. - * Saves 780 bytes program memory and 26 bytes RAM compared to SimpleSender, which does the same, but uses the IRRemote library (and is therefore much more flexible). - * - * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header. - * FAST Protocol characteristics: - * - Bit timing is like NEC or JVC - * - The header is shorter, 3156 vs. 12500 - * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command, - * leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms. - * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance. - * - * - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#include <Arduino.h> - -//#define USE_FAST_PROTOCOL // Use FAST protocol. No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command -//#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory. -//#define USE_ONKYO_PROTOCOL // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. -//#define USE_FAST_PROTOCOL // Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC. -//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. - -#include "TinyIRSender.hpp" - -#define IR_SEND_PIN 3 - -void setup() { - pinMode(LED_BUILTIN, OUTPUT); - - Serial.begin(115200); - - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_TINYIR)); - Serial.print(F("Send IR signals at pin ")); - Serial.println(IR_SEND_PIN); -} - -/* - * Set up the data to be sent. - * The compiler is intelligent and removes the code for 16 bit address handling if we call it with an uint8_t address :-). - * Using an uint16_t address or data requires additional 28 bytes program memory for NEC and 56 bytes program memory for FAST. - */ -uint8_t sAddress = 0x02; -//uint16_t sAddress = 0x02; -uint8_t sCommand = 0x34; -//uint16_t sCommand = 0x34; -uint8_t sRepeats = 0; - -void loop() { - /* - * Print current send values - */ - Serial.println(); - Serial.print(F("Send now:")); -#if defined(USE_FAST_PROTOCOL) - Serial.print(F(" address=0x")); - Serial.print(sAddress, HEX); -#endif - Serial.print(F(" command=0x")); - Serial.print(sCommand, HEX); - Serial.print(F(" repeats=")); - Serial.print(sRepeats); - Serial.println(); - -#if defined(USE_FAST_PROTOCOL) - Serial.println(F("Send FAST with 8 bit address")); - Serial.flush(); - sendFAST(IR_SEND_PIN, sCommand, sRepeats); -#elif defined(USE_ONKYO_PROTOCOL) - Serial.println(F("Send ONKYO with 16 bit address and command")); - Serial.flush(); - sendONKYO(IR_SEND_PIN, sAddress, sCommand, sRepeats); -#else - Serial.println(F("Send NEC with 8 bit address")); - Serial.flush(); - sendNEC(IR_SEND_PIN, sAddress, sCommand, sRepeats); -#endif - /* - * Increment send values - * Also increment address just for demonstration, which normally makes no sense - */ - sAddress += 0x0101; - sCommand += 0x11; - sRepeats++; - // clip repeats at 4 - if (sRepeats > 4) { - sRepeats = 4; - } - - delay(1000); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal -} diff --git a/IRremote/examples/UnitTest/PinDefinitionsAndMore.h b/IRremote/examples/UnitTest/PinDefinitionsAndMore.h deleted file mode 100644 index aa85fdddf0dcd99801c15c24e73e380797549b84..0000000000000000000000000000000000000000 --- a/IRremote/examples/UnitTest/PinDefinitionsAndMore.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PinDefinitionsAndMore.h - * - * Contains pin definitions for IRremote examples for various platforms - * as well as definitions for feedback LED and tone() and includes - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * Arduino-IRremote is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -/* - * Pin mapping table for different platforms - * - * Platform IR input IR output Tone Core/Pin schema - * -------------------------------------------------------------- - * DEFAULT/AVR 2 3 4 Arduino - * ATtinyX5 0|PB0 4|PB4 3|PB3 ATTinyCore - * ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore - * ATtiny167 9|PA3 8|PA2 5|PA7 Digispark original core - * ATtiny84 |PB2 |PA4 |PA3 ATTinyCore - * ATtiny88 3|PD3 4|PD4 9|PB1 ATTinyCore - * ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore - * ATtiny1604 2 3|PA5 % - * ATtiny816 14|PA1 16|PA3 1|PA5 MegaTinyCore - * ATtiny1614 8|PA1 10|PA3 1|PA5 MegaTinyCore - * SAMD21 3 4 5 - * ESP8266 14|D5 12|D6 % - * ESP32 15 4 27 - * BluePill PA6 PA7 PA3 - * APOLLO3 11 12 5 - * RP2040 3|GPIO15 4|GPIO16 5|GPIO17 - */ -//#define _IR_MEASURE_TIMING // For debugging purposes. - -#if defined(__AVR__) -#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // TX is at pin 2 - Available as Arduino library "ATtinySerialOut". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore. -#define IR_RECEIVE_PIN PIN_PB0 -#define IR_SEND_PIN PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board. -#define TONE_PIN PIN_PB3 -#define _IR_TIMING_TEST_PIN PIN_PB3 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut" -// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source. -# if defined(ARDUINO_AVR_DIGISPARKPRO) -// For use with Digispark original core -#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9 -//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8 -#define TONE_PIN 5 // PA7 - on Digispark board labeled as pin 5 -#define _IR_TIMING_TEST_PIN 10 // PA4 -# else -// For use with ATTinyCore -#define IR_RECEIVE_PIN PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards -#define IR_SEND_PIN PIN_PA2 // On Digispark board labeled as pin 8 -#define TONE_PIN PIN_PA7 // On Digispark board labeled as pin 5 -# endif - -# elif defined(__AVR_ATtiny84__) // For use with ATTinyCore -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -#define IR_RECEIVE_PIN PIN_PB2 // INT0 -#define IR_SEND_PIN PIN_PA4 -#define TONE_PIN PIN_PA3 -#define _IR_TIMING_TEST_PIN PIN_PA5 - -# elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board. For use with ATTinyCore. -#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory. -// Pin 6 is TX, pin 7 is RX -#define IR_RECEIVE_PIN PIN_PD3 // 3 - INT1 -#define IR_SEND_PIN PIN_PD4 // 4 -#define TONE_PIN PIN_PB1 // 9 -#define _IR_TIMING_TEST_PIN PIN_PB0 // 8 - -# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // For use with megaTinyCore -// Tiny Core Dev board -// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ -// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ -#define IR_RECEIVE_PIN PIN_PA1 // use 18 for TinyCore32 -#define IR_SEND_PIN PIN_PA2 // 19 -#define TONE_PIN PIN_PA3 // 20 -#define APPLICATION_PIN PIN_PA0 // 0 -#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output -#define LED_BUILTIN PIN_PA6 // use 2 for TinyCore32 - -# elif defined(__AVR_ATtiny816__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 14 -#define IR_SEND_PIN PIN_PA1 // 16 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 -#undef LED_BUILTIN // No LED available, take the one which is connected to the DAC output -#define LED_BUILTIN PIN_PB5 // 4 - -# elif defined(__AVR_ATtiny1614__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA1 // 8 -#define IR_SEND_PIN PIN_PA3 // 10 -#define TONE_PIN PIN_PA5 // 1 -#define APPLICATION_PIN PIN_PA4 // 0 - -# elif defined(__AVR_ATtiny1604__) // For use with megaTinyCore -#define IR_RECEIVE_PIN PIN_PA6 // 2 - To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN PIN_PA7 // 3 -#define APPLICATION_PIN PIN_PB2 // 5 - -#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone() -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 13 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc. -#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here. -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit -// We have no built in LED at pin 13 -> reuse RX LED -#undef LED_BUILTIN -#define LED_BUILTIN LED_BUILTIN_RX -# endif -# endif // defined(__AVR_ATtiny25__)... - -#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4 -// To be compatible with Uno R3. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ESP8266) -#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW -#define IR_RECEIVE_PIN 14 // D5 -#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED -#define _IR_TIMING_TEST_PIN 2 // D4 -#define APPLICATION_PIN 13 // D7 - -#define tone(...) void() // tone() inhibits receive timer -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#define IR_INPUT_PIN 8 -#define IR_SEND_PIN 9 -#define TONE_PIN 10 // ADC2_0 -#define APPLICATION_PIN 11 - -#elif defined(ESP32) -#include <Arduino.h> - -// tone() is included in ESP32 core since 2.0.2 -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678 -#endif -#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) -#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer. -void tone(uint8_t aPinNumber, unsigned int aFrequency){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); -} -void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){ - ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL); - ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency); - delay(aDuration); - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -void noTone(uint8_t aPinNumber){ - ledcWriteTone(TONE_LEDC_CHANNEL, 0); -} -#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2) - -#define IR_RECEIVE_PIN 15 // D15 -#define IR_SEND_PIN 4 // D4 -#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1 -#define APPLICATION_PIN 16 // RX2 pin - -#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill -// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone() -#define IR_RECEIVE_PIN PA6 -#define IR_RECEIVE_PIN_STRING "PA6" -#define IR_SEND_PIN PA7 -#define IR_SEND_PIN_STRING "PA7" -#define TONE_PIN PA3 -#define _IR_TIMING_TEST_PIN PA5 -#define APPLICATION_PIN PA2 -#define APPLICATION_PIN_STRING "PA2" -# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8) -// BluePill LED is active low -#define FEEDBACK_LED_IS_ACTIVE_LOW -# endif - -#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards -#define IR_RECEIVE_PIN 11 -#define IR_SEND_PIN 12 -#define TONE_PIN 5 - -#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico -#define IR_SEND_PIN 4 // GPIO16 -#define TONE_PIN 5 -#define APPLICATION_PIN 6 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 8 - -#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico -#define IR_RECEIVE_PIN 15 // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3) -#define IR_SEND_PIN 16 // GPIO16 -#define TONE_PIN 17 -#define APPLICATION_PIN 18 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 20 - -// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN -// and use the external reset with 1 kOhm to ground to enter UF2 mode -#undef LED_BUILTIN -#define LED_BUILTIN 6 - -#elif defined(PARTICLE) // !!!UNTESTED!!! -#define IR_RECEIVE_PIN A4 -#define IR_SEND_PIN A5 // Particle supports multiple pins - -#define LED_BUILTIN D7 - -/* - * 4 times the same (default) layout for easy adaption in the future - */ -#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc. -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 - -#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0) -// On the Zero and others we switch explicitly to SerialUSB -#define Serial SerialUSB -#endif - -// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17. -// Attention!!! D2 and D4 are swapped on these boards!!! -// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 24 // PB11 -// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines. -//#undef LED_BUILTIN -//#define LED_BUILTIN 25 // PB03 -//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW - -#elif defined (NRF51) // BBC micro:bit -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define APPLICATION_PIN 1 -#define _IR_TIMING_TEST_PIN 4 - -#define tone(...) void() // no tone() available -#define noTone(a) void() -#define TONE_PIN 42 // Dummy for examples using it - -#else -#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h. -// Default valued for unidentified boards -#define IR_RECEIVE_PIN 2 -#define IR_SEND_PIN 3 -#define TONE_PIN 4 -#define APPLICATION_PIN 5 -#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output. -#define _IR_TIMING_TEST_PIN 7 -#endif // defined(ESP8266) - -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED) -#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation -#else -# if defined(SEND_PWM_BY_TIMER) -#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp -# endif -#endif - -#if !defined (FLASHEND) -#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined -#endif -#if !defined (RAMEND) -#define RAMEND 0xFFFF // Dummy value for platforms where RAMEND is not defined -#endif -#if !defined (RAMSIZE) -#define RAMSIZE 0xFFFF // Dummy value for platforms where RAMSIZE is not defined -#endif - -/* - * Helper macro for getting a macro definition as string - */ -#if !defined(STR_HELPER) -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif diff --git a/IRremote/examples/UnitTest/UnitTest.ino b/IRremote/examples/UnitTest/UnitTest.ino deleted file mode 100644 index dfae7cb5feca101b9b95dd3683381d805a2b3d58..0000000000000000000000000000000000000000 --- a/IRremote/examples/UnitTest/UnitTest.ino +++ /dev/null @@ -1,812 +0,0 @@ -/* - * UnitTest.cpp - * - * Demonstrates sending IR codes in standard format with address and command and - * simultaneously receiving. Both values are checked for consistency. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -#include <Arduino.h> - -#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. - -#if !defined(RAW_BUFFER_LENGTH) -# if RAMEND <= 0x4FF || RAMSIZE < 0x4FF -//#define RAW_BUFFER_LENGTH 180 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# elif RAMEND <= 0x8FF || RAMSIZE < 0x8FF -#define RAW_BUFFER_LENGTH 150 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# else -#define RAW_BUFFER_LENGTH 200 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100. -# endif -#endif - -//#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. -//#define EXCLUDE_EXOTIC_PROTOCOLS // Saves around 240 bytes program memory if IrSender.write is used -//#define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM. -//#define USE_NO_SEND_PWM // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition -#define NO_LED_FEEDBACK_CODE // Saves 344 bytes program memory -// MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, -//#define USE_MSB_DECODING_FOR_DISTANCE_DECODER -// to compensate for the signal forming of different IR receiver modules. See also IRremote.hpp line 142. -//#define MARK_EXCESS_MICROS 20 // Adapt it to your IR receiver module. 40 is taken for the cheap VS1838 module her, since we have high intensity. - -//#define TRACE // For internal usage -//#define DEBUG // Activate this for lots of lovely debug output from the decoders. - -#if FLASHEND >= 0x1FFF // For 8k flash or more, like ATtiny85 -#define DECODE_DENON // Includes Sharp -#define DECODE_KASEIKYO -#define DECODE_PANASONIC // alias for DECODE_KASEIKYO -#define DECODE_NEC // Includes Apple and Onkyo -#endif - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 -#define DECODE_JVC -#define DECODE_RC5 -#define DECODE_RC6 - -#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols -#define DECODE_HASH // special decoder for all protocols -#endif - -#if FLASHEND >= 0x7FFF // For 32k flash or more, like ATmega328 -#define DECODE_SONY -#define DECODE_SAMSUNG -#define DECODE_LG - -#define DECODE_BEO // It prevents decoding of SONY (default repeats), which we are not using here. -//#define ENABLE_BEO_WITHOUT_FRAME_GAP // For successful unit testing we must see the warning at ir_BangOlufsen.hpp:88:2 -#if defined(DECODE_BEO) -#define RECORD_GAP_MICROS 16000 // always get the complete frame in the receive buffer -#define BEO_KHZ 38 // We send and receive Bang&Olufsen with 38 kHz here (instead of 455 kHz). -#endif - -#define DECODE_BOSEWAVE -//#define DECODE_LEGO_PF -#define DECODE_MAGIQUEST -//#define DECODE_WHYNTER -#define DECODE_FAST -#endif - -#include <IRremote.hpp> - -#if defined(APPLICATION_PIN) -#define DEBUG_BUTTON_PIN APPLICATION_PIN // if held low, print timing for each received data -#else -#define DEBUG_BUTTON_PIN 6 -#endif - -#define DELAY_AFTER_SEND 1000 -#define DELAY_AFTER_LOOP 5000 - -#if defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER) -#error Unit test cannot run if SEND_PWM_BY_TIMER is enabled i.e. receive timer us also used by send -#endif - -/* - * For callback - */ -volatile bool sDataJustReceived = false; -void ReceiveCompleteCallbackHandler(); - -void setup() { - pinMode(DEBUG_BUTTON_PIN, INPUT_PULLUP); - - Serial.begin(115200); -#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217) - delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! -#endif - // Just to know which program is running on my Arduino - Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); - - // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED - IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); - IrReceiver.registerReceiveCompleteCallback(ReceiveCompleteCallbackHandler); - - Serial.print(F("Ready to receive IR signals of protocols: ")); - printActiveIRProtocols(&Serial); -#if defined(IR_RECEIVE_PIN_STRING) - Serial.println(F("at pin " IR_RECEIVE_PIN_STRING)); -#else - Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); -#endif - -#if defined(IR_SEND_PIN) - IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin -# if defined(IR_SEND_PIN_STRING) - Serial.println(F("at pin " IR_SEND_PIN_STRING)); -# else - Serial.println(F("Send IR signals at pin " STR(IR_SEND_PIN))); -# endif -#else - IrSender.begin(3, ENABLE_LED_FEEDBACK, USE_DEFAULT_FEEDBACK_LED_PIN); // Specify send pin and enable feedback LED at default feedback LED pin - Serial.println(F("Send IR signals at pin 3")); -#endif - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - Serial.print(F("If you connect debug pin ")); -# if defined(APPLICATION_PIN_STRING) - Serial.print(APPLICATION_PIN_STRING); -# else - Serial.print(DEBUG_BUTTON_PIN); -# endif - Serial.println(F(" to ground, raw data is always printed")); - - // For esp32 we use PWM generation by ledcWrite() for each pin. -# if !defined(SEND_PWM_BY_TIMER) - /* - * Print internal software PWM generation info - */ - IrSender.enableIROut(38); // Call it with 38 kHz to initialize the values printed below - Serial.print(F("Send signal mark duration for 38kHz is ")); - Serial.print(IrSender.periodOnTimeMicros); - Serial.print(F(" us, pulse narrowing correction is ")); - Serial.print(IrSender.getPulseCorrectionNanos()); - Serial.print(F(" ns, total period is ")); - Serial.print(IrSender.periodTimeMicros); - Serial.println(F(" us")); -# endif - - // infos for receive - Serial.print(RECORD_GAP_MICROS); - Serial.println(F(" us is the (minimum) gap, after which the start of a new IR packet is assumed")); - Serial.print(MARK_EXCESS_MICROS); - Serial.println(F(" us are subtracted from all marks and added to all spaces for decoding")); -#endif - delay(DELAY_AFTER_SEND); - -} - -void checkReceivedRawData(IRRawDataType aRawData) { - // wait until signal has received - while (!sDataJustReceived) { - }; - sDataJustReceived = false; - - if (IrReceiver.decode()) { -// Print a short summary of received data -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); -#else - IrReceiver.printIRResultMinimal(&Serial); -#endif -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - if (IrReceiver.decodedIRData.protocol == UNKNOWN || digitalRead(DEBUG_BUTTON_PIN) == LOW) { - // We have an unknown protocol, print more info - IrReceiver.printIRResultRawFormatted(&Serial, true); - } -#endif - if (IrReceiver.decodedIRData.protocol == PULSE_DISTANCE || IrReceiver.decodedIRData.protocol == PULSE_WIDTH) { - if (IrReceiver.decodedIRData.decodedRawData != aRawData) { - Serial.print(F("ERROR: Received data=0x")); -#if (__INT_WIDTH__ < 32) - Serial.print(IrReceiver.decodedIRData.decodedRawData, HEX); -#else - PrintULL::print(&Serial, IrReceiver.decodedIRData.decodedRawData, HEX); -#endif - Serial.print(F(" != sent data=0x")); -#if (__INT_WIDTH__ < 32) - Serial.print(aRawData, HEX); -#else - PrintULL::print(&Serial, aRawData, HEX); -#endif - Serial.println(); - } - } - IrReceiver.resume(); - } else { - Serial.println(F("No data received")); - } - Serial.println(); -} - -#if defined(DECODE_DISTANCE_WIDTH) -void checkReceivedArray(IRRawDataType *aRawDataArrayPointer, uint8_t aArraySize) { - // wait until signal has received - while (!sDataJustReceived) { - }; - sDataJustReceived = false; - - if (IrReceiver.decode()) { -// Print a short summary of received data -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); -#else - IrReceiver.printIRResultMinimal(&Serial); -#endif -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - if (IrReceiver.decodedIRData.protocol == UNKNOWN || digitalRead(DEBUG_BUTTON_PIN) == LOW) { - // We have an unknown protocol, print more info - IrReceiver.printIRResultRawFormatted(&Serial, true); - } -#endif - - if (IrReceiver.decodedIRData.protocol == PULSE_DISTANCE || IrReceiver.decodedIRData.protocol == PULSE_WIDTH) { - for (uint_fast8_t i = 0; i < aArraySize; ++i) { - if (IrReceiver.decodedIRData.decodedRawDataArray[i] != *aRawDataArrayPointer) { - Serial.print(F("ERROR: Received data=0x")); -# if (__INT_WIDTH__ < 32) - Serial.print(IrReceiver.decodedIRData.decodedRawDataArray[i], HEX); -# else - PrintULL::print(&Serial, IrReceiver.decodedIRData.decodedRawDataArray[i], HEX); -# endif - Serial.print(F(" != sent data=0x")); - Serial.println(*aRawDataArrayPointer, HEX); - } - aRawDataArrayPointer++; - } - } - IrReceiver.resume(); - } else { - Serial.println(F("No data received")); - } - Serial.println(); -} -#endif - -/* - * Test callback function - * Has the same functionality as available() - */ -void ReceiveCompleteCallbackHandler() { - sDataJustReceived = true; -} - -void checkReceive(uint16_t aSentAddress, uint16_t aSentCommand) { - // wait until signal has received - while (!sDataJustReceived) { - }; - sDataJustReceived = false; - - if (IrReceiver.decode()) { -// Print a short summary of received data -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - IrReceiver.printIRResultShort(&Serial); - IrReceiver.printIRSendUsage(&Serial); -#else - IrReceiver.printIRResultMinimal(&Serial); -#endif - - if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_WAS_OVERFLOW) { - Serial.println(F("Try to increase the \"RAW_BUFFER_LENGTH\" value of " STR(RAW_BUFFER_LENGTH) " in " __FILE__)); - // see also https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library - } - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604 - if (IrReceiver.decodedIRData.protocol == UNKNOWN || digitalRead(DEBUG_BUTTON_PIN) == LOW) { - // We have an unknown protocol, print more info - IrReceiver.printIRResultRawFormatted(&Serial, true); - } -#endif - if (IrReceiver.decodedIRData.protocol == UNKNOWN) { - Serial.println(F("ERROR: Unknown protocol")); - } else { - /* - * Check address - */ - if (IrReceiver.decodedIRData.address != aSentAddress) { - Serial.print(F("ERROR: Received address=0x")); - Serial.print(IrReceiver.decodedIRData.address, HEX); - Serial.print(F(" != sent address=0x")); - Serial.println(aSentAddress, HEX); - } - /* - * Check command - */ - if (IrReceiver.decodedIRData.command != aSentCommand) { - Serial.print(F("ERROR: Received command=0x")); - Serial.print(IrReceiver.decodedIRData.command, HEX); - Serial.print(F(" != sent command=0x")); - Serial.println(aSentCommand, HEX); - } - } - - IrReceiver.resume(); - } else { - Serial.println(F("No data received")); - } - Serial.println(); -} - -/* - * Set up the data to be sent. - * For most protocols, the data is build up with a constant 8 (or 16 byte) address - * and a variable 8 bit command. - * There are exceptions like Sony and Denon, which have 5 bit address. - */ -uint16_t sAddress = 0xFFF1; -uint8_t sCommand = 0x76; -uint16_t s16BitCommand = 0x9876; -#define sRepeats 0 // no unit test for repeats - -void loop() { - /* - * Print values - */ - Serial.println(); - Serial.print(F("address=0x")); - Serial.print(sAddress, HEX); - Serial.print(F(" command=0x")); - Serial.print(sCommand, HEX); - Serial.println(); - Serial.println(); - - Serial.println(F("Send NEC with 8 bit address")); - Serial.flush(); - IrSender.sendNEC(sAddress & 0xFF, sCommand, sRepeats); - checkReceive(sAddress & 0xFF, sCommand); - delay(DELAY_AFTER_SEND); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal - - Serial.println(F("Send NEC with 16 bit address")); - Serial.flush(); - IrSender.sendNEC(sAddress, sCommand, sRepeats); - checkReceive(sAddress, sCommand); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send NEC2 with 16 bit address")); - Serial.flush(); - IrSender.sendNEC2(sAddress, sCommand, sRepeats); - checkReceive(sAddress, sCommand); - delay(DELAY_AFTER_SEND); - -#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc. - - if (sAddress == 0xFFF1) { -# if FLASHEND >= 0x7FFF // For 32k flash or more, like Uno. Code does not fit in program memory of ATtiny1604 etc. - /* - * Send constant values only once in this demo - */ - Serial.println(F("Send NEC Pronto data with 8 bit address 0x80 and command 0x45 and no repeats")); - Serial.flush(); - IrSender.sendPronto(F("0000 006D 0022 0000 015E 00AB " /* Pronto header + start bit */ - "0017 0015 0017 0015 0017 0017 0015 0017 0017 0015 0017 0015 0017 0015 0017 003F " /* Lower address byte */ - "0017 003F 0017 003E 0017 003F 0015 003F 0017 003E 0017 003F 0017 003E 0017 0015 " /* Upper address byte (inverted at 8 bit mode) */ - "0017 003E 0017 0015 0017 003F 0017 0015 0017 0015 0017 0015 0017 003F 0017 0015 " /* command byte */ - "0019 0013 0019 003C 0017 0015 0017 003F 0017 003E 0017 003F 0017 0015 0017 003E " /* inverted command byte */ - "0017 0806"), 0); //stop bit, no repeat possible, because of missing repeat pattern - checkReceive(0x80, 0x45); - delay(DELAY_AFTER_SEND); - - Serial.println( - F("Send NEC sendRaw data with 8 bit address=0xFB04 and command 0x08 and exact timing (16 bit array format)")); - Serial.flush(); - const uint16_t irSignal[] = { 9000, 4500/*Start bit*/, 560, 560, 560, 560, 560, 1690, 560, - 560/*0010 0x4 of 16 bit address LSB first*/, 560, 560, 560, 560, 560, 560, 560, 560/*0000*/, 560, 1690, 560, 1690, - 560, 560, 560, 1690/*1101 0xB*/, 560, 1690, 560, 1690, 560, 1690, 560, 1690/*1111*/, 560, 560, 560, 560, 560, 560, - 560, 1690/*0001 0x08 of command LSB first*/, 560, 560, 560, 560, 560, 560, 560, 560/*0000 0x00*/, 560, 1690, 560, - 1690, 560, 1690, 560, 560/*1110 Inverted 8 of command*/, 560, 1690, 560, 1690, 560, 1690, 560, - 1690/*1111 inverted 0 of command*/, 560 /*stop bit*/}; // Using exact NEC timing - IrSender.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), NEC_KHZ); // Note the approach used to automatically calculate the size of the array. - checkReceive(0xFB04 & 0xFF, 0x08); - delay(DELAY_AFTER_SEND); - - /* - * With sendNECRaw() you can send 32 bit codes directly, i.e. without parity etc. - */ - Serial.println(F("Send ONKYO with 16 bit address 0x0102 and 16 bit command 0x0304 with NECRaw(0x03040102)")); - Serial.flush(); - IrSender.sendNECRaw(0x03040102, sRepeats); - checkReceive(0x0102, 0x304); - delay(DELAY_AFTER_SEND); - - /* - * With Send sendNECMSB() you can send your old 32 bit codes. - * To convert one into the other, you must reverse the byte positions and then reverse all positions of each byte. - * Example: - * 0xCB340102 byte reverse -> 0x020134CB bit reverse-> 40802CD3 - */ - Serial.println(F("Send ONKYO with 16 bit address 0x0102 and command 0x34 with old 32 bit format MSB first (0x40802CD3)")); - Serial.flush(); - IrSender.sendNECMSB(0x40802CD3, 32, false); - checkReceive(0x0102, 0x34); - delay(DELAY_AFTER_SEND); -# endif - -# if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO) - Serial.println(F("Send Panasonic 0xB, 0x10 as 48 bit generic PulseDistance using ProtocolConstants")); - Serial.flush(); -# if __INT_WIDTH__ < 32 - IRRawDataType tRawData[] = { 0xB02002, 0xA010, 0x0 }; // LSB of tRawData[0] is sent first - IrSender.sendPulseDistanceWidthFromArray(&KaseikyoProtocolConstants, &tRawData[0], 48, NO_REPEATS); // Panasonic is a Kaseikyo variant - checkReceive(0x0B, 0x10); -# else - IrSender.sendPulseDistanceWidth(&KaseikyoProtocolConstants, 0xA010B02002, 48, NO_REPEATS); // Panasonic is a Kaseikyo variant - checkReceivedRawData(0xA010B02002); -# endif - delay(DELAY_AFTER_SEND); - - /* - * Send 2 Panasonic 48 bit codes as generic Pulse Distance data, once with LSB and once with MSB first - */ - Serial.println(F("Send Panasonic 0xB, 0x10 as generic 48 bit PulseDistance")); - Serial.println(F(" LSB first")); - Serial.flush(); -# if __INT_WIDTH__ < 32 - IrSender.sendPulseDistanceWidthFromArray(38, 3450, 1700, 450, 1250, 450, 400, &tRawData[0], 48, PROTOCOL_IS_LSB_FIRST, 0, - NO_REPEATS); - checkReceive(0x0B, 0x10); -# else - IrSender.sendPulseDistanceWidth(38, 3450, 1700, 450, 1250, 450, 400, 0xA010B02002, 48, PROTOCOL_IS_LSB_FIRST, - 0, NO_REPEATS); - checkReceivedRawData(0xA010B02002); -# endif - delay(DELAY_AFTER_SEND); - - // The same with MSB first. Use bit reversed raw data of LSB first part - Serial.println(F(" MSB first")); -# if __INT_WIDTH__ < 32 - tRawData[0] = 0x40040D00; // MSB of tRawData[0] is sent first - tRawData[1] = 0x805; - IrSender.sendPulseDistanceWidthFromArray(38, 3450, 1700, 450, 1250, 450, 400, &tRawData[0], 48, PROTOCOL_IS_MSB_FIRST, 0, - NO_REPEATS); - checkReceive(0x0B, 0x10); -# else - IrSender.sendPulseDistanceWidth(38, 3450, 1700, 450, 1250, 450, 400, 0x40040D000805, 48, PROTOCOL_IS_MSB_FIRST, 0, NO_REPEATS); - checkReceivedRawData(0x40040D000805); -# endif - - delay(DELAY_AFTER_SEND); -# endif // defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO) - -# if defined(DECODE_DISTANCE_WIDTH) -# if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER) - Serial.println(F("Send generic 52 bit PulseDistance 0x43D8613C and 0x3BC3B MSB first")); - Serial.flush(); -# if __INT_WIDTH__ < 32 - tRawData[0] = 0x43D8613C; // MSB of tRawData[0] is sent first - tRawData[1] = 0x3BC3B; - IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1700, 550, 600, &tRawData[0], 52, PROTOCOL_IS_MSB_FIRST, 0, - NO_REPEATS); - checkReceivedArray(tRawData, 2); -# else - IrSender.sendPulseDistanceWidth(38, 8900, 4450, 550, 1700, 550, 600, 0x43D8613CBC3B, 52, PROTOCOL_IS_MSB_FIRST, 0, NO_REPEATS); - checkReceivedRawData(0x43D8613CBC3B); -# endif - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send generic 52 bit PulseDistanceWidth 0x43D8613C and 0x3BC3B MSB first")); - Serial.flush(); - // Real PulseDistanceWidth (constant bit length) does not require a stop bit -# if __INT_WIDTH__ < 32 - IrSender.sendPulseDistanceWidthFromArray(38, 300, 600, 600, 300, 300, 600, &tRawData[0], 52, PROTOCOL_IS_MSB_FIRST, 0, 0); - checkReceivedArray(tRawData, 2); -# else - IrSender.sendPulseDistanceWidth(38, 300, 600, 600, 300, 300, 600, 0x123456789ABC, 52, PROTOCOL_IS_MSB_FIRST, 0, 0); - checkReceivedRawData(0x123456789ABC); -# endif - delay(DELAY_AFTER_SEND); - Serial.println(F("Send generic 32 bit PulseWidth 0x43D8613C MSB first")); - Serial.flush(); - // Real PulseDistanceWidth (constant bit length) does not require a stop bit - IrSender.sendPulseDistanceWidth(38, 1000, 500, 600, 300, 300, 300, 0x43D8613C, 32, PROTOCOL_IS_MSB_FIRST, 0, 0); - checkReceivedRawData(0x43D8613C); - delay(DELAY_AFTER_SEND); - -# else // defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER) - Serial.println(F("Send generic 72 bit PulseDistance 0x5A AFEDCBA9 87654321 LSB first")); - Serial.flush(); -# if __INT_WIDTH__ < 32 - tRawData[0] = 0x87654321; // LSB of tRawData[0] is sent first - tRawData[1] = 0xAFEDCBA9; - tRawData[2] = 0x5A; - IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1700, 550, 600, &tRawData[0], 72, PROTOCOL_IS_LSB_FIRST, 0, - NO_REPEATS); - checkReceivedArray(tRawData, 3); -# else - IRRawDataType tRawData[] = { 0xAFEDCBA987654321, 0x5A }; // LSB of tRawData[0] is sent first - IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1700, 550, 600, &tRawData[0], 72, PROTOCOL_IS_LSB_FIRST, 0, NO_REPEATS); - checkReceivedArray(tRawData, 2); -# endif - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send generic 52 bit PulseDistanceWidth 0xDCBA9 87654321 LSB first")); - Serial.flush(); - // Real PulseDistanceWidth (constant bit length) does not require a stop bit -# if __INT_WIDTH__ < 32 - tRawData[1] = 0xDCBA9; - IrSender.sendPulseDistanceWidthFromArray(38, 300, 600, 600, 300, 300, 600, &tRawData[0], 52, PROTOCOL_IS_LSB_FIRST, 0, 0); - checkReceivedArray(tRawData, 2); -# else - IrSender.sendPulseDistanceWidth(38, 300, 600, 600, 300, 300, 600, 0xDCBA987654321, 52, PROTOCOL_IS_LSB_FIRST, 0, 0); - checkReceivedRawData(0xDCBA987654321); -# endif - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send generic 32 bit PulseWidth 0x87654321 LSB first")); - Serial.flush(); - // Real PulseDistanceWidth (constant bit length) does not require a stop bit - IrSender.sendPulseDistanceWidth(38, 1000, 500, 600, 300, 300, 300, 0x87654321, 32, PROTOCOL_IS_LSB_FIRST, 0, 0); - checkReceivedRawData(0x87654321); - delay(DELAY_AFTER_SEND); -# endif // defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER) -# endif // defined(DECODE_DISTANCE_WIDTH) - -# if defined(DECODE_MAGIQUEST) - Serial.println(F("Send MagiQuest 0x6BCDFF00, 0x176 as generic 55 bit PulseDistanceWidth MSB first")); - Serial.flush(); -# if __INT_WIDTH__ < 32 - tRawData[0] = 0x01AF37FC; // We have 1 header (start) bit and 7 start bits and 31 address bits for MagiQuest, so 0x6BCDFF00 is shifted 2 left - tRawData[1] = 0x017619; // We send only 23 instead of 24 bite here! 19 is the checksum - IrSender.sendPulseDistanceWidthFromArray(38, 287, 864, 576, 576, 287, 864, &tRawData[0], 55, PROTOCOL_IS_MSB_FIRST, 0, 0); -# else - // 0xD79BFE00 is 0x6BCDFF00 is shifted 1 left - IrSender.sendPulseDistanceWidth(38, 287, 864, 576, 576, 287, 864, 0xD79BFE017619, 55, PROTOCOL_IS_MSB_FIRST, 0, 0); -# endif - checkReceive(0xFF00, 0x176); - if (IrReceiver.decodedIRData.decodedRawData != 0x6BCDFF00) { - Serial.print(F("ERROR: Received address=0x")); -#if (__INT_WIDTH__ < 32) - Serial.print(IrReceiver.decodedIRData.decodedRawData, HEX); -#else - PrintULL::print(&Serial, IrReceiver.decodedIRData.decodedRawData, HEX); -#endif - Serial.println(F(" != sent address=0x6BCDFF00")); - Serial.println(); - } - delay(DELAY_AFTER_SEND); -# endif // defined(DECODE_MAGIQUEST) - - } -#endif // if FLASHEND >= 0x3FFF - - Serial.println(F("Send Onkyo (NEC with 16 bit command)")); - Serial.flush(); - IrSender.sendOnkyo(sAddress, (sCommand + 1) << 8 | sCommand, sRepeats); - checkReceive(sAddress, (sCommand + 1) << 8 | sCommand); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Apple")); - Serial.flush(); - IrSender.sendApple(sAddress & 0xFF, sCommand, sRepeats); - checkReceive(sAddress & 0xFF, sCommand); - delay(DELAY_AFTER_SEND); - -#if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO) - Serial.println(F("Send Panasonic")); - Serial.flush(); - IrSender.sendPanasonic(sAddress & 0xFFF, sCommand, sRepeats); - checkReceive(sAddress & 0xFFF, sCommand); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Kaseikyo with 0x4711 as Vendor ID")); - Serial.flush(); - IrSender.sendKaseikyo(sAddress & 0xFFF, sCommand, sRepeats, 0x4711); - checkReceive(sAddress & 0xFFF, sCommand); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Kaseikyo_Denon variant")); - Serial.flush(); - IrSender.sendKaseikyo_Denon(sAddress & 0xFFF, sCommand, sRepeats); - checkReceive(sAddress & 0xFFF, sCommand); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_DENON) - Serial.println(F("Send Denon")); - Serial.flush(); - IrSender.sendDenon(sAddress & 0x1F, sCommand, sRepeats); - checkReceive(sAddress & 0x1F, sCommand); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Denon/Sharp variant")); - Serial.flush(); - IrSender.sendSharp(sAddress & 0x1F, sCommand, sRepeats); - checkReceive(sAddress & 0x1F, sCommand); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_SONY) - Serial.println(F("Send Sony/SIRCS with 7 command and 5 address bits")); - Serial.flush(); - IrSender.sendSony(sAddress & 0x1F, sCommand, sRepeats); - checkReceive(sAddress & 0x1F, sCommand & 0x7F); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Sony/SIRCS with 7 command and 8 address bits")); - Serial.flush(); - IrSender.sendSony(sAddress & 0xFF, sCommand, sRepeats, SIRCS_15_PROTOCOL); - checkReceive(sAddress & 0xFF, sCommand & 0x7F); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Sony/SIRCS with 7 command and 13 address bits")); - Serial.flush(); - IrSender.sendSony(sAddress & 0x1FFF, sCommand, sRepeats, SIRCS_20_PROTOCOL); - checkReceive(sAddress & 0x1FFF, sCommand & 0x7F); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_SAMSUNG) - Serial.println(F("Send Samsung 8 bit command")); - Serial.flush(); - IrSender.sendSamsung(sAddress, sCommand, sRepeats); - checkReceive(sAddress, sCommand); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Samsung 16 bit command")); - Serial.flush(); - IrSender.sendSamsung(sAddress, s16BitCommand, sRepeats); - checkReceive(sAddress, s16BitCommand); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send Samsung48 16 bit command")); - Serial.flush(); - IrSender.sendSamsung48(sAddress, s16BitCommand, sRepeats); - checkReceive(sAddress, s16BitCommand); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_RC5) - Serial.println(F("Send RC5")); - Serial.flush(); - IrSender.sendRC5(sAddress & 0x1F, sCommand & 0x3F, sRepeats, true); // 5 address, 6 command bits - checkReceive(sAddress & 0x1F, sCommand & 0x3F); - delay(DELAY_AFTER_SEND); - - Serial.println(F("Send RC5X with 7.th MSB of command set")); - Serial.flush(); - IrSender.sendRC5(sAddress & 0x1F, (sCommand & 0x3F) + 0x40, sRepeats, true); // 5 address, 7 command bits - checkReceive(sAddress & 0x1F, (sCommand & 0x3F) + 0x40); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_RC6) - Serial.println(F("Send RC6")); - // RC6 check does not work stable without the flush - Serial.flush(); - IrSender.sendRC6(sAddress & 0xFF, sCommand, sRepeats, true); - checkReceive(sAddress & 0xFF, sCommand); - delay(DELAY_AFTER_SEND); -#endif - - /* - * Next example how to use the IrSender.write function - */ - IRData IRSendData; - // prepare data - IRSendData.address = sAddress; - IRSendData.command = sCommand; - IRSendData.flags = IRDATA_FLAGS_EMPTY; - -#if defined(DECODE_JVC) - IRSendData.protocol = JVC; // switch protocol - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - checkReceive(IRSendData.address & 0xFF, IRSendData.command); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_LG) || defined(DECODE_MAGIQUEST) - IRSendData.command = s16BitCommand; // LG support more than 8 bit command -#endif - -#if defined(DECODE_SAMSUNG) - IRSendData.protocol = SAMSUNG; - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - checkReceive(IRSendData.address, IRSendData.command); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_LG) - IRSendData.protocol = LG; - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - checkReceive(IRSendData.address & 0xFF, IRSendData.command); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_MAGIQUEST) - Serial.println(F("Send MagiQuest")); - Serial.flush(); - IrSender.sendMagiQuest(0x6BCD0000 | (uint32_t) sAddress, s16BitCommand); // we have 31 bit address - checkReceive(sAddress, s16BitCommand & 0x1FF); // we have 9 bit command - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_BEO) - Serial.println(F("Send Bang&Olufsen")); - Serial.flush(); - IrSender.sendBangOlufsen(sAddress & 0x0FF, sCommand, sRepeats); -# if defined(ENABLE_BEO_WITHOUT_FRAME_GAP) - delay((RECORD_GAP_MICROS / 1000) + 1); - IrReceiver.printIRResultRawFormatted(&Serial, true); - uint8_t tOriginalRawlen = IrReceiver.decodedIRData.rawDataPtr->rawlen; - IrReceiver.decodedIRData.rawDataPtr->rawlen = 6; - // decode first part of frame - IrReceiver.decode(); - IrReceiver.printIRResultShort(&Serial); - - // Remove trailing 6 entries for next decode - IrReceiver.decodedIRData.rawDataPtr->rawlen = tOriginalRawlen - 6; - for (uint_fast8_t i = 0; i < IrReceiver.decodedIRData.rawDataPtr->rawlen; ++i) { - IrReceiver.decodedIRData.rawDataPtr->rawbuf[i] = IrReceiver.decodedIRData.rawDataPtr->rawbuf[i + 6]; - } -# endif - checkReceive(sAddress & 0x0FF, sCommand); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_BOSEWAVE) - IRSendData.protocol = BOSEWAVE; - Serial.println(F("Send Bosewave with no address and 8 command bits")); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - checkReceive(0, IRSendData.command & 0xFF); - delay(DELAY_AFTER_SEND); -#endif - -#if defined(DECODE_FAST) - IRSendData.protocol = FAST; - Serial.print(F("Send ")); - Serial.println(getProtocolString(IRSendData.protocol)); - Serial.flush(); - IrSender.write(&IRSendData, sRepeats); - checkReceive(0, IRSendData.command & 0xFF); - delay(DELAY_AFTER_SEND); -#endif - - /* - * LEGO is skipped, since it is difficult to receive because of its short marks and spaces - */ -// Serial.println(F("Send Lego with 2 channel and with 4 command bits")); -// Serial.flush(); -// IrSender.sendLegoPowerFunctions(sAddress, sCommand, LEGO_MODE_COMBO, true); -// checkReceive(sAddress, sCommand); // never has success for Lego protocol :-( -// delay(DELAY_AFTER_SEND); - /* - * Force buffer overflow - */ - Serial.println(F("Force buffer overflow by sending 280 marks and spaces")); - for (unsigned int i = 0; i < 140; ++i) { - // 400 + 400 should be received as 8/8 and sometimes as 9/7 or 7/9 if compensation by MARK_EXCESS_MICROS is optimal. - // 210 + 540 = 750 should be received as 5/10 or 4/11 if compensation by MARK_EXCESS_MICROS is optimal. - IrSender.mark(210); // 8 pulses at 38 kHz - IrSender.space(540); // to fill up to 750 us - } - checkReceive(sAddress, sCommand); - delay(DELAY_AFTER_SEND); - - /* - * Increment values - * Also increment address just for demonstration, which normally makes no sense - */ - sAddress += 0x0101; - sCommand += 0x11; - s16BitCommand += 0x1111; - - delay(DELAY_AFTER_LOOP); // additional delay at the end of each loop -} - diff --git a/IRremote/examples/UnitTest/UnitTest.log b/IRremote/examples/UnitTest/UnitTest.log deleted file mode 100644 index da30c2188b6e06df82e3483a47cb2016a840c2b2..0000000000000000000000000000000000000000 --- a/IRremote/examples/UnitTest/UnitTest.log +++ /dev/null @@ -1,751 +0,0 @@ -START ../src/UnitTest.cpp from Feb 22 2023 -Using library version 4.1.0 -Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, Panasonic/Kaseikyo, Denon/Sharp, Sony, RC5, RC6, LG, JVC, Samsung, Bang & Olufsen, FAST, Bosewave , MagiQuest, Universal Pulse Distance Width, Hash at pin 2 -Send IR signals at pin 3 -If you connect debug pin 5 to ground, raw data is always printed -Send signal mark duration for 38kHz is 8 us, pulse narrowing correction is 3000 ns, total period is 26 us -16000 us is the (minimum) gap, after which the start of a new IR packet is assumed -20 us are subtracted from all marks and added to all spaces for decoding - -address=0xFFF1 command=0x76 - -Send NEC with 8 bit address -Protocol=NEC Address=0xF1 Command=0x76 Raw-Data=0x89760EF1 32 bits LSB first -Send with: IrSender.sendNEC(0xF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1044300 - +8950,-4400 - + 600,-1650 + 600,- 500 + 600,- 550 + 600,- 500 - + 600,-1650 + 600,-1600 + 600,-1650 + 600,-1650 - + 550,- 550 + 600,-1650 + 600,-1650 + 550,-1650 - + 600,- 550 + 550,- 550 + 600,- 550 + 550,- 600 - + 550,- 550 + 550,-1650 + 600,-1650 + 600,- 500 - + 600,-1650 + 600,-1650 + 600,-1650 + 600,- 500 - + 600,-1650 + 550,- 600 + 550,- 550 + 600,-1800 - + 450,- 500 + 600,- 550 + 550,- 550 + 600,-1650 - + 550 -Sum: 67650 - -Send NEC with 16 bit address -Protocol=NEC Address=0xFFF1 Command=0x76 Raw-Data=0x8976FFF1 32 bits LSB first -Send with: IrSender.sendNEC(0xFFF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1055100 - +8850,-4450 - + 600,-1650 + 600,- 500 + 600,- 550 + 600,- 500 - + 600,-1650 + 600,-1650 + 550,-1650 + 600,-1650 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,-1650 - + 550,-1650 + 600,-1650 + 550,-1700 + 550,-1650 - + 550,- 600 + 550,-1650 + 600,-1650 + 600,- 550 - + 550,-1650 + 600,-1650 + 600,-1650 + 600,- 500 - + 600,-1650 + 600,- 550 + 550,- 550 + 600,-1650 - + 600,- 500 + 550,- 600 + 600,- 500 + 600,-1650 - + 550 -Sum: 73150 - -Send NEC2 with 16 bit address -Protocol=NEC Address=0xFFF1 Command=0x76 Raw-Data=0x8976FFF1 32 bits LSB first -Send with: IrSender.sendNEC(0xFFF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1055500 - +8950,-4400 - + 650,-1600 + 600,- 500 + 650,- 500 + 600,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 600,-1600 - + 650,-1600 + 650,-1600 + 650,-1600 + 600,-1600 - + 650,-1600 + 650,-1600 + 650,-1600 + 650,-1600 - + 600,- 500 + 650,-1600 + 650,-1600 + 600,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 650,- 450 - + 650,-1600 + 650,- 500 + 600,- 500 + 600,-1650 - + 650,- 500 + 600,- 500 + 650,- 500 + 600,-1600 - + 650 -Sum: 73400 - -Send NEC Pronto data with 8 bit address 0x80 and command 0x45 and no repeats -Protocol=NEC Address=0x80 Command=0x45 Raw-Data=0xBA457F80 32 bits LSB first -Send with: IrSender.sendNEC(0x80, 0x45, <numberOfRepeats>); -rawData[68]: - -1064450 - +9050,-4450 - + 550,- 550 + 600,- 550 + 600,- 600 + 550,- 600 - + 600,- 550 + 600,- 550 + 600,- 550 + 600,-1600 - + 650,-1600 + 600,-1600 + 600,-1650 + 550,-1600 - + 600,-1600 + 600,-1600 + 600,-1600 + 650,- 500 - + 650,-1550 + 600,- 550 + 600,-1600 + 600,- 550 - + 600,- 550 + 600,- 550 + 600,-1600 + 600,- 550 - + 650,- 500 + 650,-1550 + 600,- 550 + 600,-1600 - + 600,-1600 + 600,-1650 + 600,- 550 + 600,-1650 - + 550 -Sum: 67800 - -Send NEC sendRaw data with 8 bit address=0xFB04 and command 0x08 and exact timing (16 bit array format) -Protocol=NEC Address=0x4 Command=0x8 Raw-Data=0xF708FB04 32 bits LSB first -Send with: IrSender.sendNEC(0x4, 0x8, <numberOfRepeats>); -rawData[68]: - -1061400 - +9000,-4400 - + 600,- 500 + 650,- 500 + 600,-1650 + 600,- 500 - + 650,- 500 + 600,- 550 + 600,- 500 + 600,- 550 - + 600,-1650 + 600,-1650 + 600,- 500 + 600,-1650 - + 600,-1650 + 600,-1650 + 600,-1650 + 600,-1650 - + 600,- 500 + 600,- 550 + 600,- 500 + 600,-1650 - + 600,- 500 + 600,- 550 + 600,- 500 + 600,- 550 - + 600,-1650 + 600,-1650 + 600,-1650 + 600,- 500 - + 600,-1650 + 600,-1650 + 600,-1650 + 550,-1650 - + 600 -Sum: 67900 - -Send ONKYO with 16 bit address 0x0102 and 16 bit command 0x0304 with NECRaw(0x03040102) -Protocol=Onkyo Address=0x102 Command=0x304 Raw-Data=0x3040102 32 bits LSB first -Send with: IrSender.sendOnkyo(0x102, 0x304, <numberOfRepeats>); -rawData[68]: - -1059700 - +8900,-4400 - + 600,- 550 + 600,-1600 + 600,- 550 + 600,- 500 - + 600,- 550 + 600,- 500 + 600,- 550 + 600,- 500 - + 600,-1650 + 600,- 500 + 600,- 550 + 600,- 500 - + 600,- 550 + 600,- 500 + 600,- 550 + 600,- 550 - + 550,- 550 + 600,- 500 + 600,-1650 + 600,- 500 - + 600,- 550 + 600,- 500 + 650,- 500 + 600,- 500 - + 600,-1650 + 600,-1600 + 600,- 550 + 600,- 500 - + 650,- 500 + 600,- 550 + 550,- 550 + 600,- 500 - + 650 -Sum: 55450 - -Send ONKYO with 16 bit address 0x0102 and command 0x34 with old 32 bit format MSB first (0x40802CD3) -Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendNEC(0x102, 0x34, <numberOfRepeats>); -rawData[68]: - -1061500 - +8950,-4400 - + 600,- 500 + 550,-1700 + 600,- 500 + 650,- 500 - + 600,- 500 + 650,- 500 + 550,- 550 + 650,- 500 - + 600,-1650 + 600,- 500 + 600,- 550 + 600,- 500 - + 600,- 550 + 600,- 500 + 600,- 550 + 600,- 500 - + 600,- 550 + 600,- 500 + 600,-1650 + 600,- 500 - + 600,-1650 + 600,-1650 + 600,- 500 + 600,- 550 - + 600,-1600 + 550,-1700 + 600,- 550 + 600,-1600 - + 600,- 550 + 600,- 500 + 650,-1600 + 600,-1650 - + 550 -Sum: 61000 - -Send Panasonic 0xB, 0x10 as 48 bit generic PulseDistance using ProtocolConstants -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); -rawData[100]: - -1059500 - +3450,-1700 - + 450,- 450 + 450,-1250 + 450,- 400 + 450,- 450 - + 450,- 400 + 450,- 400 + 450,- 450 + 400,- 450 - + 450,- 400 + 450,- 450 + 400,- 450 + 450,- 400 - + 450,- 450 + 400,-1300 + 450,- 400 + 450,- 450 - + 400,- 450 + 450,- 400 + 450,- 450 + 400,- 450 - + 450,-1300 + 400,-1300 + 450,- 400 + 450,-1300 - + 450,- 400 + 450,- 450 + 450,- 400 + 450,- 400 - + 450,- 450 + 400,- 450 + 450,- 400 + 450,- 450 - + 450,- 400 + 450,- 450 + 400,- 450 + 450,- 400 - + 450,-1300 + 400,- 450 + 450,- 450 + 400,- 450 - + 450,- 400 + 450,- 450 + 400,- 450 + 450,- 400 - + 450,- 450 + 400,-1300 + 450,- 400 + 450,-1300 - + 450 -Sum: 54100 - -Send Panasonic 0xB, 0x10 as generic 48 bit PulseDistance - LSB first -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); -rawData[100]: - -1076450 - +3450,-1700 - + 450,- 400 + 450,-1250 + 450,- 400 + 450,- 400 - + 450,- 400 + 400,- 450 + 400,- 450 + 450,- 400 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,-1250 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,-1250 + 450,-1250 + 450,- 400 + 450,-1250 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 350 - + 500,- 400 + 400,- 450 + 450,- 350 + 500,- 400 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,-1250 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,-1200 + 500,- 400 + 450,-1300 - + 400 -Sum: 53200 - - MSB first -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B0 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); -rawData[100]: - -1070700 - +3400,-1700 - + 450,- 400 + 450,-1250 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,-1250 + 450,- 400 + 450,- 400 - + 400,- 450 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,-1250 + 400,-1300 + 450,- 400 + 450,-1300 - + 400,- 400 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 400 - + 450,- 400 + 450,- 400 + 450,- 400 + 450,- 550 - + 250,-1300 + 450,- 450 + 400,- 400 + 450,- 400 - + 450,- 400 + 400,- 450 + 400,- 450 + 450,- 400 - + 450,- 400 + 450,-1250 + 450,- 400 + 450,-1250 - + 450 -Sum: 53150 - -Send generic 72 bit PulseDistance 0x5A AFEDCBA9 87654321 LSB first -Protocol=PulseDistance Raw-Data=0x5A 72 bits LSB first -Send with: - uint32_t tRawData[]={0x87654321, 0xAFEDCBA9, 0x5A}; - IrSender.sendPulseDistanceWidthFromArray(38, 8850, 4400, 550, 1650, 550, 600, &tRawData[0], 72, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); -rawData[148]: - -1076300 - +8850,-4400 - + 600,-1650 + 550,- 600 + 550,- 600 + 550,- 600 - + 550,- 600 + 550,-1650 + 550,- 650 + 550,- 600 - + 550,-1700 + 550,-1650 + 600,- 600 + 550,- 600 - + 550,- 600 + 500,- 650 + 550,-1650 + 600,- 600 - + 550,-1650 + 600,- 600 + 550,-1650 + 550,- 650 - + 550,- 600 + 550,-1650 + 550,-1700 + 550,- 600 - + 550,-1700 + 550,-1700 + 550,-1650 + 550,- 650 - + 550,- 600 + 550,- 600 + 550,- 600 + 550,-1700 - + 550,-1700 + 550,- 600 + 550,- 600 + 550,-1650 - + 500,- 700 + 550,-1650 + 600,- 600 + 550,-1650 - + 600,-1650 + 600,-1650 + 550,- 650 + 550,-1650 - + 550,- 600 + 550,- 600 + 550,-1700 + 550,-1700 - + 550,-1650 + 600,- 600 + 550,-1650 + 600,-1650 - + 600,- 600 + 550,-1650 + 550,-1700 + 550,-1700 - + 550,-1700 + 550,-1700 + 550,-1700 + 550,-1650 - + 550,- 650 + 550,-1650 + 550,- 650 + 550,-1700 - + 550,- 600 + 550,-1650 + 600,- 550 + 600,-1650 - + 550,-1700 + 550,- 600 + 550,-1700 + 550,- 600 - + 550 -Sum: 138200 - -Send generic 52 bit PulseDistanceWidth 0xDCBA9 87654321 LSB first -Protocol=PulseWidth Raw-Data=0xDCBA9 52 bits LSB first -Send with: - uint32_t tRawData[]={0x87654321, 0xDCBA9}; - IrSender.sendPulseDistanceWidthFromArray(38, 350, 600, 600, 300, 300, 600, &tRawData[0], 52, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); -rawData[106]: - -1115100 - + 350,- 600 - + 650,- 250 + 350,- 550 + 350,- 550 + 300,- 600 - + 350,- 550 + 600,- 300 + 350,- 550 + 350,- 550 - + 600,- 300 + 600,- 300 + 350,- 550 + 350,- 550 - + 350,- 600 + 300,- 600 + 600,- 300 + 300,- 600 - + 600,- 300 + 300,- 600 + 600,- 300 + 300,- 600 - + 300,- 600 + 600,- 300 + 600,- 300 + 350,- 550 - + 600,- 300 + 600,- 300 + 600,- 300 + 300,- 600 - + 350,- 550 + 350,- 550 + 350,- 550 + 600,- 350 - + 600,- 300 + 300,- 600 + 300,- 600 + 600,- 300 - + 300,- 600 + 600,- 300 + 300,- 600 + 600,- 300 - + 600,- 300 + 600,- 300 + 300,- 600 + 600,- 300 - + 300,- 600 + 350,- 550 + 600,- 300 + 600,- 300 - + 600,- 300 + 300,- 600 + 600,- 300 + 600 -Sum: 47550 - -Send generic 32 bit PulseWidth 0x87654321 LSB first -Protocol=PulseWidth Raw-Data=0x87654321 32 bits LSB first -Send with: IrSender.sendPulseDistanceWidth(38, 950, 550, 600, 300, 300, 300, 0x87654321, 32, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); -rawData[66]: - -1088600 - + 950,- 550 - + 600,- 300 + 300,- 300 + 350,- 250 + 350,- 250 - + 350,- 300 + 600,- 300 + 300,- 300 + 300,- 300 - + 650,- 250 + 650,- 250 + 300,- 300 + 350,- 250 - + 350,- 300 + 300,- 300 + 600,- 300 + 300,- 300 - + 600,- 300 + 350,- 250 + 600,- 300 + 350,- 250 - + 350,- 300 + 600,- 300 + 600,- 300 + 300,- 300 - + 600,- 300 + 600,- 300 + 600,- 300 + 300,- 300 - + 300,- 300 + 300,- 300 + 350,- 250 + 650 -Sum: 24500 - -Send MagiQuest 0x6BCDFF00, 0x176 as generic 55 bit PulseDistanceWidth MSB first -Protocol=MagiQuest Address=0xFF00 Command=0x176 Raw-Data=0x6BCDFF00 56 bits MSB first -Send with: IrSender.sendMagiQuest(0x6BCDFF00, 0x176, <numberOfRepeats>); -rawData[112]: - -1089000 - + 350,- 800 + 350,- 800 + 350,- 800 + 300,- 850 - + 300,- 850 + 300,- 850 + 300,- 850 + 350,- 800 - + 600,- 550 + 600,- 550 + 350,- 800 + 600,- 550 - + 300,- 850 + 600,- 550 + 600,- 550 + 600,- 550 - + 600,- 550 + 350,- 800 + 300,- 850 + 550,- 600 - + 600,- 550 + 300,- 850 + 600,- 550 + 600,- 550 - + 600,- 550 + 600,- 600 + 550,- 550 + 600,- 550 - + 600,- 550 + 600,- 550 + 600,- 550 + 300,- 850 - + 300,- 850 + 350,- 800 + 300,- 850 + 300,- 850 - + 300,- 850 + 300,- 850 + 300,- 850 + 600,- 550 - + 300,- 850 + 600,- 550 + 600,- 550 + 600,- 550 - + 350,- 800 + 600,- 550 + 600,- 550 + 350,- 800 - + 300,- 850 + 300,- 850 + 300,- 850 + 600,- 600 - + 550,- 600 + 250,- 900 + 250,- 850 + 600 -Sum: 63850 - -Send Onkyo (NEC with 16 bit command) -Protocol=Onkyo Address=0xFFF1 Command=0x7776 Raw-Data=0x7776FFF1 32 bits LSB first -Send with: IrSender.sendOnkyo(0xFFF1, 0x7776, <numberOfRepeats>); -rawData[68]: - -1070700 - +8900,-4550 - + 500,-1600 + 650,- 500 + 600,- 500 + 600,- 550 - + 600,-1600 + 600,-1650 + 600,-1650 + 550,-1650 - + 600,-1650 + 600,-1650 + 550,-1650 + 600,-1650 - + 600,-1650 + 550,-1650 + 600,-1650 + 550,-1700 - + 550,- 550 + 600,-1650 + 550,-1650 + 600,- 550 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,- 500 - + 600,-1650 + 600,-1650 + 600,-1600 + 600,- 550 - + 600,-1650 + 550,-1650 + 600,-1650 + 550,- 550 - + 600 -Sum: 76500 - -Send Apple -Protocol=Apple Address=0xF1 Command=0x76 Raw-Data=0xF17687EE 32 bits LSB first -Send with: IrSender.sendApple(0xF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1054650 - +8950,-4400 - + 600,- 550 + 550,-1650 + 650,-1600 + 600,-1600 - + 600,- 550 + 600,-1650 + 550,-1650 + 600,-1650 - + 600,-1650 + 600,-1650 + 550,-1650 + 600,- 550 - + 550,- 550 + 600,- 550 + 600,- 500 + 600,-1650 - + 600,- 550 + 550,-1650 + 600,-1650 + 600,- 500 - + 550,-1700 + 600,-1650 + 550,-1650 + 600,- 550 - + 550,-1650 + 600,- 550 + 600,- 550 + 550,- 550 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,-1650 - + 550 -Sum: 72100 - -Send Panasonic -Protocol=Panasonic Address=0xFF1 Command=0x76 Raw-Data=0x9976FF10 48 bits LSB first -Send with: IrSender.sendPanasonic(0xFF1, 0x76, <numberOfRepeats>); -rawData[100]: - -1054300 - +3450,-1700 - + 450,- 450 + 400,-1300 + 450,- 400 + 450,- 450 - + 450,- 400 + 450,- 450 + 400,- 450 + 450,- 400 - + 450,- 450 + 450,- 400 + 450,- 400 + 450,- 450 - + 450,- 400 + 450,-1300 + 400,- 450 + 450,- 400 - + 450,- 450 + 400,- 450 + 450,- 400 + 450,- 450 - + 450,-1250 + 450,- 400 + 450,- 450 + 450,- 400 - + 450,-1300 + 400,-1300 + 450,-1300 + 400,-1300 - + 450,-1300 + 400,-1300 + 450,-1300 + 400,-1300 - + 450,- 450 + 450,-1250 + 500,-1250 + 450,- 400 - + 450,-1300 + 400,-1300 + 450,-1300 + 400,- 450 - + 450,-1250 + 450,- 450 + 450,- 400 + 450,-1300 - + 400,-1300 + 450,- 400 + 450,- 450 + 450,-1250 - + 450 -Sum: 64400 - -Send Kaseikyo with 0x4711 as Vendor ID -Protocol=Kaseikyo Address=0xFF1 Command=0x76 Extra=0x4711 Raw-Data=0x9A76FF13 48 bits LSB first -Send with: IrSender.sendKaseikyo(0xFF1, 0x76, <numberOfRepeats>, 0x4711); -rawData[100]: - -1074550 - +3400,-1750 - + 450,-1250 + 450,- 450 + 450,- 400 + 450,- 450 - + 400,-1300 + 450,- 400 + 450,- 450 + 450,- 400 - + 450,-1300 + 400,-1300 + 450,-1300 + 400,- 450 - + 450,- 400 + 450,- 450 + 450,-1250 + 450,- 450 - + 400,-1300 + 450,-1300 + 400,- 450 + 450,- 400 - + 450,-1300 + 450,- 400 + 450,- 450 + 400,- 450 - + 450,-1250 + 400,-1350 + 450,-1300 + 400,-1350 - + 400,-1300 + 400,-1300 + 450,-1300 + 450,-1250 - + 450,- 450 + 400,-1300 + 450,-1300 + 400,- 450 - + 450,-1250 + 450,-1300 + 400,-1300 + 450,- 400 - + 450,- 450 + 450,-1250 + 450,- 400 + 450,-1300 - + 450,-1250 + 450,- 400 + 450,- 450 + 450,-1250 - + 450 -Sum: 69500 - -Send Kaseikyo_Denon variant -Protocol=Kaseikyo_Denon Address=0xFF1 Command=0x76 Raw-Data=0x9976FF10 48 bits LSB first -Send with: IrSender.sendKaseikyo_Denon(0xFF1, 0x76, <numberOfRepeats>); -rawData[100]: - -1067700 - +3400,-1750 - + 450,- 400 + 450,- 450 + 450,-1250 + 450,- 400 - + 450,-1300 + 450,- 400 + 450,-1300 + 400,- 450 - + 450,- 400 + 450,-1300 + 450,- 400 + 450,- 400 - + 450,-1300 + 450,-1250 + 450,- 400 + 450,- 450 - + 400,- 450 + 450,- 400 + 450,- 450 + 400,- 450 - + 450,-1250 + 450,- 450 + 450,- 400 + 450,- 400 - + 450,-1300 + 450,-1250 + 450,-1300 + 400,-1300 - + 450,-1300 + 400,-1300 + 450,-1250 + 450,-1300 - + 450,- 400 + 450,-1300 + 400,-1300 + 450,- 400 - + 450,-1300 + 400,-1300 + 450,-1300 + 400,- 450 - + 450,-1250 + 450,- 450 + 400,- 450 + 450,-1300 - + 400,-1300 + 450,- 400 + 450,- 450 + 450,-1250 - + 450 -Sum: 67700 - -Send Denon -Protocol=Denon Address=0x11 Command=0x76 Raw-Data=0xED1 15 bits LSB first -Send with: IrSender.sendDenon(0x11, 0x76, <numberOfRepeats>); -rawData[32]: - -1073050 - + 250,-1850 + 250,- 750 + 250,- 800 + 250,- 800 - + 250,-1800 + 250,- 800 + 250,-1800 + 250,-1850 - + 250,- 750 + 300,-1800 + 250,-1800 + 300,-1800 - + 250,- 750 + 300,- 750 + 300,- 750 + 250 -Sum: 23050 - -Send Denon/Sharp variant -Protocol=Sharp Address=0x11 Command=0x76 Raw-Data=0x4ED1 15 bits LSB first -Send with: IrSender.sendSharp(0x11, 0x76, <numberOfRepeats>); -rawData[32]: - -1018750 - + 300,-1750 + 300,- 750 + 250,- 800 + 250,- 800 - + 250,-1800 + 250,- 800 + 250,-1800 + 300,-1800 - + 250,- 800 + 250,-1800 + 300,-1750 + 300,-1800 - + 250,- 800 + 250,- 750 + 300,-1800 + 250 -Sum: 24100 - -Send Sony/SIRCS with 7 command and 5 address bits -Protocol=Sony Address=0x11 Command=0x76 Raw-Data=0x8F6 12 bits LSB first -Send with: IrSender.sendSony(0x11, 0x76, 2, 12); -rawData[26]: - -1020950 - +2400,- 650 - + 550,- 600 +1200,- 550 +1250,- 550 + 650,- 550 - +1250,- 550 +1250,- 600 +1200,- 550 +1200,- 600 - + 650,- 550 + 650,- 550 + 650,- 550 +1200 -Sum: 20950 - -Send Sony/SIRCS with 7 command and 8 address bits -Protocol=Sony Address=0xF1 Command=0x76 Raw-Data=0x78F6 15 bits LSB first -Send with: IrSender.sendSony(0xF1, 0x76, 2, 15); -rawData[32]: - -1032550 - +2400,- 600 - + 600,- 600 +1200,- 600 +1200,- 550 + 650,- 550 - +1200,- 600 +1200,- 650 +1200,- 550 +1200,- 600 - + 650,- 550 + 650,- 550 + 650,- 550 +1200,- 600 - +1200,- 600 +1250,- 600 +1200 -Sum: 26400 - -Send Sony/SIRCS with 7 command and 13 address bits -Protocol=Sony Address=0x1FF1 Command=0x76 Raw-Data=0xFF8F6 20 bits LSB first -Send with: IrSender.sendSony(0x1FF1, 0x76, 2, 20); -rawData[42]: - -1036350 - +2300,- 650 - + 600,- 600 +1200,- 550 +1250,- 550 + 650,- 600 - +1200,- 550 +1250,- 550 +1200,- 600 +1250,- 600 - + 600,- 600 + 600,- 600 + 600,- 550 +1200,- 600 - +1250,- 550 +1250,- 550 +1250,- 550 +1250,- 600 - +1200,- 550 +1200,- 600 +1250,- 600 +1200 -Sum: 35350 - -Send Samsung 8 bit command -Protocol=Samsung Address=0xFFF1 Command=0x76 Raw-Data=0x8976FFF1 32 bits LSB first -Send with: IrSender.sendSamsung(0xFFF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1039650 - +4400,-4450 - + 550,-1700 + 550,- 550 + 600,- 550 + 550,- 550 - + 600,-1650 + 550,-1650 + 600,-1650 + 550,-1650 - + 600,-1650 + 600,-1650 + 600,-1650 + 550,-1650 - + 600,-1650 + 600,-1650 + 550,-1650 + 600,-1650 - + 600,- 550 + 550,-1650 + 600,-1650 + 600,- 550 - + 550,-1650 + 600,-1650 + 550,-1700 + 550,- 550 - + 600,-1650 + 550,- 550 + 600,- 550 + 600,-1600 - + 600,- 550 + 600,- 550 + 550,- 550 + 600,-1650 - + 600 -Sum: 68750 - -Send Samsung 16 bit command -Protocol=Samsung Address=0xFFF1 Command=0x9876 Raw-Data=0x9876FFF1 32 bits LSB first -Send with: IrSender.sendSamsung(0xFFF1, 0x9876, <numberOfRepeats>); -rawData[68]: - -1056350 - +4400,-4400 - + 600,-1650 + 550,- 550 + 600,- 550 + 550,- 550 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,-1600 - + 600,-1650 + 600,-1650 + 600,-1650 + 550,-1650 - + 600,-1650 + 600,-1650 + 550,-1650 + 600,-1650 - + 600,- 500 + 550,-1700 + 600,-1650 + 550,- 550 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,- 550 - + 550,- 550 + 600,- 550 + 550,- 550 + 600,-1650 - + 550,-1650 + 600,- 550 + 600,- 550 + 550,-1650 - + 600 -Sum: 68650 - -Send Samsung48 16 bit command -Protocol=Samsung48 Address=0xFFF1 Command=0x9876 Raw-Data=0x6798 48 bits LSB first -Send with: IrSender.sendSamsung48(0xFFF1, 0x9876, <numberOfRepeats>); -rawData[100]: - -1056750 - +4450,-4450 - + 600,-1650 + 600,- 500 + 600,- 550 + 550,- 550 - + 600,-1650 + 600,-1650 + 550,-1650 + 600,-1650 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,-1650 - + 550,-1650 + 550,-1700 + 550,-1700 + 550,-1650 - + 600,- 550 + 550,-1700 + 550,-1650 + 600,- 550 - + 550,-1650 + 600,-1650 + 600,-1650 + 600,- 500 - + 600,-1650 + 600,- 500 + 600,- 550 + 600,-1650 - + 550,- 550 + 600,- 550 + 550,- 550 + 550,-1700 - + 600,- 550 + 600,- 500 + 600,- 550 + 600,-1650 - + 550,-1650 + 600,- 550 + 550,- 550 + 600,-1650 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,- 550 - + 550,- 550 + 600,-1650 + 550,-1650 + 600,- 550 - + 550 -Sum: 95650 - -Send RC5 -Protocol=RC5 Address=0x11 Command=0x36 Raw-Data=0x1476 13 bits MSB first -Send with: IrSender.sendRC5(0x11, 0x36, <numberOfRepeats>); -rawData[20]: - -1073300 - + 900,- 900 - +1750,-1800 +1750,- 900 + 900,- 850 + 900,-1750 - + 900,- 900 + 900,- 850 +1800,-1800 + 900,- 850 - +1800 -Sum: 23100 - -Send RC5X with 7.th MSB of command set -Protocol=RC5 Address=0x11 Command=0x76 Toggle=1 Raw-Data=0xC76 13 bits MSB first -Send with: IrSender.sendRC5(0x11, 0x76, <numberOfRepeats>); -rawData[20]: - -1031250 - +1800,-1750 - + 850,- 900 +1800,- 850 + 900,- 900 + 900,-1750 - + 900,- 900 + 850,- 900 +1750,-1800 + 900,- 850 - +1800 -Sum: 23050 - -Send RC6 -Protocol=RC6 Address=0xF1 Command=0x76 Raw-Data=0xF176 20 bits MSB first -Send with: IrSender.sendRC6(0xF1, 0x76, <numberOfRepeats>); -rawData[36]: - -1028550 - +2650,- 900 - + 450,- 900 + 450,- 450 + 450,- 450 + 450,- 850 - +1350,- 450 + 450,- 450 + 450,- 450 + 450,- 900 - + 450,- 450 + 450,- 450 + 900,- 900 + 900,- 450 - + 450,- 450 + 450,- 900 + 850,- 450 + 450,- 900 - + 450 -Sum: 23250 - -Send JVC -Protocol=JVC Address=0xF1 Command=0x76 Raw-Data=0x76F1 16 bits LSB first -Send with: IrSender.sendJVC(0xF1, 0x76, <numberOfRepeats>); -rawData[36]: - -1037050 - +8400,-4150 - + 500,-1600 + 550,- 500 + 500,- 550 + 550,- 500 - + 550,-1550 + 550,-1550 + 500,-1600 + 550,-1550 - + 550,- 500 + 550,-1550 + 550,-1550 + 500,- 550 - + 550,-1550 + 550,-1550 + 550,-1550 + 550,- 500 - + 550 -Sum: 40400 - -Send Samsung -Protocol=Samsung Address=0xFFF1 Command=0x9876 Raw-Data=0x9876FFF1 32 bits LSB first -Send with: IrSender.sendSamsung(0xFFF1, 0x9876, <numberOfRepeats>); -rawData[68]: - -1036350 - +4450,-4400 - + 550,-1700 + 600,- 550 + 550,- 550 + 600,- 550 - + 550,-1650 + 600,-1650 + 600,-1650 + 550,-1650 - + 550,-1700 + 600,-1650 + 550,-1650 + 600,-1650 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,-1650 - + 550,- 550 + 600,-1650 + 550,-1700 + 550,- 550 - + 600,-1650 + 600,-1650 + 550,-1650 + 600,- 550 - + 550,- 550 + 600,- 550 + 550,- 550 + 600,-1650 - + 550,-1650 + 600,- 550 + 600,- 500 + 600,-1700 - + 550 -Sum: 68750 - -Send LG -Protocol=LG Address=0xF1 Command=0x9876 Raw-Data=0xF19876E 28 bits MSB first -Send with: IrSender.sendLG(0xF1, 0x9876, <numberOfRepeats>); -rawData[60]: - -1054900 - +9000,-4150 - + 450,-1600 + 500,-1550 + 500,-1550 + 500,-1600 - + 500,- 550 + 500,- 550 + 500,- 550 + 500,-1550 - + 500,-1600 + 500,- 550 + 500,- 550 + 450,-1600 - + 500,-1600 + 500,- 550 + 500,- 550 + 500,- 550 - + 500,- 550 + 500,-1550 + 500,-1550 + 550,-1550 - + 500,- 550 + 500,-1550 + 500,-1600 + 500,- 550 - + 500,-1550 + 500,-1550 + 500,-1600 + 500,- 550 - + 500 -Sum: 59350 - -Send MagiQuest -Protocol=MagiQuest Address=0xFFF1 Command=0x76 Raw-Data=0x6BCDFFF1 56 bits MSB first -Send with: IrSender.sendMagiQuest(0x6BCDFFF1, 0x76, <numberOfRepeats>); -rawData[112]: - -1049950 - + 250,- 850 + 250,- 900 + 250,- 900 + 250,- 900 - + 250,- 900 + 300,- 850 + 250,- 900 + 250,- 900 - + 600,- 550 + 600,- 550 + 300,- 850 + 550,- 600 - + 250,- 900 + 550,- 600 + 550,- 600 + 550,- 600 - + 550,- 600 + 300,- 850 + 250,- 900 + 550,- 600 - + 550,- 600 + 300,- 850 + 550,- 600 + 550,- 600 - + 550,- 600 + 550,- 600 + 550,- 600 + 550,- 600 - + 550,- 600 + 550,- 600 + 550,- 600 + 550,- 600 - + 550,- 600 + 550,- 600 + 600,- 550 + 300,- 900 - + 250,- 900 + 250,- 900 + 550,- 550 + 300,- 850 - + 250,- 900 + 550,- 600 + 550,- 600 + 550,- 600 - + 300,- 850 + 550,- 600 + 550,- 600 + 250,- 900 - + 300,- 850 + 300,- 850 + 600,- 550 + 550,- 600 - + 300,- 850 + 550,- 600 + 550,- 600 + 550 -Sum: 63750 - -Send Bang&Olufsen -Protocol=Bang&Olufsen Address=0xF1 Command=0x76 Raw-Data=0xF176 16 bits MSB first -Send with: IrSender.sendBang&Olufsen(0xF1, 0x76, <numberOfRepeats>); -rawData[44]: - -1078450 - + 150,-2850 - + 200,-2900 + 200,-15300 + 200,-2900 + 200,-9100 - + 250,-5950 + 250,-5950 + 250,-5950 + 200,-2900 - + 200,-6000 + 200,-6000 + 200,-9100 + 200,-2900 - + 200,-9100 + 250,-5950 + 250,-5950 + 250,-2850 - + 200,-9100 + 250,-5950 + 250,-2850 + 200,-12200 - + 200 -Sum: 136500 - -Send Bosewave with no address and 8 command bits -Protocol=BoseWave Address=0x0 Command=0x76 Raw-Data=0x8976 16 bits LSB first -Send with: IrSender.sendBoseWave(0x0, 0x76, <numberOfRepeats>); -rawData[36]: - -1044750 - +1050,-1450 - + 550,- 450 + 550,-1400 + 550,-1450 + 550,- 450 - + 500,-1450 + 550,-1450 + 500,-1450 + 550,- 450 - + 550,-1400 + 550,- 450 + 550,- 450 + 550,-1450 - + 500,- 500 + 500,- 450 + 550,- 450 + 550,-1450 - + 500 -Sum: 26750 - -Send FAST -Protocol=FAST Address=0x0 Command=0x76 Raw-Data=0x8976 16 bits LSB first -Send with: IrSender.sendFAST(0x0, 0x76, <numberOfRepeats>); -rawData[36]: - -1036750 - +2100,-1050 - + 550,- 500 + 550,-1550 + 550,-1550 + 550,- 500 - + 550,-1550 + 550,-1550 + 550,-1550 + 550,- 500 - + 550,-1550 + 550,- 500 + 550,- 500 + 550,-1550 - + 550,- 500 + 550,- 500 + 550,- 500 + 550,-1550 - + 550 -Sum: 28900 - -Force buffer overflow by sending 280 marks and spaces -Overflow -Try to increase the "RAW_BUFFER_LENGTH" value of 150 in ../src/UnitTest.cpp -rawData[150]: - -1040000 - + 250,- 500 - + 200,- 600 + 200,- 550 + 200,- 500 + 200,- 550 - + 200,- 550 + 250,- 500 + 250,- 550 + 200,- 550 - + 250,- 500 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,-1300 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 550 + 250,- 500 + 200,- 550 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 550 + 200,- 500 + 250,- 550 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 500 + 250,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 550 + 200,- 550 + 200,- 550 - + 200,- 550 + 250,- 500 + 200,- 550 + 200,- 550 - + 200,- 550 + 200,- 500 + 250,- 550 + 200,- 500 - + 250,- 550 + 200,- 550 + 250,- 500 + 200,- 550 - + 200,- 550 + 200 -Sum: 56500 -ERROR: Unknown protocol - - -address=0xF2 command=0x87 - -Send NEC with 8 bit address -Protocol=NEC Address=0xF2 Command=0x87 Raw-Data=0x78870DF2 32 bits LSB first -Send with: IrSender.sendNEC(0xF2, 0x87, <numberOfRepeats>); -rawData[68]: - -3276750 - +8850,-4500 - + 550,- 500 + 600,-1650 + 600,- 500 + 600,- 550 - + 600,-1600 + 600,-1650 + 600,-1650 + 600,-1650 - + 600,-1600 + 600,- 550 + 600,-1650 + 550,-1650 - + 600,- 550 + 550,- 550 + 600,- 550 + 550,- 550 - + 600,-1650 + 600,-1600 + 600,-1650 + 600,- 550 - + 550,- 550 + 600,- 550 + 550,- 550 + 600,-1650 - + 600,- 500 + 550,- 600 + 550,- 550 + 600,-1650 - + 550,-1700 + 550,-1650 + 600,-1650 + 600,- 500 - + 600 -Sum: 67600 - -Send NEC with 16 bit address -Protocol=NEC Address=0xF2 Command=0x87 Raw-Data=0x78870DF2 32 bits LSB first -Send with: IrSender.sendNEC(0xF2, 0x87, <numberOfRepeats>); -rawData[68]: - -998700 - +8900,-4400 - + 600,- 500 + 600,-1650 + 600,- 550 + 600,- 500 - + 600,-1650 + 600,-1600 + 600,-1650 + 600,-1650 - + 600,-1600 + 650,- 500 + 600,-1650 + 600,-1600 - + 600,- 550 + 600,- 500 + 600,- 550 + 600,- 500 - + 600,-1650 + 600,-1650 + 600,-1600 + 650,- 500 - + 600,- 500 + 600,- 550 + 600,- 500 + 600,-1650 - + 600,- 500 + 650,- 500 + 600,- 500 + 650,-1600 - + 600,-1650 + 600,-1650 + 600,-1600 + 650,- 500 - + 600 -Sum: 67650 - -Send NEC2 with 16 bit address -Protocol=NEC Address=0xF2 Command=0x87 Raw-Data=0x78870DF2 32 bits LSB first -Send with: IrSender.sendNEC(0xF2, 0x87, <numberOfRepeats>); -rawData[68]: - -1055100 - +8950,-4400 - + 600,- 500 + 650,-1600 + 650,- 500 + 600,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 600,-1600 - + 650,-1600 + 650,- 500 + 650,-1600 + 600,-1600 - + 650,- 500 + 600,- 500 + 650,- 500 + 600,- 500 - + 650,-1600 + 600,-1650 + 600,-1650 + 600,- 500 - + 650,- 500 + 600,- 500 + 650,- 500 + 600,-1650 - + 600,- 500 + 600,- 550 + 600,- 500 + 600,-1650 - + 600,-1650 + 600,-1650 + 600,-1650 + 600,- 500 - + 600 -Sum: 67800 - -Send Onkyo (NEC with 16 bit command) -Protocol=Onkyo Address=0xF2 Command=0x8887 Raw-Data=0x888700F2 32 bits LSB first -Send with: IrSender.sendOnkyo(0xF2, 0x8887, <numberOfRepeats>); -rawData[68]: - -1053400 - +8850,-4400 - + 600,- 550 + 600,-1650 + 600,- 500 + 600,- 550 - + 600,-1600 + 600,-1650 + 600,-1650 + 550,-1650 - + 600,- 550 + 550,- 550 + 650,- 500 + 550,- 550 - + 600,- 550 + 600,- 500 + 600,- 550 + 550,- 550 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,- 550 - + 550,- 550 + 600,- 550 + 550,- 550 + 600,-1650 - + 600,- 500 + 600,- 550 + 550,- 550 + 600,-1650 - + 600,- 500 + 600,- 550 + 600,- 500 + 600,-1650 - + 600 -Sum: 62050 - -Send Apple -Protocol=Apple Address=0xF2 Command=0x87 Raw-Data=0xF28787EE 32 bits LSB first -Send with: IrSender.sendApple(0xF2, 0x87, <numberOfRepeats>); -rawData[68]: - -1054100 - +8900,-4450 - + 550,- 550 + 600,-1650 + 600,-1650 + 600,-1650 - + 550,- 550 + 600,-1650 + 550,-1650 + 600,-1650 - + 600,-1650 + 600,-1650 + 550,-1650 + 600,- 550 - + 600,- 500 + 600,- 600 + 550,- 500 + 600,-1650 - + 600,-1650 + 550,-1650 + 600,-1650 + 600,- 500 - + 600,- 550 + 600,- 500 + 600,- 550 + 600,-1650 - + 550,- 550 + 600,-1650 + 550,- 550 + 600,- 550 - + 550,-1650 + 600,-1650 + 600,-1650 + 550,-1650 - + 600 -Sum: 71000 - diff --git a/IRremote/examples/UnitTest/UnitTest_64bit.log b/IRremote/examples/UnitTest/UnitTest_64bit.log deleted file mode 100644 index e69f1c73b9407325057954e62602fa5d8fe4a474..0000000000000000000000000000000000000000 --- a/IRremote/examples/UnitTest/UnitTest_64bit.log +++ /dev/null @@ -1,796 +0,0 @@ -START UnitTest.cpp from Feb 24 2023 -Using library version 4.1.0 -Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, Panasonic/Kaseikyo, Denon/Sharp, Sony, RC5, RC6, LG, JVC, Samsung, Bang & Olufsen, FAST, Bosewave , MagiQuest, Universal Pulse Distance Width, Hash at pin 14 -Send IR signals at pin 12 -If you connect debug pin 13 to ground, raw data is always printed -Send signal mark duration for 38kHz is 8 us, pulse narrowing correction is 600 ns, total period is 26 us -16000 us is the (minimum) gap, after which the start of a new IR packet is assumed -100 us are subtracted from all marks and added to all spaces for decoding - -address=0xFFF1 command=0x76 - -Send NEC with 8 bit address -Protocol=NEC Address=0xF1 Command=0x76 Raw-Data=0x89760EF1 32 bits LSB first -Send with: IrSender.sendNEC(0xF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1050650 - +9050,-4450 - + 650,-1600 + 700,- 450 + 650,- 500 + 650,- 450 - + 700,-1600 + 650,-1600 + 650,-1600 + 650,-1600 - + 700,- 450 + 650,-1600 + 650,-1650 + 650,-1600 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,- 450 - + 700,- 450 + 650,-1600 + 650,-1600 + 700,- 450 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 450 - + 700,-1600 + 650,- 450 + 700,- 450 + 650,-1600 - + 650,- 500 + 650,- 450 + 700,- 450 + 650,-1600 - + 700 -Sum: 68500 - -Send NEC with 16 bit address -Protocol=NEC Address=0xFFF1 Command=0x76 Raw-Data=0x8976FFF1 32 bits LSB first -Send with: IrSender.sendNEC(0xFFF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1060200 - +9050,-4400 - + 650,-1600 + 650,- 500 + 650,- 450 + 700,- 450 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,- 500 + 650,-1600 + 650,-1600 + 650,- 500 - + 650,-1600 + 650,-1600 + 650,-1650 + 650,- 450 - + 650,-1600 + 700,- 450 + 650,- 500 + 650,-1600 - + 650,- 500 + 650,- 450 + 650,- 500 + 650,-1600 - + 650 -Sum: 74050 - -Send NEC2 with 16 bit address -Protocol=NEC Address=0xFFF1 Command=0x76 Raw-Data=0x8976FFF1 32 bits LSB first -Send with: IrSender.sendNEC(0xFFF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1060450 - +9050,-4450 - + 650,-1600 + 650,- 500 + 650,- 450 + 650,- 500 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,- 500 + 650,-1600 + 650,-1600 + 650,- 500 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 500 - + 650,-1600 + 650,- 500 + 650,- 500 + 650,-1600 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,-1600 - + 650 -Sum: 74150 - -Send NEC Pronto data with 8 bit address 0x80 and command 0x45 and no repeats -Protocol=NEC Address=0x80 Command=0x45 Raw-Data=0xBA457F80 32 bits LSB first -Send with: IrSender.sendNEC(0x80, 0x45, <numberOfRepeats>); -rawData[68]: - -1065600 - +9200,-4400 - + 700,- 450 + 700,- 450 + 700,- 500 + 650,- 500 - + 700,- 500 + 650,- 500 + 650,- 550 + 700,-1550 - + 700,-1550 + 700,-1550 + 700,-1550 + 650,-1550 - + 700,-1550 + 700,-1550 + 700,-1550 + 700,- 450 - + 700,-1550 + 650,- 500 + 650,-1600 + 700,- 450 - + 700,- 450 + 700,- 450 + 700,-1550 + 700,- 450 - + 750,- 450 + 700,-1500 + 700,- 450 + 700,-1550 - + 700,-1550 + 700,-1550 + 700,- 450 + 700,-1550 - + 700 -Sum: 68800 - -Send NEC sendRaw data with 8 bit address=0xFB04 and command 0x08 and exact timing (16 bit array format) -Protocol=NEC Address=0x4 Command=0x8 Raw-Data=0xF708FB04 32 bits LSB first -Send with: IrSender.sendNEC(0x4, 0x8, <numberOfRepeats>); -rawData[68]: - -1066550 - +9150,-4400 - + 650,- 500 + 650,- 450 + 700,-1600 + 650,- 450 - + 700,- 450 + 650,- 500 + 650,- 450 + 650,- 500 - + 650,-1600 + 700,-1600 + 650,- 450 + 700,-1600 - + 650,-1600 + 700,-1600 + 650,-1600 + 650,-1650 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,-1600 - + 650,- 500 + 650,- 450 + 700,- 450 + 650,- 500 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 500 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 700 -Sum: 68700 - -Send ONKYO with 16 bit address 0x0102 and 16 bit command 0x0304 with NECRaw(0x03040102) -Protocol=Onkyo Address=0x102 Command=0x304 Raw-Data=0x3040102 32 bits LSB first -Send with: IrSender.sendOnkyo(0x102, 0x304, <numberOfRepeats>); -rawData[68]: - -1064800 - +9050,-4450 - + 650,- 450 + 650,-1600 + 700,- 450 + 650,- 500 - + 650,- 450 + 650,- 500 + 650,- 500 + 650,- 450 - + 650,-1600 + 700,- 450 + 700,- 450 + 650,- 500 - + 650,- 450 + 650,- 500 + 650,- 450 + 700,- 450 - + 650,- 500 + 650,- 450 + 700,-1600 + 650,- 450 - + 650,- 500 + 650,- 450 + 650,- 500 + 650,- 500 - + 650,-1600 + 650,-1600 + 650,- 500 + 650,- 450 - + 650,- 550 + 650,- 500 + 600,- 500 + 650,- 500 - + 650 -Sum: 56050 - -Send ONKYO with 16 bit address 0x0102 and command 0x34 with old 32 bit format MSB first (0x40802CD3) -Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 32 bits LSB first -Send with: IrSender.sendNEC(0x102, 0x34, <numberOfRepeats>); -rawData[68]: - -1066900 - +9050,-4400 - + 650,- 500 + 650,-1600 + 650,- 500 + 650,- 450 - + 650,- 500 + 650,- 450 + 700,- 450 + 650,- 500 - + 650,-1600 + 650,- 500 + 650,- 450 + 650,- 550 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,- 450 - + 650,- 500 + 650,- 450 + 700,-1600 + 650,- 450 - + 700,-1600 + 650,-1600 + 650,- 500 + 650,- 450 - + 650,-1600 + 700,-1600 + 600,- 500 + 650,-1650 - + 650,- 450 + 700,- 450 + 650,-1600 + 650,-1600 - + 700 -Sum: 61700 - -Send Panasonic 0xB, 0x10 as 48 bit generic PulseDistance using ProtocolConstants -Protocol=Panasonic Address=0x10B Command=0xA0 Raw-Data=0xA010B02002 48 bits LSB first -Send with: IrSender.sendPanasonic(0x10B, 0xA0, <numberOfRepeats>); -rawData[100]: - -1064700 - +3550,-1650 - + 550,- 350 + 500,-1250 + 500,- 400 + 500,- 350 - + 500,- 400 + 500,- 350 + 500,- 400 + 500,- 350 - + 500,- 400 + 500,- 350 + 500,- 400 + 500,- 350 - + 500,- 400 + 450,-1300 + 500,- 350 + 500,- 400 - + 500,- 350 + 500,- 400 + 500,- 350 + 500,- 400 - + 500,-1250 + 500,-1250 + 500,- 350 + 500,-1250 - + 500,- 400 + 500,- 350 + 500,- 400 + 500,- 350 - + 500,-1250 + 500,- 400 + 500,- 350 + 500,- 400 - + 500,- 350 + 550,- 350 + 500,- 350 + 550,- 350 - + 500,- 350 + 500,-1250 + 500,- 400 + 500,-1250 - + 500,- 350 + 550,- 350 + 500,- 350 + 550,- 350 - + 500,- 350 + 550,- 350 + 500,- 400 + 500,- 350 - + 500 -Sum: 54750 - -Send Panasonic 0xB, 0x10 as generic 48 bit PulseDistance - LSB first -Protocol=Panasonic Address=0x10B Command=0xA0 Raw-Data=0xA010B02002 48 bits LSB first -Send with: IrSender.sendPanasonic(0x10B, 0xA0, <numberOfRepeats>); -rawData[100]: - -1082450 - +3550,-1600 - + 550,- 350 + 550,-1150 + 550,- 300 + 600,- 300 - + 550,- 300 + 550,- 300 + 600,- 300 + 550,- 300 - + 550,- 300 + 550,- 350 + 550,- 300 + 550,- 350 - + 550,- 300 + 550,-1200 + 550,- 300 + 550,- 300 - + 550,- 350 + 550,- 300 + 550,- 300 + 550,- 350 - + 550,-1150 + 550,-1200 + 550,- 300 + 550,-1200 - + 550,- 300 + 550,- 300 + 550,- 300 + 600,- 300 - + 550,-1150 + 600,- 300 + 550,- 300 + 550,- 300 - + 550,- 350 + 550,- 300 + 550,- 350 + 550,- 300 - + 550,- 300 + 550,-1200 + 550,- 300 + 550,-1200 - + 550,- 300 + 550,- 300 + 600,- 300 + 550,- 300 - + 550,- 300 + 600,- 300 + 550,- 300 + 550,- 300 - + 550 -Sum: 54200 - - MSB first -Protocol=Panasonic Address=0xB Command=0x10 Raw-Data=0xA01000B02002 48 bits LSB first -Send with: IrSender.sendPanasonic(0xB, 0x10, <numberOfRepeats>); -rawData[100]: - -1076300 - +3550,-1600 - + 550,- 350 + 550,-1150 + 550,- 300 + 600,- 300 - + 550,- 300 + 600,- 300 + 550,- 300 + 550,- 300 - + 600,- 300 + 550,- 300 + 550,- 300 + 600,- 300 - + 550,- 300 + 550,-1200 + 550,- 300 + 550,- 300 - + 550,- 350 + 550,- 300 + 550,- 300 + 550,- 350 - + 550,-1150 + 550,-1200 + 550,- 300 + 550,-1200 - + 550,- 300 + 550,- 300 + 550,- 350 + 550,- 300 - + 550,- 350 + 550,- 350 + 550,- 300 + 550,- 300 - + 550,- 350 + 550,- 300 + 550,- 300 + 550,- 350 - + 550,-1150 + 550,- 300 + 600,- 300 + 550,- 300 - + 550,- 300 + 600,- 300 + 550,- 300 + 550,- 300 - + 600,- 300 + 550,-1150 + 550,- 350 + 550,-1150 - + 550 -Sum: 54250 - -Send generic 72 bit PulseDistance 0x5A AFEDCBA9 87654321 LSB first -Protocol=PulseDistance Raw-Data=0x5A 72 bits LSB first -Send with: - uint64_t tRawData[]={0xAFEDCBA987654321, 0x5A}; - IrSender.sendPulseDistanceWidthFromArray(38, 9000, 4350, 650, 1600, 650, 500, &tRawData[0], 72, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); -rawData[148]: - -1082050 - +9000,-4350 - + 700,-1600 + 650,- 500 + 700,- 500 + 650,- 500 - + 650,- 550 + 650,-1600 + 650,- 550 + 650,- 500 - + 700,-1600 + 650,-1650 + 650,- 500 + 650,- 500 - + 700,- 500 + 650,- 500 + 650,-1650 + 650,- 500 - + 650,-1650 + 650,- 500 + 650,-1650 + 650,- 500 - + 650,- 550 + 650,-1600 + 650,-1650 + 650,- 500 - + 650,-1650 + 650,-1600 + 700,-1600 + 650,- 500 - + 700,- 500 + 650,- 500 + 700,- 500 + 650,-1600 - + 700,-1600 + 650,- 500 + 700,- 500 + 650,-1600 - + 700,- 500 + 650,-1650 + 600,- 550 + 700,-1600 - + 650,-1650 + 650,-1600 + 650,- 550 + 650,-1600 - + 700,- 500 + 650,- 500 + 650,-1650 + 650,-1600 - + 650,-1650 + 650,- 500 + 700,-1600 + 650,-1650 - + 650,- 500 + 650,-1650 + 650,-1600 + 700,-1600 - + 650,-1650 + 650,-1600 + 700,-1600 + 650,-1650 - + 650,- 500 + 650,-1650 + 650,- 500 + 700,-1600 - + 650,- 500 + 700,-1600 + 650,- 550 + 650,-1600 - + 650,-1650 + 650,- 500 + 650,-1650 + 650,- 500 - + 650 -Sum: 140550 - -Send generic 52 bit PulseDistanceWidth 0xDCBA9 87654321 LSB first -Protocol=PulseWidth Raw-Data=0xDCBA987654321 52 bits LSB first -Send with: IrSender.sendPulseDistanceWidth(38, 400, 550, 750, 150, 400, 500, 0xDCBA987654321, 52, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); -rawData[106]: - -1120100 - + 400,- 550 - + 700,- 150 + 450,- 500 + 400,- 550 + 400,- 500 - + 400,- 500 + 700,- 150 + 450,- 550 + 400,- 500 - + 700,- 150 + 800,- 150 + 450,- 500 + 400,- 500 - + 400,- 550 + 350,- 550 + 700,- 200 + 400,- 550 - + 700,- 200 + 400,- 500 + 750,- 200 + 400,- 500 - + 400,- 550 + 700,- 150 + 750,- 200 + 450,- 500 - + 700,- 150 + 750,- 200 + 750,- 150 + 450,- 500 - + 400,- 550 + 400,- 500 + 400,- 500 + 700,- 150 - + 800,- 150 + 450,- 500 + 400,- 500 + 750,- 150 - + 450,- 500 + 700,- 200 + 450,- 500 + 700,- 250 - + 700,- 150 + 800,- 150 + 450,- 500 + 700,- 200 - + 450,- 500 + 400,- 500 + 700,- 200 + 750,- 150 - + 750,- 150 + 450,- 550 + 700,- 200 + 700 -Sum: 48450 - -Send generic 32 bit PulseWidth 0x87654321 LSB first -Protocol=PulseWidth Raw-Data=0x87654321 32 bits LSB first -Send with: IrSender.sendPulseDistanceWidth(38, 1100, 400, 750, 200, 450, 200, 0x87654321, 32, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>); -rawData[66]: - -1090450 - +1100,- 400 - + 700,- 150 + 450,- 200 + 450,- 150 + 450,- 200 - + 400,- 200 + 750,- 150 + 450,- 150 + 450,- 200 - + 700,- 200 + 750,- 200 + 400,- 200 + 400,- 200 - + 450,- 150 + 450,- 150 + 750,- 150 + 450,- 200 - + 750,- 200 + 400,- 200 + 750,- 150 + 450,- 150 - + 450,- 200 + 700,- 200 + 750,- 200 + 400,- 200 - + 750,- 150 + 750,- 200 + 700,- 200 + 450,- 150 - + 450,- 200 + 400,- 200 + 450,- 150 + 750 -Sum: 24900 - -Send MagiQuest 0x6BCDFF00, 0x176 as generic 55 bit PulseDistanceWidth MSB first -Protocol=MagiQuest Address=0xFF00 Command=0x176 Raw-Data=0x6BCDFF00 56 bits MSB first -Send with: IrSender.sendMagiQuest(0x6BCDFF00, 0x176, <numberOfRepeats>); -rawData[112]: - -1070250 - + 400,- 800 + 400,- 750 + 450,- 800 + 400,- 750 - + 400,- 800 + 400,- 750 + 400,- 800 + 400,- 750 - + 700,- 500 + 650,- 500 + 400,- 800 + 650,- 500 - + 400,- 800 + 650,- 500 + 700,- 500 + 650,- 500 - + 700,- 450 + 450,- 750 + 400,- 750 + 700,- 500 - + 700,- 450 + 400,- 800 + 700,- 450 + 700,- 500 - + 700,- 500 + 650,- 500 + 700,- 450 + 700,- 500 - + 700,- 450 + 700,- 500 + 700,- 450 + 400,- 800 - + 350,- 800 + 400,- 800 + 400,- 750 + 400,- 800 - + 400,- 750 + 400,- 800 + 400,- 750 + 700,- 450 - + 450,- 750 + 700,- 450 + 700,- 500 + 700,- 450 - + 400,- 800 + 650,- 500 + 700,- 500 + 400,- 750 - + 400,- 800 + 400,- 750 + 450,- 750 + 700,- 450 - + 700,- 500 + 400,- 750 + 400,- 800 + 700 -Sum: 65350 - -Send Onkyo (NEC with 16 bit command) -Protocol=Onkyo Address=0xFFF1 Command=0x7776 Raw-Data=0x7776FFF1 32 bits LSB first -Send with: IrSender.sendOnkyo(0xFFF1, 0x7776, <numberOfRepeats>); -rawData[68]: - -1086400 - +9050,-4400 - + 700,-1600 + 650,- 450 + 700,- 450 + 650,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,-1600 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,-1600 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,-1600 - + 650,- 450 + 700,-1600 + 650,-1600 + 650,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,- 450 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 450 - + 700,-1600 + 650,-1600 + 650,-1600 + 650,- 500 - + 650 -Sum: 77500 - -Send Apple -Protocol=Apple Address=0xF1 Command=0x76 Raw-Data=0xF17687EE 32 bits LSB first -Send with: IrSender.sendApple(0xF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1059500 - +9050,-4400 - + 700,- 500 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,- 500 + 650,-1600 + 650,-1600 + 650,-1600 - + 700,-1600 + 650,-1600 + 650,-1600 + 650,- 500 - + 650,- 450 + 700,- 450 + 700,- 450 + 650,-1600 - + 650,- 500 + 650,-1600 + 650,-1600 + 700,- 450 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 450 - + 700,-1600 + 650,- 450 + 650,- 500 + 650,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,-1600 - + 600 -Sum: 73000 - -Send Panasonic -Protocol=Panasonic Address=0xFF1 Command=0x76 Raw-Data=0x9976FF102002 48 bits LSB first -Send with: IrSender.sendPanasonic(0xFF1, 0x76, <numberOfRepeats>); -rawData[100]: - -1059200 - +3500,-1700 - + 500,- 350 + 500,-1250 + 500,- 400 + 500,- 350 - + 500,- 400 + 500,- 350 + 500,- 400 + 500,- 350 - + 500,- 400 + 500,- 350 + 500,- 400 + 500,- 350 - + 500,- 400 + 500,-1250 + 500,- 350 + 500,- 400 - + 500,- 350 + 500,- 400 + 450,- 400 + 500,- 400 - + 500,-1250 + 500,- 350 + 500,- 400 + 450,- 400 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,-1250 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,-1250 - + 500,- 400 + 500,-1250 + 500,-1250 + 500,- 350 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,- 400 - + 500,-1250 + 500,- 350 + 500,- 400 + 500,-1250 - + 500,-1250 + 500,- 400 + 500,- 350 + 500,-1250 - + 500 -Sum: 65200 - -Send Kaseikyo with 0x4711 as Vendor ID -Protocol=Kaseikyo Address=0xFF1 Command=0x76 Extra=0x4711 Raw-Data=0x9A76FF134711 48 bits LSB first -Send with: IrSender.sendKaseikyo(0xFF1, 0x76, <numberOfRepeats>, 0x4711); -rawData[100]: - -1079950 - +3550,-1650 - + 500,-1250 + 500,- 400 + 500,- 350 + 500,- 400 - + 500,-1250 + 500,- 350 + 550,- 350 + 500,- 400 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,- 350 - + 500,- 400 + 500,- 350 + 500,-1250 + 500,- 400 - + 500,-1250 + 500,-1250 + 500,- 350 + 500,- 400 - + 500,-1250 + 500,- 350 + 500,- 400 + 500,- 350 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,-1250 - + 500,-1250 + 500,-1250 + 500,-1250 + 550,-1200 - + 550,- 350 + 500,-1250 + 500,-1250 + 500,- 350 - + 500,-1250 + 500,-1250 + 500,-1250 + 550,- 350 - + 500,- 350 + 500,-1250 + 550,- 350 + 500,-1250 - + 500,-1250 + 500,- 350 + 500,- 400 + 500,-1250 - + 500 -Sum: 70500 - -Send Kaseikyo_Denon variant -Protocol=Kaseikyo_Denon Address=0xFF1 Command=0x76 Raw-Data=0x9976FF103254 48 bits LSB first -Send with: IrSender.sendKaseikyo_Denon(0xFF1, 0x76, <numberOfRepeats>); -rawData[100]: - -1080650 - +3550,-1650 - + 550,- 350 + 500,- 350 + 550,-1200 + 550,- 350 - + 500,-1250 + 500,- 350 + 550,-1200 + 500,- 400 - + 500,- 350 + 500,-1250 + 550,- 350 + 500,- 350 - + 550,-1200 + 550,-1200 + 550,- 350 + 500,- 350 - + 550,- 350 + 500,- 350 + 550,- 350 + 500,- 350 - + 550,-1200 + 550,- 350 + 500,- 350 + 550,- 350 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,-1250 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,-1250 - + 500,- 350 + 500,-1250 + 500,-1250 + 500,- 400 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,- 350 - + 500,-1250 + 550,- 350 + 500,- 350 + 550,-1250 - + 450,-1300 + 500,- 350 + 500,- 400 + 500,-1250 - + 500 -Sum: 68750 - -Send Denon -Protocol=Denon Address=0x11 Command=0x76 Raw-Data=0xED1 15 bits LSB first -Send with: IrSender.sendDenon(0x11, 0x76, <numberOfRepeats>); -rawData[32]: - -1078400 - + 350,-1750 + 350,- 700 + 350,- 700 + 350,- 700 - + 350,-1750 + 350,- 700 + 300,-1800 + 350,-1750 - + 350,- 700 + 350,-1750 + 350,-1750 + 350,-1750 - + 350,- 700 + 350,- 700 + 350,- 700 + 350 -Sum: 23450 - -Send Denon/Sharp variant -Protocol=Sharp Address=0x11 Command=0x76 Raw-Data=0x4ED1 15 bits LSB first -Send with: IrSender.sendSharp(0x11, 0x76, <numberOfRepeats>); -rawData[32]: - -1023500 - + 350,-1750 + 350,- 700 + 350,- 700 + 350,- 700 - + 350,-1750 + 350,- 700 + 350,-1750 + 350,-1750 - + 350,- 700 + 350,-1750 + 350,-1750 + 350,-1750 - + 350,- 700 + 300,- 750 + 350,-1750 + 350 -Sum: 24500 - -Send Sony/SIRCS with 7 command and 5 address bits -Protocol=Sony Address=0x11 Command=0x76 Raw-Data=0x8F6 12 bits LSB first -Send with: IrSender.sendSony(0x11, 0x76, 2, 12); -rawData[26]: - -1025750 - +2500,- 500 - + 700,- 500 +1300,- 650 +1250,- 550 + 700,- 500 - +1300,- 500 +1300,- 500 +1300,- 550 +1300,- 500 - + 700,- 500 + 700,- 500 + 700,- 550 +1250 -Sum: 21300 - -Send Sony/SIRCS with 7 command and 8 address bits -Protocol=Sony Address=0xF1 Command=0x76 Raw-Data=0x78F6 15 bits LSB first -Send with: IrSender.sendSony(0xF1, 0x76, 2, 15); -rawData[32]: - -1037600 - +2500,- 550 - + 650,- 550 +1300,- 500 +1300,- 500 + 700,- 500 - +1300,- 550 +1250,- 550 +1300,- 500 +1300,- 500 - + 700,- 500 + 700,- 550 + 650,- 550 +1300,- 500 - +1300,- 550 +1300,- 500 +1300 -Sum: 26700 - -Send Sony/SIRCS with 7 command and 13 address bits -Protocol=Sony Address=0x1FF1 Command=0x76 Raw-Data=0xFF8F6 20 bits LSB first -Send with: IrSender.sendSony(0x1FF1, 0x76, 2, 20); -rawData[42]: - -1041100 - +2500,- 500 - + 700,- 550 +1300,- 500 +1300,- 500 + 700,- 550 - +1250,- 550 +1300,- 500 +1300,- 550 +1300,- 500 - + 700,- 500 + 700,- 500 + 700,- 500 +1300,- 550 - +1300,- 500 +1300,- 500 +1300,- 500 +1300,- 550 - +1300,- 500 +1300,- 500 +1300,- 550 +1250 -Sum: 35750 - -Send Samsung 8 bit command -Protocol=Samsung Address=0xFFF1 Command=0x76 Raw-Data=0x8976FFF1 32 bits LSB first -Send with: IrSender.sendSamsung(0xFFF1, 0x76, <numberOfRepeats>); -rawData[68]: - -1044850 - +4550,-4400 - + 700,-1600 + 650,- 450 + 700,- 450 + 650,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,-1600 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,-1600 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,-1600 - + 650,- 450 + 700,-1600 + 650,-1600 + 650,- 500 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 450 - + 700,-1600 + 650,- 450 + 650,- 500 + 650,-1600 - + 650,- 500 + 650,- 450 + 700,- 450 + 650,-1600 - + 650 -Sum: 69600 - -Send Samsung 16 bit command -Protocol=Samsung Address=0xFFF1 Command=0x9876 Raw-Data=0x9876FFF1 32 bits LSB first -Send with: IrSender.sendSamsung(0xFFF1, 0x9876, <numberOfRepeats>); -rawData[68]: - -1061000 - +4600,-4400 - + 650,-1600 + 700,- 450 + 650,- 500 + 650,- 450 - + 700,-1550 + 700,-1600 + 650,-1600 + 650,-1600 - + 650,-1600 + 700,-1600 + 650,-1600 + 650,-1600 - + 650,-1600 + 700,-1600 + 650,-1600 + 650,-1600 - + 650,- 500 + 650,-1600 + 700,-1600 + 650,- 450 - + 700,-1600 + 650,-1600 + 650,-1600 + 650,- 500 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,-1600 - + 650,-1600 + 650,- 500 + 650,- 450 + 700,-1600 - + 650 -Sum: 69650 - -Send Samsung48 16 bit command -Protocol=Samsung48 Address=0xFFF1 Command=0x9876 Raw-Data=0xFFFFFFFF8976FFF1 48 bits LSB first -Send with: IrSender.sendSamsung48(0xFFF1, 0x9876, <numberOfRepeats>); -rawData[100]: - -1066350 - +4550,-4400 - + 650,-1650 + 600,- 500 + 700,- 450 + 650,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,-1600 - + 600,-1650 + 650,-1600 + 650,-1600 + 700,-1600 - + 600,-1650 + 650,-1600 + 650,-1600 + 700,-1550 - + 700,- 450 + 650,-1600 + 700,-1600 + 600,- 500 - + 650,-1600 + 700,-1600 + 650,-1600 + 650,- 500 - + 650,-1600 + 650,- 500 + 650,- 500 + 650,-1600 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,-1600 - + 650,- 500 + 650,- 450 + 650,- 500 + 650,-1600 - + 650,-1600 + 700,- 450 + 650,- 500 + 650,-1600 - + 650,-1600 + 650,-1600 + 650,-1650 + 650,- 450 - + 650,- 500 + 650,-1600 + 650,-1600 + 650,- 500 - + 650 -Sum: 96750 - -Send RC5 -Protocol=RC5 Address=0x11 Command=0x36 Raw-Data=0x1476 13 bits MSB first -Send with: IrSender.sendRC5(0x11, 0x36, <numberOfRepeats>); -rawData[20]: - -1079150 - +1000,- 800 - +1900,-1650 +1900,- 800 +1000,- 800 +1000,-1700 - +1000,- 800 +1000,- 750 +1900,-1700 +1000,- 800 - +1900 -Sum: 23400 - -Send RC5X with 7.th MSB of command set -Protocol=RC5 Address=0x11 Command=0x76 Toggle=1 Raw-Data=0xC76 13 bits MSB first -Send with: IrSender.sendRC5(0x11, 0x76, <numberOfRepeats>); -rawData[20]: - -1035450 - +1900,-1700 - +1000,- 800 +1900,- 750 +1000,- 800 +1000,-1700 - +1000,- 800 +1000,- 800 +1900,-1650 +1000,- 800 - +1900 -Sum: 23400 - -Send RC6 -Protocol=RC6 Address=0xF1 Command=0x76 Raw-Data=0xF176 20 bits MSB first -Send with: IrSender.sendRC6(0xF1, 0x76, <numberOfRepeats>); -rawData[36]: - -1032650 - +2750,- 800 - + 550,- 800 + 550,- 350 + 550,- 350 + 550,- 800 - +1450,- 350 + 550,- 350 + 550,- 350 + 550,- 800 - + 550,- 350 + 550,- 350 +1000,- 800 +1000,- 350 - + 550,- 350 + 550,- 800 +1000,- 350 + 550,- 800 - + 550 -Sum: 23450 - -Send JVC -Protocol=JVC Address=0xF1 Command=0x76 Raw-Data=0x76F1 16 bits LSB first -Send with: IrSender.sendJVC(0xF1, 0x76, <numberOfRepeats>); -rawData[36]: - -1040750 - +8500,-4150 - + 650,-1500 + 650,- 400 + 650,- 450 + 600,- 450 - + 650,-1500 + 600,-1500 + 650,-1500 + 600,-1550 - + 600,- 450 + 650,-1500 + 650,-1450 + 650,- 450 - + 650,-1450 + 650,-1500 + 650,-1500 + 600,- 450 - + 650 -Sum: 41050 - -Send Samsung -Protocol=Samsung Address=0xFFF1 Command=0x9876 Raw-Data=0x9876FFF1 32 bits LSB first -Send with: IrSender.sendSamsung(0xFFF1, 0x9876, <numberOfRepeats>); -rawData[68]: - -1040900 - +4600,-4400 - + 650,-1600 + 700,- 450 + 650,- 500 + 650,- 450 - + 700,-1600 + 650,-1600 + 650,-1600 + 650,-1600 - + 650,-1650 + 650,-1600 + 650,-1600 + 650,-1600 - + 650,-1600 + 700,-1600 + 650,-1600 + 650,-1600 - + 650,- 500 + 650,-1600 + 650,-1600 + 700,- 450 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 450 - + 700,- 450 + 650,- 500 + 650,- 450 + 650,-1600 - + 700,-1600 + 650,- 500 + 650,- 450 + 650,-1600 - + 700 -Sum: 69650 - -Send LG -Protocol=LG Address=0xF1 Command=0x9876 Raw-Data=0xF19876E 28 bits MSB first -Send with: IrSender.sendLG(0xF1, 0x9876, <numberOfRepeats>); -rawData[60]: - -1059650 - +9100,-4100 - + 650,-1500 + 600,-1500 + 600,-1500 + 600,-1500 - + 600,- 500 + 600,- 450 + 600,- 450 + 650,-1500 - + 600,-1500 + 600,- 450 + 600,- 500 + 600,-1500 - + 600,-1500 + 600,- 500 + 600,- 450 + 600,- 450 - + 650,- 450 + 600,-1500 + 600,-1500 + 600,-1500 - + 650,- 450 + 600,-1500 + 600,-1500 + 600,- 500 - + 600,-1500 + 600,-1500 + 600,-1500 + 600,- 500 - + 600 -Sum: 60450 - -Send MagiQuest -Protocol=MagiQuest Address=0xFFF1 Command=0x76 Raw-Data=0x6BCDFFF1 56 bits MSB first -Send with: IrSender.sendMagiQuest(0x6BCDFFF1, 0x76, <numberOfRepeats>); -rawData[112]: - -1054600 - + 400,- 750 + 400,- 800 + 400,- 750 + 400,- 750 - + 400,- 800 + 400,- 750 + 400,- 800 + 400,- 750 - + 700,- 500 + 650,- 500 + 400,- 800 + 650,- 500 - + 400,- 750 + 700,- 500 + 700,- 450 + 700,- 500 - + 650,- 500 + 400,- 800 + 400,- 750 + 700,- 500 - + 650,- 500 + 400,- 800 + 650,- 500 + 700,- 450 - + 700,- 500 + 650,- 500 + 700,- 500 + 650,- 500 - + 700,- 450 + 700,- 500 + 700,- 450 + 700,- 500 - + 650,- 500 + 700,- 450 + 700,- 500 + 400,- 750 - + 400,- 800 + 400,- 750 + 700,- 500 + 400,- 800 - + 400,- 750 + 700,- 450 + 700,- 500 + 650,- 500 - + 400,- 800 + 650,- 500 + 700,- 450 + 400,- 800 - + 400,- 750 + 400,- 800 + 650,- 500 + 700,- 500 - + 350,- 800 + 700,- 450 + 700,- 500 + 650 -Sum: 65100 - -Send Bang&Olufsen -Protocol=Bang&Olufsen Address=0xF1 Command=0x76 Raw-Data=0xF176 16 bits MSB first -Send with: IrSender.sendBang&Olufsen(0xF1, 0x76, <numberOfRepeats>); -rawData[44]: - -1084600 - + 300,-2850 - + 250,-2900 + 250,-15400 + 300,-2850 + 300,-9100 - + 250,-6050 + 250,-6000 + 250,-6000 + 300,-2850 - + 300,-6000 + 250,-6000 + 300,-9100 + 300,-2850 - + 300,-9100 + 300,-6000 + 250,-6000 + 300,-2850 - + 300,-9100 + 250,-6000 + 300,-2900 + 250,-12250 - + 300 -Sum: 138300 - -Send Bosewave with no address and 8 command bits -Protocol=BoseWave Address=0x0 Command=0x76 Raw-Data=0x8976 16 bits LSB first -Send with: IrSender.sendBoseWave(0x0, 0x76, <numberOfRepeats>); -rawData[36]: - -1050250 - +1100,-1400 - + 600,- 400 + 600,-1400 + 600,-1400 + 600,- 400 - + 600,-1400 + 600,-1400 + 650,-1400 + 600,- 400 - + 600,-1400 + 600,- 400 + 600,- 400 + 600,-1400 - + 600,- 400 + 600,- 400 + 600,- 400 + 600,-1400 - + 600 -Sum: 27150 - -Send FAST -Protocol=FAST Address=0x0 Command=0x76 Raw-Data=0x8976 16 bits LSB first -Send with: IrSender.sendFAST(0x0, 0x76, <numberOfRepeats>); -rawData[36]: - -1041350 - +2200,-1000 - + 650,- 400 + 650,-1500 + 650,-1500 + 600,- 450 - + 650,-1500 + 650,-1500 + 600,-1500 + 650,- 450 - + 600,-1500 + 650,- 450 + 600,- 450 + 650,-1500 - + 600,- 450 + 650,- 450 + 600,- 450 + 650,-1500 - + 600 -Sum: 29450 - -Force buffer overflow by sending 280 marks and spaces -Overflow -Try to increase the "RAW_BUFFER_LENGTH" value of 200 in UnitTest.cpp -rawData[200]: - -1039850 - + 300,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 300,- 500 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 500 + 300,- 450 + 350,- 450 + 300,- 500 - + 350,- 450 + 300,- 450 + 350,- 450 + 300,- 450 - + 350,- 400 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 300,- 500 + 300,- 450 + 300,- 500 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 350,- 450 + 300,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 450 + 300,- 450 + 350,- 450 - + 300,- 450 + 350,- 400 + 350,- 450 + 300,- 450 - + 350,- 450 + 300,- 450 + 350,- 450 + 300,- 450 - + 350,- 450 + 300,- 450 + 350,- 450 + 300,- 450 - + 350,- 450 + 300,- 450 + 350,- 450 + 300,- 450 - + 350,- 450 + 300,- 450 + 300,- 500 + 300,- 450 - + 350,- 450 + 300,- 450 + 300,- 500 + 300,- 450 - + 350,- 450 + 350,- 450 + 300,- 450 + 300,- 450 - + 350,- 450 + 300,- 450 + 350,- 450 + 300,- 450 - + 350,- 450 + 300,- 450 + 350 -Sum: 77050 -ERROR: Unknown protocol - - -address=0xF2 command=0x87 - -Send NEC with 8 bit address -Protocol=NEC Address=0xF2 Command=0x87 Raw-Data=0x78870DF2 32 bits LSB first -Send with: IrSender.sendNEC(0xF2, 0x87, <numberOfRepeats>); -rawData[68]: - -3276750 - +9050,-4400 - + 650,- 500 + 650,-1600 + 650,- 500 + 650,- 450 - + 650,-1600 + 700,-1600 + 650,-1600 + 650,-1600 - + 650,-1600 + 650,- 500 + 650,-1600 + 700,-1550 - + 650,- 500 + 650,- 500 + 600,- 500 + 700,- 450 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 450 - + 700,- 450 + 650,- 500 + 650,- 450 + 700,-1550 - + 700,- 450 + 650,- 500 + 650,- 500 + 650,-1600 - + 650,-1650 + 650,-1600 + 650,-1600 + 650,- 500 - + 650 -Sum: 68450 - -Send NEC with 16 bit address -Protocol=NEC Address=0xF2 Command=0x87 Raw-Data=0x78870DF2 32 bits LSB first -Send with: IrSender.sendNEC(0xF2, 0x87, <numberOfRepeats>); -rawData[68]: - -1060000 - +9100,-4400 - + 650,- 450 + 700,-1600 + 650,- 450 + 700,- 450 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,-1600 + 650,- 500 + 650,-1600 + 650,-1600 - + 650,- 500 + 650,- 500 + 600,- 500 + 650,- 500 - + 650,-1600 + 650,-1600 + 650,-1600 + 700,- 450 - + 650,- 500 + 600,- 500 + 650,- 500 + 650,-1600 - + 650,- 500 + 650,- 450 + 700,- 450 + 650,-1600 - + 700,-1550 + 700,-1600 + 650,-1600 + 650,- 500 - + 650 -Sum: 68450 - -Send NEC2 with 16 bit address -Protocol=NEC Address=0xF2 Command=0x87 Raw-Data=0x78870DF2 32 bits LSB first -Send with: IrSender.sendNEC(0xF2, 0x87, <numberOfRepeats>); -rawData[68]: - -1060100 - +9050,-4400 - + 700,- 450 + 650,-1600 + 650,- 500 + 650,- 450 - + 700,-1600 + 650,-1600 + 650,-1600 + 650,-1600 - + 700,-1600 + 650,- 450 + 700,-1600 + 650,-1600 - + 650,- 500 + 600,- 500 + 650,- 500 + 650,- 450 - + 700,-1600 + 650,-1600 + 650,-1600 + 650,- 500 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,-1600 - + 650,- 500 + 650,- 500 + 650,- 450 + 650,-1600 - + 700,-1600 + 600,-1650 + 650,-1600 + 650,- 500 - + 650 -Sum: 68450 - -Send Onkyo (NEC with 16 bit command) -Protocol=Onkyo Address=0xF2 Command=0x8887 Raw-Data=0x888700F2 32 bits LSB first -Send with: IrSender.sendOnkyo(0xF2, 0x8887, <numberOfRepeats>); -rawData[68]: - -1060700 - +9100,-4400 - + 650,- 450 + 700,-1600 + 650,- 450 + 700,- 450 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,- 450 - + 700,- 450 + 650,- 500 + 650,- 450 + 650,- 500 - + 650,-1600 + 650,-1600 + 700,-1550 + 700,- 450 - + 650,- 500 + 650,- 500 + 650,- 450 + 650,-1600 - + 700,- 450 + 650,- 500 + 650,- 450 + 650,-1650 - + 650,- 500 + 650,- 450 + 700,- 450 + 650,-1600 - + 650 -Sum: 62800 - -Send Apple -Protocol=Apple Address=0xF2 Command=0x87 Raw-Data=0xF28787EE 32 bits LSB first -Send with: IrSender.sendApple(0xF2, 0x87, <numberOfRepeats>); -rawData[68]: - -1059150 - +9050,-4400 - + 650,- 500 + 650,-1600 + 650,-1600 + 700,-1600 - + 650,- 450 + 650,-1600 + 700,-1600 + 650,-1600 - + 650,-1600 + 650,-1600 + 700,-1600 + 650,- 450 - + 700,- 450 + 650,- 500 + 650,- 450 + 650,-1600 - + 700,-1600 + 650,-1600 + 650,-1600 + 650,- 500 - + 650,- 450 + 700,- 450 + 650,- 500 + 650,-1600 - + 650,- 500 + 600,-1650 + 650,- 500 + 650,- 450 - + 650,-1600 + 650,-1650 + 650,-1600 + 650,-1600 - + 650 -Sum: 71800 - -Send Panasonic -Protocol=Panasonic Address=0xF2 Command=0x87 Raw-Data=0xA8870F202002 48 bits LSB first -Send with: IrSender.sendPanasonic(0xF2, 0x87, <numberOfRepeats>); -rawData[100]: - -1069050 - +3550,-1650 - + 500,- 400 + 500,-1250 + 500,- 350 + 500,- 400 - + 500,- 350 + 500,- 400 + 500,- 350 + 500,- 400 - + 500,- 350 + 500,- 400 + 500,- 350 + 500,- 400 - + 500,- 350 + 500,-1250 + 500,- 400 + 500,- 350 - + 500,- 400 + 500,- 350 + 500,- 400 + 500,- 350 - + 500,- 400 + 450,-1300 + 500,- 350 + 550,- 350 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,-1250 - + 500,- 350 + 500,- 400 + 500,- 350 + 500,- 400 - + 500,-1250 + 500,-1250 + 450,-1300 + 500,- 350 - + 500,- 400 + 450,- 400 + 500,- 400 + 450,-1300 - + 500,- 350 + 550,- 350 + 500,- 350 + 500,-1250 - + 550,- 350 + 500,-1250 + 450,- 400 + 550,-1200 - + 550 -Sum: 60000 - -Send Kaseikyo with 0x4711 as Vendor ID -Protocol=Kaseikyo Address=0xF2 Command=0x87 Extra=0x4711 Raw-Data=0xAB870F234711 48 bits LSB first -Send with: IrSender.sendKaseikyo(0xF2, 0x87, <numberOfRepeats>, 0x4711); -rawData[100]: - -1079750 - +3550,-1650 - + 550,-1200 + 550,- 350 + 500,- 350 + 550,- 350 - + 500,-1250 + 500,- 350 + 550,- 350 + 500,- 350 - + 550,-1200 + 550,-1200 + 550,-1200 + 550,- 350 - + 500,- 350 + 550,- 350 + 500,-1250 + 500,- 350 - + 550,-1200 + 550,-1200 + 550,- 350 + 500,- 350 - + 550,- 350 + 500,-1250 + 500,- 350 + 550,- 350 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,-1250 - + 500,- 300 + 550,- 400 + 500,- 350 + 550,- 350 - + 500,-1250 + 500,-1250 + 500,-1250 + 500,- 350 - + 500,- 400 + 500,- 350 + 500,- 400 + 500,-1250 - + 500,-1250 + 500,-1250 + 500,- 350 + 500,-1250 - + 500,- 400 + 500,-1250 + 500,- 350 + 500,-1250 - + 550 -Sum: 67000 \ No newline at end of file diff --git a/IRremote/irPronto.cpp b/IRremote/irPronto.cpp deleted file mode 100644 index 49d2685f962d5a306853e649eda875073b3711ef..0000000000000000000000000000000000000000 --- a/IRremote/irPronto.cpp +++ /dev/null @@ -1,513 +0,0 @@ -#define TEST 0 - -#if TEST -# define SEND_PRONTO 1 -# define PRONTO_ONCE false -# define PRONTO_REPEAT true -# define PRONTO_FALLBACK true -# define PRONTO_NOFALLBACK false -#endif - -#if SEND_PRONTO - -//****************************************************************************** -#if TEST -# include <stdio.h> - void enableIROut (int freq) { printf("\nFreq = %d KHz\n", freq); } - void mark (int t) { printf("+%d," , t); } - void space (int t) { printf("-%d, ", t); } -#else -# include "IRremote.h" -#endif // TEST - -//+============================================================================= -// Check for a valid hex digit -// -bool ishex (char ch) -{ - return ( ((ch >= '0') && (ch <= '9')) || - ((ch >= 'A') && (ch <= 'F')) || - ((ch >= 'a') && (ch <= 'f')) ) ? true : false ; -} - -//+============================================================================= -// Check for a valid "blank" ... '\0' is a valid "blank" -// -bool isblank (char ch) -{ - return ((ch == ' ') || (ch == '\t') || (ch == '\0')) ? true : false ; -} - -//+============================================================================= -// Bypass spaces -// -bool byp (char** pcp) -{ - while (isblank(**pcp)) (*pcp)++ ; -} - -//+============================================================================= -// Hex-to-Byte : Decode a hex digit -// We assume the character has already been validated -// -uint8_t htob (char ch) -{ - if ((ch >= '0') && (ch <= '9')) return ch - '0' ; - if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; - if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; -} - -//+============================================================================= -// Hex-to-Word : Decode a block of 4 hex digits -// We assume the string has already been validated -// and the pointer being passed points at the start of a block of 4 hex digits -// -uint16_t htow (char* cp) -{ - return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | - (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; -} - -//+============================================================================= -// -bool sendPronto (char* s, bool repeat, bool fallback) -{ - int i; - int len; - int skip; - char* cp; - uint16_t freq; // Frequency in KHz - uint8_t usec; // pronto uSec/tick - uint8_t once; - uint8_t rpt; - - // Validate the string - for (cp = s; *cp; cp += 4) { - byp(&cp); - if ( !ishex(cp[0]) || !ishex(cp[1]) || - !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; - } - - // We will use cp to traverse the string - cp = s; - - // Check mode = Oscillated/Learned - byp(&cp); - if (htow(cp) != 0000) return false; - cp += 4; - - // Extract & set frequency - byp(&cp); - freq = (int)(1000000 / (htow(cp) * 0.241246)); // Rounding errors will occur, tolerance is +/- 10% - usec = (int)(((1.0 / freq) * 1000000) + 0.5); // Another rounding error, thank Cod for analogue electronics - freq /= 1000; // This will introduce a(nother) rounding error which we do not want in the usec calcualtion - cp += 4; - - // Get length of "once" code - byp(&cp); - once = htow(cp); - cp += 4; - - // Get length of "repeat" code - byp(&cp); - rpt = htow(cp); - cp += 4; - - // Which code are we sending? - if (fallback) { // fallback on the "other" code if "this" code is not present - if (!repeat) { // requested 'once' - if (once) len = once * 2, skip = 0 ; // if once exists send it - else len = rpt * 2, skip = 0 ; // else send repeat code - } else { // requested 'repeat' - if (rpt) len = rpt * 2, skip = 0 ; // if rpt exists send it - else len = once * 2, skip = 0 ; // else send once code - } - } else { // Send what we asked for, do not fallback if the code is empty! - if (!repeat) len = once * 2, skip = 0 ; // 'once' starts at 0 - else len = rpt * 2, skip = once ; // 'repeat' starts where 'once' ends - } - - // Skip to start of code - for (i = 0; i < skip; i++, cp += 4) byp(&cp) ; - - // Send code - enableIROut(freq); - for (i = 0; i < len; i++) { - byp(&cp); - if (i & 1) space(htow(cp) * usec); - else mark (htow(cp) * usec); - cp += 4; - } -} - -//+============================================================================= -#if TEST - -int main ( ) -{ - char prontoTest[] = - "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 - "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 - "0010 0030 0010 0aa6"; // 104 - - sendPronto(prontoTest, PRONTO_ONCE, PRONTO_FALLBACK); // once code - sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_FALLBACK); // repeat code - sendPronto(prontoTest, PRONTO_ONCE, PRONTO_NOFALLBACK); // once code - sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_NOFALLBACK); // repeat code - - return 0; -} - -#endif // TEST - -#endif // SEND_PRONTO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if 0 -//****************************************************************************** -// Sources: -// http://www.remotecentral.com/features/irdisp2.htm -// http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex -//****************************************************************************** - -#include <stdint.h> -#include <stdio.h> - -#define IRPRONTO -#include "IRremoteInt.h" // The Arduino IRremote library defines USECPERTICK - -//------------------------------------------------------------------------------ -// Source: https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet -// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls -// -char prontoTest[] = - "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 - "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 - "0010 0030 0010 0aa6"; // 104 - -//------------------------------------------------------------------------------ -// This is the longest code we can support -#define CODEMAX 200 - -//------------------------------------------------------------------------------ -// This is the data we pull out of the pronto code -typedef - struct { - int freq; // Carrier frequency (in Hz) - int usec; // uSec per tick (based on freq) - - int codeLen; // Length of code - uint16_t code[CODEMAX]; // Code in hex - - int onceLen; // Length of "once" transmit - uint16_t* once; // Pointer to start within 'code' - - int rptLen; // Length of "repeat" transmit - uint16_t* rpt; // Pointer to start within 'code' - } -pronto_t; - -//------------------------------------------------------------------------------ -// From what I have seen, the only time we go over 8-bits is the 'space' -// on the end which creates the lead-out/inter-code gap. Assuming I'm right, -// we can code this up as a special case and otherwise halve the size of our -// data! -// Ignoring the first four values (the config data) and the last value -// (the lead-out), if you find a protocol that uses values greater than 00fe -// we are going to have to revisit this code! -// -// -// So, the 0th byte will be the carrier frequency in Khz (NOT Hz) -// " 1st " " " " length of the "once" code -// " 2nd " " " " length of the "repeat" code -// -// Thereafter, odd bytes will be Mark lengths as a multiple of USECPERTICK uS -// even " " " Space " " " " " " " -// -// Any occurence of "FF" in either a Mark or a Space will indicate -// "Use the 16-bit FF value" which will also be a multiple of USECPERTICK uS -// -// -// As a point of comparison, the test code (prontoTest[]) is 520 bytes -// (yes, more than 0.5KB of our Arduino's precious 32KB) ... after conversion -// to pronto hex that goes down to ((520/5)*2) = 208 bytes ... once converted to -// our format we are down to ((208/2) -1 -1 +2) = 104 bytes -// -// In fariness this is still very memory-hungry -// ...As a rough guide: -// 10 codes cost 1K of memory (this will vary depending on the protocol). -// -// So if you're building a complex remote control, you will probably need to -// keep the codes on an external memory device (not in the Arduino sketch) and -// load them as you need them. Hmmm. -// -// This dictates that "Oscillated Pronto Codes" are probably NOT the way forward -// -// For example, prontoTest[] happens to be: A 48-bit IR code in Denon format -// So we know it starts with 80/40 (Denon header) -// and ends with 10/aa6 (Denon leadout) -// and all (48) bits in between are either 10/10 (Denon 0) -// or 10/30 (Denon 1) -// So we could easily store this data in 1-byte ("Denon") -// + 1-byte (Length=48) -// + 6-bytes (IR code) -// At 8-bytes per code, we can store 128 codes in 1KB or memory - that's a lot -// better than the 2 (two) we started off with! -// -// And serendipitously, by reducing the amount of data, our program will run -// a LOT faster! -// -// Again, I repeat, even after you have spent time converting the "Oscillated -// Pronto Codes" in to IRremote format, it will be a LOT more memory-hungry -// than using sendDenon() (or whichever) ...BUT these codes are easily -// available on the internet, so we'll support them! -// -typedef - struct { - uint16_t FF; - uint8_t code[CODEMAX]; - } -irCode_t; - -//------------------------------------------------------------------------------ -#define DEBUGF(...) printf(__VA_ARGS__) - -//+============================================================================= -// String must be block of 4 hex digits separated with blanks -// -bool validate (char* cp, int* len) -{ - for (*len = 0; *cp; (*len)++, cp += 4) { - byp(&cp); - if ( !ishex(cp[0]) || !ishex(cp[1]) || - !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; - } - - return true; -} - -//+============================================================================= -// Hex-to-Byte : Decode a hex digit -// We assume the character has already been validated -// -uint8_t htob (char ch) -{ - if ((ch >= '0') && (ch <= '9')) return ch - '0' ; - if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; - if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; -} - -//+============================================================================= -// Hex-to-Word : Decode a block of 4 hex digits -// We assume the string has already been validated -// and the pointer being passed points at the start of a block of 4 hex digits -// -uint16_t htow (char* cp) -{ - return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | - (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; -} - -//+============================================================================= -// Convert the pronto string in to data -// -bool decode (char* s, pronto_t* p, irCode_t* ir) -{ - int i, len; - char* cp; - - // Validate the Pronto string - if (!validate(s, &p->codeLen)) { - DEBUGF("Invalid pronto string\n"); - return false ; - } - DEBUGF("Found %d hex codes\n", p->codeLen); - - // Allocate memory to store the decoded string - //if (!(p->code = malloc(p->len))) { - // DEBUGF("Memory allocation failed\n"); - // return false ; - //} - - // Check in case our code is too long - if (p->codeLen > CODEMAX) { - DEBUGF("Code too long, edit CODEMAX and recompile\n"); - return false ; - } - - // Decode the string - cp = s; - for (i = 0; i < p->codeLen; i++, cp += 4) { - byp(&cp); - p->code[i] = htow(cp); - } - - // Announce our findings - DEBUGF("Input: |%s|\n", s); - DEBUGF("Found: |"); - for (i = 0; i < p->codeLen; i++) DEBUGF("%04x ", p->code[i]) ; - DEBUGF("|\n"); - - DEBUGF("Form [%04X] : ", p->code[0]); - if (p->code[0] == 0x0000) DEBUGF("Oscillated (Learned)\n"); - else if (p->code[0] == 0x0100) DEBUGF("Unmodulated\n"); - else DEBUGF("Unknown\n"); - if (p->code[0] != 0x0000) return false ; // Can only handle Oscillated - - // Calculate the carrier frequency (+/- 10%) & uSecs per pulse - // Pronto uses a crystal which generates a timeabse of 0.241246 - p->freq = (int)(1000000 / (p->code[1] * 0.241246)); - p->usec = (int)(((1.0 / p->freq) * 1000000) + 0.5); - ir->code[0] = p->freq / 1000; - DEBUGF("Freq [%04X] : %d Hz (%d uS/pluse) -> %d KHz\n", - p->code[1], p->freq, p->usec, ir->code[0]); - - // Set the length & start pointer for the "once" code - p->onceLen = p->code[2]; - p->once = &p->code[4]; - ir->code[1] = p->onceLen; - DEBUGF("Once [%04X] : %d\n", p->code[2], p->onceLen); - - // Set the length & start pointer for the "repeat" code - p->rptLen = p->code[3]; - p->rpt = &p->code[4 + p->onceLen]; - ir->code[2] = p->rptLen; - DEBUGF("Rpt [%04X] : %d\n", p->code[3], p->rptLen); - - // Check everything tallies - if (1 + 1 + 1 + 1 + (p->onceLen * 2) + (p->rptLen * 2) != p->codeLen) { - DEBUGF("Bad code length\n"); - return false; - } - - // Convert the IR data to our new format - ir->FF = p->code[p->codeLen - 1]; - - len = (p->onceLen * 2) + (p->rptLen * 2); - DEBUGF("Encoded: |"); - for (i = 0; i < len; i++) { - if (p->code[i+4] == ir->FF) { - ir->code[i+3] = 0xFF; - } else if (p->code[i+4] > 0xFE) { - DEBUGF("\n%04X : Mark/Space overflow\n", p->code[i+4]); - return false; - } else { - ir->code[i+3] = (p->code[i+4] * p->usec) / USECPERTICK; - } - DEBUGF("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); - } - DEBUGF("|\n"); - - ir->FF = (ir->FF * p->usec) / USECPERTICK; - DEBUGF("FF -> %d\n", ir->FF); - - return true; -} - -//+============================================================================= -// -void irDump (irCode_t* ir) -{ - int i, len; - - printf("uint8_t buttonName[%d] = {", len); - - printf("%d,%d, ", (ir->FF >> 8), ir->FF & 0xFF); - printf("%d,%d,%d, ", ir->code[0], ir->code[1], ir->code[2]); - - len = (ir->code[1] * 2) + (ir->code[2] * 2); - for (i = 0; i < len; i++) { - printf("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); - } - - printf("};\n"); - -} - -//+============================================================================= -// -int main ( ) -{ - pronto_t pCode; - irCode_t irCode; - - decode(prontoTest, &pCode, &irCode); - - irDump(&irCode); - - return 0; -} - -#endif //0 diff --git a/IRremote/irRecv.cpp b/IRremote/irRecv.cpp deleted file mode 100644 index 163f2960e29d7705278f2bdd8793c59cb42ed39d..0000000000000000000000000000000000000000 --- a/IRremote/irRecv.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//+============================================================================= -// Decodes the received IR message -// Returns 0 if no data ready, 1 if data ready. -// Results of decoding are stored in results -// -int IRrecv::decode (decode_results *results) -{ - results->rawbuf = irparams.rawbuf; - results->rawlen = irparams.rawlen; - - results->overflow = irparams.overflow; - - if (irparams.rcvstate != STATE_STOP) return false ; - -#if DECODE_NEC - DBG_PRINTLN("Attempting NEC decode"); - if (decodeNEC(results)) return true ; -#endif - -#if DECODE_SONY - DBG_PRINTLN("Attempting Sony decode"); - if (decodeSony(results)) return true ; -#endif - -#if DECODE_SANYO - DBG_PRINTLN("Attempting Sanyo decode"); - if (decodeSanyo(results)) return true ; -#endif - -#if DECODE_MITSUBISHI - DBG_PRINTLN("Attempting Mitsubishi decode"); - if (decodeMitsubishi(results)) return true ; -#endif - -#if DECODE_RC5 - DBG_PRINTLN("Attempting RC5 decode"); - if (decodeRC5(results)) return true ; -#endif - -#if DECODE_RC6 - DBG_PRINTLN("Attempting RC6 decode"); - if (decodeRC6(results)) return true ; -#endif - -#if DECODE_PANASONIC - DBG_PRINTLN("Attempting Panasonic decode"); - if (decodePanasonic(results)) return true ; -#endif - -#if DECODE_LG - DBG_PRINTLN("Attempting LG decode"); - if (decodeLG(results)) return true ; -#endif - -#if DECODE_JVC - DBG_PRINTLN("Attempting JVC decode"); - if (decodeJVC(results)) return true ; -#endif - -#if DECODE_SAMSUNG - DBG_PRINTLN("Attempting SAMSUNG decode"); - if (decodeSAMSUNG(results)) return true ; -#endif - -#if DECODE_WHYNTER - DBG_PRINTLN("Attempting Whynter decode"); - if (decodeWhynter(results)) return true ; -#endif - -#if DECODE_AIWA_RC_T501 - DBG_PRINTLN("Attempting Aiwa RC-T501 decode"); - if (decodeAiwaRCT501(results)) return true ; -#endif - -#if DECODE_DENON - DBG_PRINTLN("Attempting Denon decode"); - if (decodeDenon(results)) return true ; -#endif - -#if DECODE_LEGO_PF - DBG_PRINTLN("Attempting Lego Power Functions"); - if (decodeLegoPowerFunctions(results)) return true ; -#endif - - // decodeHash returns a hash on any input. - // Thus, it needs to be last in the list. - // If you add any decodes, add them before this. - if (decodeHash(results)) return true ; - - // Throw away and start over - resume(); - return false; -} - -//+============================================================================= -IRrecv::IRrecv (int recvpin) -{ - irparams.recvpin = recvpin; - irparams.blinkflag = 0; -} - -IRrecv::IRrecv (int recvpin, int blinkpin) -{ - irparams.recvpin = recvpin; - irparams.blinkpin = blinkpin; - pinMode(blinkpin, OUTPUT); - irparams.blinkflag = 0; -} - - - -//+============================================================================= -// initialization -// -#ifdef USE_DEFAULT_ENABLE_IR_IN -void IRrecv::enableIRIn ( ) -{ -// Interrupt Service Routine - Fires every 50uS - cli(); - // Setup pulse clock timer interrupt - // Prescale /8 (16M/8 = 0.5 microseconds per tick) - // Therefore, the timer interval can range from 0.5 to 128 microseconds - // Depending on the reset value (255 to 0) - TIMER_CONFIG_NORMAL(); - - // Timer2 Overflow Interrupt Enable - TIMER_ENABLE_INTR; - - TIMER_RESET; - - sei(); // enable interrupts - - // Initialize state machine variables - irparams.rcvstate = STATE_IDLE; - irparams.rawlen = 0; - - // Set pin modes - pinMode(irparams.recvpin, INPUT); -} -#endif // USE_DEFAULT_ENABLE_IR_IN - -//+============================================================================= -// Enable/disable blinking of pin 13 on IR processing -// -void IRrecv::blink13 (int blinkflag) -{ -#ifdef BLINKLED - irparams.blinkflag = blinkflag; - if (blinkflag) pinMode(BLINKLED, OUTPUT) ; -#endif -} - -//+============================================================================= -// Return if receiving new IR signals -// -bool IRrecv::isIdle ( ) -{ - return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false; -} -//+============================================================================= -// Restart the ISR state machine -// -void IRrecv::resume ( ) -{ - irparams.rcvstate = STATE_IDLE; - irparams.rawlen = 0; -} - -//+============================================================================= -// hashdecode - decode an arbitrary IR code. -// Instead of decoding using a standard encoding scheme -// (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. -// -// The algorithm: look at the sequence of MARK signals, and see if each one -// is shorter (0), the same length (1), or longer (2) than the previous. -// Do the same with the SPACE signals. Hash the resulting sequence of 0's, -// 1's, and 2's to a 32-bit value. This will give a unique value for each -// different code (probably), for most code systems. -// -// http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html -// -// Compare two tick values, returning 0 if newval is shorter, -// 1 if newval is equal, and 2 if newval is longer -// Use a tolerance of 20% -// -int IRrecv::compare (unsigned int oldval, unsigned int newval) -{ - if (newval < oldval * .8) return 0 ; - else if (oldval < newval * .8) return 2 ; - else return 1 ; -} - -//+============================================================================= -// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param -// Converts the raw code values into a 32-bit hash code. -// Hopefully this code is unique for each button. -// This isn't a "real" decoding, just an arbitrary value. -// -#define FNV_PRIME_32 16777619 -#define FNV_BASIS_32 2166136261 - -long IRrecv::decodeHash (decode_results *results) -{ - long hash = FNV_BASIS_32; - - // Require at least 6 samples to prevent triggering on noise - if (results->rawlen < 6) return false ; - - for (int i = 1; (i + 2) < results->rawlen; i++) { - int value = compare(results->rawbuf[i], results->rawbuf[i+2]); - // Add value into the hash - hash = (hash * FNV_PRIME_32) ^ value; - } - - results->value = hash; - results->bits = 32; - results->decode_type = UNKNOWN; - - return true; -} diff --git a/IRremote/irSend.cpp b/IRremote/irSend.cpp deleted file mode 100644 index a01b5a0120e706cfc1d7fb464f1a977378cdc423..0000000000000000000000000000000000000000 --- a/IRremote/irSend.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -#ifdef SENDING_SUPPORTED -//+============================================================================= -void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz) -{ - // Set IR carrier frequency - enableIROut(hz); - - for (unsigned int i = 0; i < len; i++) { - if (i & 1) space(buf[i]) ; - else mark (buf[i]) ; - } - - space(0); // Always end with the LED off -} - -#ifdef USE_SOFT_CARRIER -void inline IRsend::sleepMicros(unsigned long us) -{ -#ifdef USE_SPIN_WAIT - sleepUntilMicros(micros() + us); -#else - if (us > 0U) // Is this necessary? (Official docu https://www.arduino.cc/en/Reference/DelayMicroseconds does not tell.) - delayMicroseconds((unsigned int) us); -#endif -} - -void inline IRsend::sleepUntilMicros(unsigned long targetTime) -{ -#ifdef USE_SPIN_WAIT - while (micros() < targetTime) - ; -#else - unsigned long now = micros(); - if (now < targetTime) - sleepMicros(targetTime - now); -#endif -} -#endif // USE_SOFT_CARRIER - -//+============================================================================= -// Sends an IR mark for the specified number of microseconds. -// The mark output is modulated at the PWM frequency. -// - -void IRsend::mark(unsigned int time) -{ -#ifdef USE_SOFT_CARRIER - unsigned long start = micros(); - unsigned long stop = start + time; - if (stop + periodTime < start) - // Counter wrap-around, happens very seldomly, but CAN happen. - // Just give up instead of possibly damaging the hardware. - return; - - unsigned long nextPeriodEnding = start; - unsigned long now = micros(); - while (now < stop) { - SENDPIN_ON(sendPin); - sleepMicros(periodOnTime); - SENDPIN_OFF(sendPin); - nextPeriodEnding += periodTime; - sleepUntilMicros(nextPeriodEnding); - now = micros(); - } -#else - TIMER_ENABLE_PWM; // Enable pin 3 PWM output - if (time > 0) custom_delay_usec(time); -#endif -} - -//+============================================================================= -// Leave pin off for time (given in microseconds) -// Sends an IR space for the specified number of microseconds. -// A space is no output, so the PWM output is disabled. -// -void IRsend::space (unsigned int time) -{ - TIMER_DISABLE_PWM; // Disable pin 3 PWM output - if (time > 0) IRsend::custom_delay_usec(time); -} - - - - - -//+============================================================================= -// Enables IR output. The khz value controls the modulation frequency in kilohertz. -// The IR output will be on pin 3 (OC2B). -// This routine is designed for 36-40KHz; if you use it for other values, it's up to you -// to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.) -// TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B -// controlling the duty cycle. -// There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A) -// To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin. -// A few hours staring at the ATmega documentation and this will all make sense. -// See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details. -// -void IRsend::enableIROut (int khz) -{ -#ifdef USE_SOFT_CARRIER - periodTime = (1000U + khz/2) / khz; // = 1000/khz + 1/2 = round(1000.0/khz) - periodOnTime = periodTime * DUTY_CYCLE / 100U - PULSE_CORRECTION; -#endif - - // Disable the Timer2 Interrupt (which is used for receiving IR) - TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt - - pinMode(sendPin, OUTPUT); - SENDPIN_OFF(sendPin); // When not sending, we want it low - - // COM2A = 00: disconnect OC2A - // COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted - // WGM2 = 101: phase-correct PWM with OCRA as top - // CS2 = 000: no prescaling - // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A. - TIMER_CONFIG_KHZ(khz); -} - -//+============================================================================= -// Custom delay function that circumvents Arduino's delayMicroseconds limit - -void IRsend::custom_delay_usec(unsigned long uSecs) { - if (uSecs > 4) { - unsigned long start = micros(); - unsigned long endMicros = start + uSecs - 4; - if (endMicros < start) { // Check if overflow - while ( micros() > start ) {} // wait until overflow - } - while ( micros() < endMicros ) {} // normal wait - } - //else { - // __asm__("nop\n\t"); // must have or compiler optimizes out - //} -} - -#endif // SENDING_SUPPORTED \ No newline at end of file diff --git a/IRremote/ir_Aiwa.cpp b/IRremote/ir_Aiwa.cpp deleted file mode 100644 index ee4d46e8640a42456298818441e650acde6d0871..0000000000000000000000000000000000000000 --- a/IRremote/ir_Aiwa.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// AAA IIIII W W AAA -// A A I W W A A -// AAAAA I W W W AAAAA -// A A I W W W A A -// A A IIIII WWW A A -//============================================================================== - -// Based off the RC-T501 RCU -// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 - -#define AIWA_RC_T501_HZ 38 -#define AIWA_RC_T501_BITS 15 -#define AIWA_RC_T501_PRE_BITS 26 -#define AIWA_RC_T501_POST_BITS 1 -#define AIWA_RC_T501_SUM_BITS (AIWA_RC_T501_PRE_BITS + AIWA_RC_T501_BITS + AIWA_RC_T501_POST_BITS) -#define AIWA_RC_T501_HDR_MARK 8800 -#define AIWA_RC_T501_HDR_SPACE 4500 -#define AIWA_RC_T501_BIT_MARK 500 -#define AIWA_RC_T501_ONE_SPACE 600 -#define AIWA_RC_T501_ZERO_SPACE 1700 - -//+============================================================================= -#if SEND_AIWA_RC_T501 -void IRsend::sendAiwaRCT501 (int code) -{ - unsigned long pre = 0x0227EEC0; // 26-bits - - // Set IR carrier frequency - enableIROut(AIWA_RC_T501_HZ); - - // Header - mark(AIWA_RC_T501_HDR_MARK); - space(AIWA_RC_T501_HDR_SPACE); - - // Send "pre" data - for (unsigned long mask = 1UL << (26 - 1); mask; mask >>= 1) { - mark(AIWA_RC_T501_BIT_MARK); - if (pre & mask) space(AIWA_RC_T501_ONE_SPACE) ; - else space(AIWA_RC_T501_ZERO_SPACE) ; - } - -//-v- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK! -// it only send 15bits and ignores the top bit -// then uses TOPBIT which is 0x80000000 to check the bit code -// I suspect TOPBIT should be changed to 0x00008000 - - // Skip first code bit - code <<= 1; - // Send code - for (int i = 0; i < 15; i++) { - mark(AIWA_RC_T501_BIT_MARK); - if (code & 0x80000000) space(AIWA_RC_T501_ONE_SPACE) ; - else space(AIWA_RC_T501_ZERO_SPACE) ; - code <<= 1; - } - -//-^- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK! - - // POST-DATA, 1 bit, 0x0 - mark(AIWA_RC_T501_BIT_MARK); - space(AIWA_RC_T501_ZERO_SPACE); - - mark(AIWA_RC_T501_BIT_MARK); - space(0); -} -#endif - -//+============================================================================= -#if DECODE_AIWA_RC_T501 -bool IRrecv::decodeAiwaRCT501 (decode_results *results) -{ - int data = 0; - int offset = 1; - - // Check SIZE - if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return false ; - - // Check HDR Mark/Space - if (!MATCH_MARK (results->rawbuf[offset++], AIWA_RC_T501_HDR_MARK )) return false ; - if (!MATCH_SPACE(results->rawbuf[offset++], AIWA_RC_T501_HDR_SPACE)) return false ; - - offset += 26; // skip pre-data - optional - while(offset < irparams.rawlen - 4) { - if (MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_BIT_MARK)) offset++ ; - else return false ; - - // ONE & ZERO - if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ONE_SPACE)) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ZERO_SPACE)) data = (data << 1) | 0 ; - else break ; // End of one & zero detected - offset++; - } - - results->bits = (offset - 1) / 2; - if (results->bits < 42) return false ; - - results->value = data; - results->decode_type = AIWA_RC_T501; - return true; -} -#endif diff --git a/IRremote/ir_Denon.cpp b/IRremote/ir_Denon.cpp deleted file mode 100644 index 4c9a502a51adb4fab896d84126f7483d93c8a1e0..0000000000000000000000000000000000000000 --- a/IRremote/ir_Denon.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -// Reverse Engineered by looking at RAW dumps generated by IRremote - -// I have since discovered that Denon publish all their IR codes: -// https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet -// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls - -// Having looked at the official Denon Pronto sheet and reverse engineered -// the timing values from it, it is obvious that Denon have a range of -// different timings and protocols ...the values here work for my AVR-3801 Amp! - -//============================================================================== -// DDDD EEEEE N N OOO N N -// D D E NN N O O NN N -// D D EEE N N N O O N N N -// D D E N NN O O N NN -// DDDD EEEEE N N OOO N N -//============================================================================== - -#define BITS 14 // The number of bits in the command - -#define HDR_MARK 300 // The length of the Header:Mark -#define HDR_SPACE 750 // The lenght of the Header:Space - -#define BIT_MARK 300 // The length of a Bit:Mark -#define ONE_SPACE 1800 // The length of a Bit:Space for 1's -#define ZERO_SPACE 750 // The length of a Bit:Space for 0's - -//+============================================================================= -// -#if SEND_DENON -void IRsend::sendDenon (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(38); - - // Header - mark (HDR_MARK); - space(HDR_SPACE); - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark (BIT_MARK); - space(ONE_SPACE); - } else { - mark (BIT_MARK); - space(ZERO_SPACE); - } - } - - // Footer - mark(BIT_MARK); - space(0); // Always end with the LED off -} -#endif - -//+============================================================================= -// -#if DECODE_DENON -bool IRrecv::decodeDenon (decode_results *results) -{ - unsigned long data = 0; // Somewhere to build our code - int offset = 1; // Skip the Gap reading - - // Check we have the right amount of data - if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ; - - // Check initial Mark+Space match - if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ; - if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ; - - // Read the bits in - for (int i = 0; i < BITS; i++) { - // Each bit looks like: MARK + SPACE_1 -> 1 - // or : MARK + SPACE_0 -> 0 - if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ; - - // IR data is big-endian, so we shuffle it in from the right: - if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // Success - results->bits = BITS; - results->value = data; - results->decode_type = DENON; - return true; -} -#endif diff --git a/IRremote/ir_Dish.cpp b/IRremote/ir_Dish.cpp deleted file mode 100644 index 0a17a6036fefe066f9c0b0f6aab007b08120e28f..0000000000000000000000000000000000000000 --- a/IRremote/ir_Dish.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// DDDD IIIII SSSS H H -// D D I S H H -// D D I SSS HHHHH -// D D I S H H -// DDDD IIIII SSSS H H -//============================================================================== - -// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) -// -// The sned function needs to be repeated 4 times -// -// Only send the last for characters of the hex. -// I.E. Use 0x1C10 instead of 0x0000000000001C10 as listed in the LIRC file. -// -// Here is the LIRC file I found that seems to match the remote codes from the -// oscilloscope: -// DISH NETWORK (echostar 301): -// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx - -#define DISH_BITS 16 -#define DISH_HDR_MARK 400 -#define DISH_HDR_SPACE 6100 -#define DISH_BIT_MARK 400 -#define DISH_ONE_SPACE 1700 -#define DISH_ZERO_SPACE 2800 -#define DISH_RPT_SPACE 6200 - -//+============================================================================= -#if SEND_DISH -void IRsend::sendDISH (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(56); - - mark(DISH_HDR_MARK); - space(DISH_HDR_SPACE); - - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark(DISH_BIT_MARK); - space(DISH_ONE_SPACE); - } else { - mark(DISH_BIT_MARK); - space(DISH_ZERO_SPACE); - } - } - mark(DISH_HDR_MARK); //added 26th March 2016, by AnalysIR ( https://www.AnalysIR.com ) -} -#endif - diff --git a/IRremote/ir_JVC.cpp b/IRremote/ir_JVC.cpp deleted file mode 100644 index 03d5e7c0184ed6ea9a0ece89097731f6e80e72c7..0000000000000000000000000000000000000000 --- a/IRremote/ir_JVC.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// JJJJJ V V CCCC -// J V V C -// J V V C -// J J V V C -// J V CCCC -//============================================================================== - -#define JVC_BITS 16 -#define JVC_HDR_MARK 8000 -#define JVC_HDR_SPACE 4000 -#define JVC_BIT_MARK 600 -#define JVC_ONE_SPACE 1600 -#define JVC_ZERO_SPACE 550 -#define JVC_RPT_LENGTH 60000 - -//+============================================================================= -// JVC does NOT repeat by sending a separate code (like NEC does). -// The JVC protocol repeats by skipping the header. -// To send a JVC repeat signal, send the original code value -// and set 'repeat' to true -// -#if SEND_JVC -void IRsend::sendJVC (unsigned long data, int nbits, bool repeat) -{ - // Set IR carrier frequency - enableIROut(38); - - // Only send the Header if this is NOT a repeat command - if (!repeat){ - mark(JVC_HDR_MARK); - space(JVC_HDR_SPACE); - } - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark(JVC_BIT_MARK); - space(JVC_ONE_SPACE); - } else { - mark(JVC_BIT_MARK); - space(JVC_ZERO_SPACE); - } - } - - // Footer - mark(JVC_BIT_MARK); - space(0); // Always end with the LED off -} -#endif - -//+============================================================================= -#if DECODE_JVC -bool IRrecv::decodeJVC (decode_results *results) -{ - long data = 0; - int offset = 1; // Skip first space - - // Check for repeat - if ( (irparams.rawlen - 1 == 33) - && MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK) - && MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK) - ) { - results->bits = 0; - results->value = REPEAT; - results->decode_type = JVC; - return true; - } - - // Initial mark - if (!MATCH_MARK(results->rawbuf[offset++], JVC_HDR_MARK)) return false ; - - if (irparams.rawlen < (2 * JVC_BITS) + 1 ) return false ; - - // Initial space - if (!MATCH_SPACE(results->rawbuf[offset++], JVC_HDR_SPACE)) return false ; - - for (int i = 0; i < JVC_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset++], JVC_BIT_MARK)) return false ; - - if (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE)) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // Stop bit - if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return false ; - - // Success - results->bits = JVC_BITS; - results->value = data; - results->decode_type = JVC; - - return true; -} -#endif - diff --git a/IRremote/ir_LG.cpp b/IRremote/ir_LG.cpp deleted file mode 100644 index 27bea287342ffb5597d93d02140e0af366076627..0000000000000000000000000000000000000000 --- a/IRremote/ir_LG.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// L GGGG -// L G -// L G GG -// L G G -// LLLLL GGG -//============================================================================== - -#define LG_BITS 28 - -#define LG_HDR_MARK 8000 -#define LG_HDR_SPACE 4000 -#define LG_BIT_MARK 600 -#define LG_ONE_SPACE 1600 -#define LG_ZERO_SPACE 550 -#define LG_RPT_LENGTH 60000 - -//+============================================================================= -#if DECODE_LG -bool IRrecv::decodeLG (decode_results *results) -{ - long data = 0; - int offset = 1; // Skip first space - - // Check we have the right amount of data - if (irparams.rawlen < (2 * LG_BITS) + 1 ) return false ; - - // Initial mark/space - if (!MATCH_MARK(results->rawbuf[offset++], LG_HDR_MARK)) return false ; - if (!MATCH_SPACE(results->rawbuf[offset++], LG_HDR_SPACE)) return false ; - - for (int i = 0; i < LG_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset++], LG_BIT_MARK)) return false ; - - if (MATCH_SPACE(results->rawbuf[offset], LG_ONE_SPACE)) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], LG_ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // Stop bit - if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ; - - // Success - results->bits = LG_BITS; - results->value = data; - results->decode_type = LG; - return true; -} -#endif - -//+============================================================================= -#if SEND_LG -void IRsend::sendLG (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(38); - - // Header - mark(LG_HDR_MARK); - space(LG_HDR_SPACE); - mark(LG_BIT_MARK); - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - space(LG_ONE_SPACE); - mark(LG_BIT_MARK); - } else { - space(LG_ZERO_SPACE); - mark(LG_BIT_MARK); - } - } - space(0); // Always end with the LED off -} -#endif - diff --git a/IRremote/ir_Lego_PF.cpp b/IRremote/ir_Lego_PF.cpp deleted file mode 100644 index 91902c503f961b5a6998b2655fcfc65ba9fcceca..0000000000000000000000000000000000000000 --- a/IRremote/ir_Lego_PF.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" -#include "ir_Lego_PF_BitStreamEncoder.h" - -//============================================================================== -// L EEEEEE EEEE OOOO -// L E E O O -// L EEEE E EEE O O -// L E E E O O LEGO Power Functions -// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel -//============================================================================== - -// Supported Devices -// LEGO® Power Functions IR Receiver 8884 - -//+============================================================================= -// -#if SEND_LEGO_PF - -#if DEBUG -namespace { -void logFunctionParameters(uint16_t data, bool repeat) { - DBG_PRINT("sendLegoPowerFunctions(data="); - DBG_PRINT(data); - DBG_PRINT(", repeat="); - DBG_PRINTLN(repeat?"true)" : "false)"); -} -} // anonymous namespace -#endif // DEBUG - -void IRsend::sendLegoPowerFunctions(uint16_t data, bool repeat) -{ -#if DEBUG - ::logFunctionParameters(data, repeat); -#endif // DEBUG - - enableIROut(38); - static LegoPfBitStreamEncoder bitStreamEncoder; - bitStreamEncoder.reset(data, repeat); - do { - mark(bitStreamEncoder.getMarkDuration()); - space(bitStreamEncoder.getPauseDuration()); - } while (bitStreamEncoder.next()); -} - -#endif // SEND_LEGO_PF diff --git a/IRremote/ir_Lego_PF_BitStreamEncoder.h b/IRremote/ir_Lego_PF_BitStreamEncoder.h deleted file mode 100644 index 3cd6fb5e1fafda8e99b7a263f395536f92516476..0000000000000000000000000000000000000000 --- a/IRremote/ir_Lego_PF_BitStreamEncoder.h +++ /dev/null @@ -1,115 +0,0 @@ - -//============================================================================== -// L EEEEEE EEEE OOOO -// L E E O O -// L EEEE E EEE O O -// L E E E O O LEGO Power Functions -// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016, 2017 Philipp Henkel -//============================================================================== - -//+============================================================================= -// - -class LegoPfBitStreamEncoder { - private: - uint16_t data; - bool repeatMessage; - uint8_t messageBitIdx; - uint8_t repeatCount; - uint16_t messageLength; - - public: - // HIGH data bit = IR mark + high pause - // LOW data bit = IR mark + low pause - static const uint16_t LOW_BIT_DURATION = 421; - static const uint16_t HIGH_BIT_DURATION = 711; - static const uint16_t START_BIT_DURATION = 1184; - static const uint16_t STOP_BIT_DURATION = 1184; - static const uint8_t IR_MARK_DURATION = 158; - static const uint16_t HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; - static const uint16_t LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; - static const uint16_t START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; - static const uint16_t STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; - static const uint8_t MESSAGE_BITS = 18; - static const uint16_t MAX_MESSAGE_LENGTH = 16000; - - void reset(uint16_t data, bool repeatMessage) { - this->data = data; - this->repeatMessage = repeatMessage; - messageBitIdx = 0; - repeatCount = 0; - messageLength = getMessageLength(); - } - - int getChannelId() const { return 1 + ((data >> 12) & 0x3); } - - uint16_t getMessageLength() const { - // Sum up all marks - uint16_t length = MESSAGE_BITS * IR_MARK_DURATION; - - // Sum up all pauses - length += START_PAUSE_DURATION; - for (unsigned long mask = 1UL << 15; mask; mask >>= 1) { - if (data & mask) { - length += HIGH_PAUSE_DURATION; - } else { - length += LOW_PAUSE_DURATION; - } - } - length += STOP_PAUSE_DURATION; - return length; - } - - boolean next() { - messageBitIdx++; - if (messageBitIdx >= MESSAGE_BITS) { - repeatCount++; - messageBitIdx = 0; - } - if (repeatCount >= 1 && !repeatMessage) { - return false; - } else if (repeatCount >= 5) { - return false; - } else { - return true; - } - } - - uint8_t getMarkDuration() const { return IR_MARK_DURATION; } - - uint32_t getPauseDuration() const { - if (messageBitIdx == 0) - return START_PAUSE_DURATION; - else if (messageBitIdx < MESSAGE_BITS - 1) { - return getDataBitPause(); - } else { - return getStopPause(); - } - } - - private: - uint16_t getDataBitPause() const { - const int pos = MESSAGE_BITS - 2 - messageBitIdx; - const bool isHigh = data & (1 << pos); - return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; - } - - uint32_t getStopPause() const { - if (repeatMessage) { - return getRepeatStopPause(); - } else { - return STOP_PAUSE_DURATION; - } - } - - uint32_t getRepeatStopPause() const { - if (repeatCount == 0 || repeatCount == 1) { - return STOP_PAUSE_DURATION + (uint32_t)5 * MAX_MESSAGE_LENGTH - messageLength; - } else if (repeatCount == 2 || repeatCount == 3) { - return STOP_PAUSE_DURATION - + (uint32_t)(6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; - } else { - return STOP_PAUSE_DURATION; - } - } -}; diff --git a/IRremote/ir_Mitsubishi.cpp b/IRremote/ir_Mitsubishi.cpp deleted file mode 100644 index 5068a2620bfc0c58f4428a18673ab7c395a3cc0b..0000000000000000000000000000000000000000 --- a/IRremote/ir_Mitsubishi.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII -// M M M I T S U U B B I S H H I -// M M M I T SSS U U BBBB I SSS HHHHH I -// M M I T S U U B B I S H H I -// M M IIIII T SSSS UUU BBBBB IIIII SSSS H H IIIII -//============================================================================== - -// Looks like Sony except for timings, 48 chars of data and time/space different - -#define MITSUBISHI_BITS 16 - -// Mitsubishi RM 75501 -// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 -// #define MITSUBISHI_HDR_MARK 250 // seen range 3500 -#define MITSUBISHI_HDR_SPACE 350 // 7*50+100 -#define MITSUBISHI_ONE_MARK 1950 // 41*50-100 -#define MITSUBISHI_ZERO_MARK 750 // 17*50-100 -// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround -// #define MITSUBISHI_RPT_LENGTH 45000 - -//+============================================================================= -#if DECODE_MITSUBISHI -bool IRrecv::decodeMitsubishi (decode_results *results) -{ - // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2); - long data = 0; - if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) return false ; - int offset = 0; // Skip first space - // Initial space - -#if 0 - // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay - Serial.print("IR Gap: "); - Serial.println( results->rawbuf[offset]); - Serial.println( "test against:"); - Serial.println(results->rawbuf[offset]); -#endif - -#if 0 - // Not seeing double keys from Mitsubishi - if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) { - // Serial.print("IR Gap found: "); - results->bits = 0; - results->value = REPEAT; - results->decode_type = MITSUBISHI; - return true; - } -#endif - - offset++; - - // Typical - // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 - - // Initial Space - if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) return false ; - offset++; - - while (offset + 1 < irparams.rawlen) { - if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK)) data = (data << 1) | 1 ; - else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK)) data <<= 1 ; - else return false ; - offset++; - - if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) break ; - offset++; - } - - // Success - results->bits = (offset - 1) / 2; - if (results->bits < MITSUBISHI_BITS) { - results->bits = 0; - return false; - } - - results->value = data; - results->decode_type = MITSUBISHI; - return true; -} -#endif - diff --git a/IRremote/ir_NEC.cpp b/IRremote/ir_NEC.cpp deleted file mode 100644 index 4443a4de67dfab6a0d4286feff57148260cf8cbe..0000000000000000000000000000000000000000 --- a/IRremote/ir_NEC.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// N N EEEEE CCCC -// NN N E C -// N N N EEE C -// N NN E C -// N N EEEEE CCCC -//============================================================================== - -#define NEC_BITS 32 -#define NEC_HDR_MARK 9000 -#define NEC_HDR_SPACE 4500 -#define NEC_BIT_MARK 560 -#define NEC_ONE_SPACE 1690 -#define NEC_ZERO_SPACE 560 -#define NEC_RPT_SPACE 2250 - -//+============================================================================= -#if SEND_NEC -void IRsend::sendNEC (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(38); - - // Header - mark(NEC_HDR_MARK); - space(NEC_HDR_SPACE); - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark(NEC_BIT_MARK); - space(NEC_ONE_SPACE); - } else { - mark(NEC_BIT_MARK); - space(NEC_ZERO_SPACE); - } - } - - // Footer - mark(NEC_BIT_MARK); - space(0); // Always end with the LED off -} -#endif - -//+============================================================================= -// NECs have a repeat only 4 items long -// -#if DECODE_NEC -bool IRrecv::decodeNEC (decode_results *results) -{ - long data = 0; // We decode in to here; Start with nothing - int offset = 1; // Index in to results; Skip first entry!? - - // Check header "mark" - if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) return false ; - offset++; - - // Check for repeat - if ( (irparams.rawlen == 4) - && MATCH_SPACE(results->rawbuf[offset ], NEC_RPT_SPACE) - && MATCH_MARK (results->rawbuf[offset+1], NEC_BIT_MARK ) - ) { - results->bits = 0; - results->value = REPEAT; - results->decode_type = NEC; - return true; - } - - // Check we have enough data - if (irparams.rawlen < (2 * NEC_BITS) + 4) return false ; - - // Check header "space" - if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return false ; - offset++; - - // Build the data - for (int i = 0; i < NEC_BITS; i++) { - // Check data "mark" - if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return false ; - offset++; - // Suppend this bit - if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE )) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // Success - results->bits = NEC_BITS; - results->value = data; - results->decode_type = NEC; - - return true; -} -#endif diff --git a/IRremote/ir_Panasonic.cpp b/IRremote/ir_Panasonic.cpp deleted file mode 100644 index bef5c5cf92ad79d2dd811fa97910f67c6983f4bc..0000000000000000000000000000000000000000 --- a/IRremote/ir_Panasonic.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// PPPP AAA N N AAA SSSS OOO N N IIIII CCCC -// P P A A NN N A A S O O NN N I C -// PPPP AAAAA N N N AAAAA SSS O O N N N I C -// P A A N NN A A S O O N NN I C -// P A A N N A A SSSS OOO N N IIIII CCCC -//============================================================================== - -#define PANASONIC_BITS 48 -#define PANASONIC_HDR_MARK 3502 -#define PANASONIC_HDR_SPACE 1750 -#define PANASONIC_BIT_MARK 502 -#define PANASONIC_ONE_SPACE 1244 -#define PANASONIC_ZERO_SPACE 400 - -//+============================================================================= -#if SEND_PANASONIC -void IRsend::sendPanasonic (unsigned int address, unsigned long data) -{ - // Set IR carrier frequency - enableIROut(35); - - // Header - mark(PANASONIC_HDR_MARK); - space(PANASONIC_HDR_SPACE); - - // Address - for (unsigned long mask = 1UL << (16 - 1); mask; mask >>= 1) { - mark(PANASONIC_BIT_MARK); - if (address & mask) space(PANASONIC_ONE_SPACE) ; - else space(PANASONIC_ZERO_SPACE) ; - } - - // Data - for (unsigned long mask = 1UL << (32 - 1); mask; mask >>= 1) { - mark(PANASONIC_BIT_MARK); - if (data & mask) space(PANASONIC_ONE_SPACE) ; - else space(PANASONIC_ZERO_SPACE) ; - } - - // Footer - mark(PANASONIC_BIT_MARK); - space(0); // Always end with the LED off -} -#endif - -//+============================================================================= -#if DECODE_PANASONIC -bool IRrecv::decodePanasonic (decode_results *results) -{ - unsigned long long data = 0; - int offset = 1; - - if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_MARK )) return false ; - if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_SPACE)) return false ; - - // decode address - for (int i = 0; i < PANASONIC_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) return false ; - - if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE )) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - results->value = (unsigned long)data; - results->address = (unsigned int)(data >> 32); - results->decode_type = PANASONIC; - results->bits = PANASONIC_BITS; - - return true; -} -#endif - diff --git a/IRremote/ir_RC5_RC6.cpp b/IRremote/ir_RC5_RC6.cpp deleted file mode 100644 index f7134a9fe113d0a15a29c9094357fab518c49924..0000000000000000000000000000000000000000 --- a/IRremote/ir_RC5_RC6.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//+============================================================================= -// Gets one undecoded level at a time from the raw buffer. -// The RC5/6 decoding is easier if the data is broken into time intervals. -// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, -// successive calls to getRClevel will return MARK, MARK, SPACE. -// offset and used are updated to keep track of the current position. -// t1 is the time interval for a single bit in microseconds. -// Returns -1 for error (measured time interval is not a multiple of t1). -// -#if (DECODE_RC5 || DECODE_RC6) -int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1) -{ - int width; - int val; - int correction; - int avail; - - if (*offset >= results->rawlen) return SPACE ; // After end of recorded buffer, assume SPACE. - width = results->rawbuf[*offset]; - val = ((*offset) % 2) ? MARK : SPACE; - correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS; - - if (MATCH(width, ( t1) + correction)) avail = 1 ; - else if (MATCH(width, (2*t1) + correction)) avail = 2 ; - else if (MATCH(width, (3*t1) + correction)) avail = 3 ; - else return -1 ; - - (*used)++; - if (*used >= avail) { - *used = 0; - (*offset)++; - } - - DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" ); - - return val; -} -#endif - -//============================================================================== -// RRRR CCCC 55555 -// R R C 5 -// RRRR C 5555 -// R R C 5 -// R R CCCC 5555 -// -// NB: First bit must be a one (start bit) -// -#define MIN_RC5_SAMPLES 11 -#define RC5_T1 889 -#define RC5_RPT_LENGTH 46000 - -//+============================================================================= -#if SEND_RC5 -void IRsend::sendRC5 (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(36); - - // Start - mark(RC5_T1); - space(RC5_T1); - mark(RC5_T1); - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - space(RC5_T1); // 1 is space, then mark - mark(RC5_T1); - } else { - mark(RC5_T1); - space(RC5_T1); - } - } - - space(0); // Always end with the LED off -} -#endif - -//+============================================================================= -#if DECODE_RC5 -bool IRrecv::decodeRC5 (decode_results *results) -{ - int nbits; - long data = 0; - int used = 0; - int offset = 1; // Skip gap space - - if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return false ; - - // Get start bits - if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ; - if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return false ; - if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ; - - for (nbits = 0; offset < irparams.rawlen; nbits++) { - int levelA = getRClevel(results, &offset, &used, RC5_T1); - int levelB = getRClevel(results, &offset, &used, RC5_T1); - - if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 1 ; - else if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 0 ; - else return false ; - } - - // Success - results->bits = nbits; - results->value = data; - results->decode_type = RC5; - return true; -} -#endif - -//+============================================================================= -// RRRR CCCC 6666 -// R R C 6 -// RRRR C 6666 -// R R C 6 6 -// R R CCCC 666 -// -// NB : Caller needs to take care of flipping the toggle bit -// -#define MIN_RC6_SAMPLES 1 -#define RC6_HDR_MARK 2666 -#define RC6_HDR_SPACE 889 -#define RC6_T1 444 -#define RC6_RPT_LENGTH 46000 - -#if SEND_RC6 -void IRsend::sendRC6 (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(36); - - // Header - mark(RC6_HDR_MARK); - space(RC6_HDR_SPACE); - - // Start bit - mark(RC6_T1); - space(RC6_T1); - - // Data - for (unsigned long i = 1, mask = 1UL << (nbits - 1); mask; i++, mask >>= 1) { - // The fourth bit we send is a "double width trailer bit" - int t = (i == 4) ? (RC6_T1 * 2) : (RC6_T1) ; - if (data & mask) { - mark(t); - space(t); - } else { - space(t); - mark(t); - } - } - - space(0); // Always end with the LED off -} -#endif - -//+============================================================================= -#if DECODE_RC6 -bool IRrecv::decodeRC6 (decode_results *results) -{ - int nbits; - long data = 0; - int used = 0; - int offset = 1; // Skip first space - - if (results->rawlen < MIN_RC6_SAMPLES) return false ; - - // Initial mark - if (!MATCH_MARK(results->rawbuf[offset++], RC6_HDR_MARK)) return false ; - if (!MATCH_SPACE(results->rawbuf[offset++], RC6_HDR_SPACE)) return false ; - - // Get start bit (1) - if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return false ; - if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return false ; - - for (nbits = 0; offset < results->rawlen; nbits++) { - int levelA, levelB; // Next two levels - - levelA = getRClevel(results, &offset, &used, RC6_T1); - if (nbits == 3) { - // T bit is double wide; make sure second half matches - if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return false; - } - - levelB = getRClevel(results, &offset, &used, RC6_T1); - if (nbits == 3) { - // T bit is double wide; make sure second half matches - if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return false; - } - - if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 1 ; // inverted compared to RC5 - else if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 0 ; // ... - else return false ; // Error - } - - // Success - results->bits = nbits; - results->value = data; - results->decode_type = RC6; - return true; -} -#endif diff --git a/IRremote/ir_Samsung.cpp b/IRremote/ir_Samsung.cpp deleted file mode 100644 index f36185fbd00364157a8d08f86414fe7d4ef137a7..0000000000000000000000000000000000000000 --- a/IRremote/ir_Samsung.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// SSSS AAA MMM SSSS U U N N GGGG -// S A A M M M S U U NN N G -// SSS AAAAA M M M SSS U U N N N G GG -// S A A M M S U U N NN G G -// SSSS A A M M SSSS UUU N N GGG -//============================================================================== - -#define SAMSUNG_BITS 32 -#define SAMSUNG_HDR_MARK 5000 -#define SAMSUNG_HDR_SPACE 5000 -#define SAMSUNG_BIT_MARK 560 -#define SAMSUNG_ONE_SPACE 1600 -#define SAMSUNG_ZERO_SPACE 560 -#define SAMSUNG_RPT_SPACE 2250 - -//+============================================================================= -#if SEND_SAMSUNG -void IRsend::sendSAMSUNG (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(38); - - // Header - mark(SAMSUNG_HDR_MARK); - space(SAMSUNG_HDR_SPACE); - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark(SAMSUNG_BIT_MARK); - space(SAMSUNG_ONE_SPACE); - } else { - mark(SAMSUNG_BIT_MARK); - space(SAMSUNG_ZERO_SPACE); - } - } - - // Footer - mark(SAMSUNG_BIT_MARK); - space(0); // Always end with the LED off -} -#endif - -//+============================================================================= -// SAMSUNGs have a repeat only 4 items long -// -#if DECODE_SAMSUNG -bool IRrecv::decodeSAMSUNG (decode_results *results) -{ - long data = 0; - int offset = 1; // Skip first space - - // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return false ; - offset++; - - // Check for repeat - if ( (irparams.rawlen == 4) - && MATCH_SPACE(results->rawbuf[offset], SAMSUNG_RPT_SPACE) - && MATCH_MARK(results->rawbuf[offset+1], SAMSUNG_BIT_MARK) - ) { - results->bits = 0; - results->value = REPEAT; - results->decode_type = SAMSUNG; - return true; - } - if (irparams.rawlen < (2 * SAMSUNG_BITS) + 4) return false ; - - // Initial space - if (!MATCH_SPACE(results->rawbuf[offset++], SAMSUNG_HDR_SPACE)) return false ; - - for (int i = 0; i < SAMSUNG_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG_BIT_MARK)) return false ; - - if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ONE_SPACE)) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // Success - results->bits = SAMSUNG_BITS; - results->value = data; - results->decode_type = SAMSUNG; - return true; -} -#endif - diff --git a/IRremote/ir_Sanyo.cpp b/IRremote/ir_Sanyo.cpp deleted file mode 100644 index 4a1e9fab8c214f7139017ca80e3d9691a44be64a..0000000000000000000000000000000000000000 --- a/IRremote/ir_Sanyo.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// SSSS AAA N N Y Y OOO -// S A A NN N Y Y O O -// SSS AAAAA N N N Y O O -// S A A N NN Y O O -// SSSS A A N N Y OOO -//============================================================================== - -// I think this is a Sanyo decoder: Serial = SA 8650B -// Looks like Sony except for timings, 48 chars of data and time/space different - -#define SANYO_BITS 12 -#define SANYO_HDR_MARK 3500 // seen range 3500 -#define SANYO_HDR_SPACE 950 // seen 950 -#define SANYO_ONE_MARK 2400 // seen 2400 -#define SANYO_ZERO_MARK 700 // seen 700 -#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround -#define SANYO_RPT_LENGTH 45000 - -//+============================================================================= -#if DECODE_SANYO -bool IRrecv::decodeSanyo (decode_results *results) -{ - long data = 0; - int offset = 0; // Skip first space <-- CHECK THIS! - - if (irparams.rawlen < (2 * SANYO_BITS) + 2) return false ; - -#if 0 - // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay - Serial.print("IR Gap: "); - Serial.println( results->rawbuf[offset]); - Serial.println( "test against:"); - Serial.println(results->rawbuf[offset]); -#endif - - // Initial space - if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) { - //Serial.print("IR Gap found: "); - results->bits = 0; - results->value = REPEAT; - results->decode_type = SANYO; - return true; - } - offset++; - - // Initial mark - if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ; - - // Skip Second Mark - if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ; - - while (offset + 1 < irparams.rawlen) { - if (!MATCH_SPACE(results->rawbuf[offset++], SANYO_HDR_SPACE)) break ; - - if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) data = (data << 1) | 1 ; - else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // Success - results->bits = (offset - 1) / 2; - if (results->bits < 12) { - results->bits = 0; - return false; - } - - results->value = data; - results->decode_type = SANYO; - return true; -} -#endif diff --git a/IRremote/ir_Sharp.cpp b/IRremote/ir_Sharp.cpp deleted file mode 100644 index f1845e03cde2a2685482e3643fd0c1e9dce0b2fa..0000000000000000000000000000000000000000 --- a/IRremote/ir_Sharp.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// SSSS H H AAA RRRR PPPP -// S H H A A R R P P -// SSS HHHHH AAAAA RRRR PPPP -// S H H A A R R P -// SSSS H H A A R R P -//============================================================================== - -// Sharp and DISH support by Todd Treece: http://unionbridge.org/design/ircommand -// -// The send function has the necessary repeat built in because of the need to -// invert the signal. -// -// Sharp protocol documentation: -// http://www.sbprojects.com/knowledge/ir/sharp.htm -// -// Here is the LIRC file I found that seems to match the remote codes from the -// oscilloscope: -// Sharp LCD TV: -// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA - -#define SHARP_BITS 15 -#define SHARP_BIT_MARK 245 -#define SHARP_ONE_SPACE 1805 -#define SHARP_ZERO_SPACE 795 -#define SHARP_GAP 600000 -#define SHARP_RPT_SPACE 3000 - -#define SHARP_TOGGLE_MASK 0x3FF - -//+============================================================================= -#if SEND_SHARP -void IRsend::sendSharpRaw (unsigned long data, int nbits) -{ - enableIROut(38); - - // Sending codes in bursts of 3 (normal, inverted, normal) makes transmission - // much more reliable. That's the exact behaviour of CD-S6470 remote control. - for (int n = 0; n < 3; n++) { - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark(SHARP_BIT_MARK); - space(SHARP_ONE_SPACE); - } else { - mark(SHARP_BIT_MARK); - space(SHARP_ZERO_SPACE); - } - } - - mark(SHARP_BIT_MARK); - space(SHARP_ZERO_SPACE); - delay(40); - - data = data ^ SHARP_TOGGLE_MASK; - } -} -#endif - -//+============================================================================= -// Sharp send compatible with data obtained through decodeSharp() -// ^^^^^^^^^^^^^ FUNCTION MISSING! -// -#if SEND_SHARP -void IRsend::sendSharp (unsigned int address, unsigned int command) -{ - sendSharpRaw((address << 10) | (command << 2) | 2, SHARP_BITS); -} -#endif diff --git a/IRremote/ir_Sony.cpp b/IRremote/ir_Sony.cpp deleted file mode 100644 index 95b710e49ebf780e6bfd0244c53ae2e7b26068d1..0000000000000000000000000000000000000000 --- a/IRremote/ir_Sony.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// SSSS OOO N N Y Y -// S O O NN N Y Y -// SSS O O N N N Y -// S O O N NN Y -// SSSS OOO N N Y -//============================================================================== - -#define SONY_BITS 12 -#define SONY_HDR_MARK 2400 -#define SONY_HDR_SPACE 600 -#define SONY_ONE_MARK 1200 -#define SONY_ZERO_MARK 600 -#define SONY_RPT_LENGTH 45000 -#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround - -//+============================================================================= -#if SEND_SONY -void IRsend::sendSony (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(40); - - // Header - mark(SONY_HDR_MARK); - space(SONY_HDR_SPACE); - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark(SONY_ONE_MARK); - space(SONY_HDR_SPACE); - } else { - mark(SONY_ZERO_MARK); - space(SONY_HDR_SPACE); - } - } - - // We will have ended with LED off -} -#endif - -//+============================================================================= -#if DECODE_SONY -bool IRrecv::decodeSony (decode_results *results) -{ - long data = 0; - int offset = 0; // Dont skip first space, check its size - - if (irparams.rawlen < (2 * SONY_BITS) + 2) return false ; - - // Some Sony's deliver repeats fast after first - // unfortunately can't spot difference from of repeat from two fast clicks - if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) { - // Serial.print("IR Gap found: "); - results->bits = 0; - results->value = REPEAT; - -# ifdef DECODE_SANYO - results->decode_type = SANYO; -# else - results->decode_type = UNKNOWN; -# endif - - return true; - } - offset++; - - // Initial mark - if (!MATCH_MARK(results->rawbuf[offset++], SONY_HDR_MARK)) return false ; - - while (offset + 1 < irparams.rawlen) { - if (!MATCH_SPACE(results->rawbuf[offset++], SONY_HDR_SPACE)) break ; - - if (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK)) data = (data << 1) | 1 ; - else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // Success - results->bits = (offset - 1) / 2; - if (results->bits < 12) { - results->bits = 0; - return false; - } - results->value = data; - results->decode_type = SONY; - return true; -} -#endif - diff --git a/IRremote/ir_Template.cpp b/IRremote/ir_Template.cpp deleted file mode 100644 index 09630c007f6d890fd619e2606b666511f5d2d555..0000000000000000000000000000000000000000 --- a/IRremote/ir_Template.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* -Assuming the protocol we are adding is for the (imaginary) manufacturer: Shuzu - -Our fantasy protocol is a standard protocol, so we can use this standard -template without too much work. Some protocols are quite unique and will require -considerably more work in this file! It is way beyond the scope of this text to -explain how to reverse engineer "unusual" IR protocols. But, unless you own an -oscilloscope, the starting point is probably to use the rawDump.ino sketch and -try to spot the pattern! - -Before you start, make sure the IR library is working OK: - # Open up the Arduino IDE - # Load up the rawDump.ino example sketch - # Run it - -Now we can start to add our new protocol... - -1. Copy this file to : ir_Shuzu.cpp - -2. Replace all occurrences of "Shuzu" with the name of your protocol. - -3. Tweak the #defines to suit your protocol. - -4. If you're lucky, tweaking the #defines will make the default send() function - work. - -5. Again, if you're lucky, tweaking the #defines will have made the default - decode() function work. - -You have written the code to support your new protocol! - -Now you must do a few things to add it to the IRremote system: - -1. Open IRremote.h and make the following changes: - REMEMEBER to change occurences of "SHUZU" with the name of your protocol - - A. At the top, in the section "Supported Protocols", add: - #define DECODE_SHUZU 1 - #define SEND_SHUZU 1 - - B. In the section "enumerated list of all supported formats", add: - SHUZU, - to the end of the list (notice there is a comma after the protocol name) - - C. Further down in "Main class for receiving IR", add: - //...................................................................... - #if DECODE_SHUZU - bool decodeShuzu (decode_results *results) ; - #endif - - D. Further down in "Main class for sending IR", add: - //...................................................................... - #if SEND_SHUZU - void sendShuzu (unsigned long data, int nbits) ; - #endif - - E. Save your changes and close the file - -2. Now open irRecv.cpp and make the following change: - - A. In the function IRrecv::decode(), add: - #ifdef DECODE_NEC - DBG_PRINTLN("Attempting Shuzu decode"); - if (decodeShuzu(results)) return true ; - #endif - - B. Save your changes and close the file - -You will probably want to add your new protocol to the example sketch - -3. Open MyDocuments\Arduino\libraries\IRremote\examples\IRrecvDumpV2.ino - - A. In the encoding() function, add: - case SHUZU: Serial.print("SHUZU"); break ; - -Now open the Arduino IDE, load up the rawDump.ino sketch, and run it. -Hopefully it will compile and upload. -If it doesn't, you've done something wrong. Check your work. -If you can't get it to work - seek help from somewhere. - -If you get this far, I will assume you have successfully added your new protocol -There is one last thing to do. - -1. Delete this giant instructional comment. - -2. Send a copy of your work to us so we can include it in the library and - others may benefit from your hard work and maybe even write a song about how - great you are for helping them! :) - -Regards, - BlueChip -*/ - -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// -// -// S H U Z U -// -// -//============================================================================== - -#define BITS 32 // The number of bits in the command - -#define HDR_MARK 1000 // The length of the Header:Mark -#define HDR_SPACE 2000 // The lenght of the Header:Space - -#define BIT_MARK 3000 // The length of a Bit:Mark -#define ONE_SPACE 4000 // The length of a Bit:Space for 1's -#define ZERO_SPACE 5000 // The length of a Bit:Space for 0's - -#define OTHER 1234 // Other things you may need to define - -//+============================================================================= -// -#if SEND_SHUZU -void IRsend::sendShuzu (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(38); - - // Header - mark (HDR_MARK); - space(HDR_SPACE); - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark (BIT_MARK); - space(ONE_SPACE); - } else { - mark (BIT_MARK); - space(ZERO_SPACE); - } - } - - // Footer - mark(BIT_MARK); - space(0); // Always end with the LED off -} -#endif - -//+============================================================================= -// -#if DECODE_SHUZU -bool IRrecv::decodeShuzu (decode_results *results) -{ - unsigned long data = 0; // Somewhere to build our code - int offset = 1; // Skip the Gap reading - - // Check we have the right amount of data - if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ; - - // Check initial Mark+Space match - if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ; - if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ; - - // Read the bits in - for (int i = 0; i < SHUZU_BITS; i++) { - // Each bit looks like: MARK + SPACE_1 -> 1 - // or : MARK + SPACE_0 -> 0 - if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ; - - // IR data is big-endian, so we shuffle it in from the right: - if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // Success - results->bits = BITS; - results->value = data; - results->decode_type = SHUZU; - return true; -} -#endif diff --git a/IRremote/ir_Whynter.cpp b/IRremote/ir_Whynter.cpp deleted file mode 100644 index 8b7bf0e63b00a3b7458891b7e27bc00174f9ea19..0000000000000000000000000000000000000000 --- a/IRremote/ir_Whynter.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//============================================================================== -// W W H H Y Y N N TTTTT EEEEE RRRRR -// W W H H Y Y NN N T E R R -// W W W HHHHH Y N N N T EEE RRRR -// W W W H H Y N NN T E R R -// WWW H H Y N N T EEEEE R R -//============================================================================== - -#define WHYNTER_BITS 32 -#define WHYNTER_HDR_MARK 2850 -#define WHYNTER_HDR_SPACE 2850 -#define WHYNTER_BIT_MARK 750 -#define WHYNTER_ONE_MARK 750 -#define WHYNTER_ONE_SPACE 2150 -#define WHYNTER_ZERO_MARK 750 -#define WHYNTER_ZERO_SPACE 750 - -//+============================================================================= -#if SEND_WHYNTER -void IRsend::sendWhynter (unsigned long data, int nbits) -{ - // Set IR carrier frequency - enableIROut(38); - - // Start - mark(WHYNTER_ZERO_MARK); - space(WHYNTER_ZERO_SPACE); - - // Header - mark(WHYNTER_HDR_MARK); - space(WHYNTER_HDR_SPACE); - - // Data - for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - mark(WHYNTER_ONE_MARK); - space(WHYNTER_ONE_SPACE); - } else { - mark(WHYNTER_ZERO_MARK); - space(WHYNTER_ZERO_SPACE); - } - } - - // Footer - mark(WHYNTER_ZERO_MARK); - space(WHYNTER_ZERO_SPACE); // Always end with the LED off -} -#endif - -//+============================================================================= -#if DECODE_WHYNTER -bool IRrecv::decodeWhynter (decode_results *results) -{ - long data = 0; - int offset = 1; // skip initial space - - // Check we have the right amount of data - if (irparams.rawlen < (2 * WHYNTER_BITS) + 6) return false ; - - // Sequence begins with a bit mark and a zero space - if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_BIT_MARK )) return false ; - if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_ZERO_SPACE)) return false ; - - // header mark and space - if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_HDR_MARK )) return false ; - if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_HDR_SPACE)) return false ; - - // data bits - for (int i = 0; i < WHYNTER_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset++], WHYNTER_BIT_MARK)) return false ; - - if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ONE_SPACE )) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; - offset++; - } - - // trailing mark - if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ; - - // Success - results->bits = WHYNTER_BITS; - results->value = data; - results->decode_type = WHYNTER; - return true; -} -#endif - diff --git a/IRremote/keywords.txt b/IRremote/keywords.txt deleted file mode 100644 index 935f913e14e2ce13ff99bb78c6282648d7e02849..0000000000000000000000000000000000000000 --- a/IRremote/keywords.txt +++ /dev/null @@ -1,104 +0,0 @@ -####################################### -# Syntax Coloring Map For IRremote -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -decode_results KEYWORD1 -IRrecv KEYWORD1 -IRsend KEYWORD1 -IrReceiver KEYWORD1 -IrSender KEYWORD1 -decodedIRData KEYWORD1 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -setFeedbackLED KEYWORD2 -enableLEDFeedback KEYWORD2 -enableLEDFeedbackForSend KEYWORD2 -disableLEDFeedback KEYWORD2 -disableLEDFeedbackForSend KEYWORD2 -printIRResultShort KEYWORD2 -begin KEYWORD2 -start KEYWORD2 -available KEYWORD2 -read KEYWORD2 -stop KEYWORD2 -end KEYWORD2 -enableLEDFeedback KEYWORD2 -decode KEYWORD2 -resume KEYWORD2 -enableIRIn KEYWORD2 -disableIRIn KEYWORD2 -sendNEC KEYWORD2 -setSendPin KEYWORD2 -write KEYWORD2 -enableIROut KEYWORD2 -IRLedOff KEYWORD2 -sendRaw KEYWORD2 -sendJVC KEYWORD2 -sendLG KEYWORD2 -sendLGRepeat KEYWORD2 -sendLGRaw KEYWORD2 -sendNEC KEYWORD2 -sendNECRepeat KEYWORD2 -sendNECRaw KEYWORD2 -sendOnkyo KEYWORD2 -sendApple KEYWORD2 -sendPanasonic KEYWORD2 -sendKaseikyo KEYWORD2 -sendKaseikyo_Denon KEYWORD2 -sendKaseikyo_Sharp KEYWORD2 -sendKaseikyo_JVC KEYWORD2 -sendKaseikyo_Mitsubishi KEYWORD2 -sendRC5 KEYWORD2 -sendRC6 KEYWORD2 -sendSamsungRepeat KEYWORD2 -sendSamsung KEYWORD2 -sendSharp KEYWORD2 -sendSony KEYWORD2 -sendSharpRaw KEYWORD2 -sendLegoPowerFunctions KEYWORD2 -sendMagiQuest KEYWORD2 -sendPronto KEYWORD2 -sendMagiQuest KEYWORD2 -sendFAST KEYWORD2 -####################################### -# Constants (LITERAL1) -####################################### - -PULSE_DISTANCE LITERAL1 -PULSE_WIDTH LITERAL1 -DENON LITERAL1 -DISH LITERAL1 -JVC LITERAL1 -LG LITERAL1 -LG2 LITERAL1 -NEC LITERAL1 -PANASONIC LITERAL1 -KASEIKYO LITERAL1 -KASEIKYO_JVC LITERAL1 -KASEIKYO_DENON LITERAL1 -KASEIKYO_SHARP LITERAL1 -KASEIKYO_MITSUBISHI LITERAL1 -RC5 LITERAL1 -RC6 LITERAL1 -SAMSUNG LITERAL1 -SHARP LITERAL1 -SONY LITERAL1 -ONKYO LITERAL1 -APPLE LITERAL1 -BANG_OLUFSEN LITERAL1 -BOSEWAVE LITERAL1 -LEGO_PF LITERAL1 -MAGIQUEST LITERAL1 -WHYNTER LITERAL1 -FAST LITERAL1 -UNKNOWN LITERAL1 -IR_RECEIVE_PIN LITERAL1 -IR_SEND_PIN LITERAL1 -FEEDBACK_LED_IS_ACTIVE_LOW LITERAL1 diff --git a/IRremote/library.json b/IRremote/library.json deleted file mode 100644 index e264f4c888f163d1e7a06e1424388b7a4282ca58..0000000000000000000000000000000000000000 --- a/IRremote/library.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "IRremote", - "keywords": "communication, infrared, ir, remote", - "description": "Send and receive infrared signals with multiple protocols", - "repository": - { - "type": "git", - "url": "https://github.com/z3t0/Arduino-IRremote.git" - }, - "version": "4.2.0", - "frameworks": "arduino", - "platforms": ["atmelavr", "atmelmegaavr", "atmelsam", "espressif8266", "espressif32", "ststm32"], - "authors" : - [ - { - "name":"Armin Joachimsmeyer", - "email":"armin.arduino@gmail.com", - "maintainer": true - }, - { - "name":"Rafi Khan", - "email":"rafi@rafikhan.io" - }, - { - "name":"Ken Shirriff", - "email":"ken.shirriff@gmail.com" - } - ], - "headers": "IRRemote.hpp" -} diff --git a/IRremote/library.properties b/IRremote/library.properties deleted file mode 100644 index 75ad868d021490d8256e3f3f0dc7d5c38b92eb11..0000000000000000000000000000000000000000 --- a/IRremote/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=IRremote -version=4.2.0 -author=shirriff, z3t0, ArminJo -maintainer=Armin Joachimsmeyer <armin.arduino@gmail.com> -sentence=Send and receive infrared signals with multiple protocols -paragraph=Currently included protocols: Denon / Sharp, JVC, LG / LG2, NEC / Onkyo / Apple, Panasonic / Kaseikyo, RC5, RC6, Samsung, Sony, (Pronto), BangOlufsen, BoseWave, Lego, Whynter, FAST, MagiQuest.<br/><br/><b>New: </b>Added untested Uno R4 support. Improved ESP support. Added DECODE_ONKYO. Old decode() prints a message now.<br/><a href="https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/changelog.md">Release notes</a><br/> -category=Communication -url=https://github.com/Arduino-IRremote/Arduino-IRremote -architectures=avr,megaavr,samd,esp8266,esp32,stm32,STM32F1,mbed,mbed_nano,rp2040,mbed_rp2040,renesas_uno -includes=IRremote.hpp diff --git a/IRremote/pictures/BoseWaveMusicSystem.jpg b/IRremote/pictures/BoseWaveMusicSystem.jpg deleted file mode 100644 index 6f11962eb09a953bfa119beadf84cef050292829..0000000000000000000000000000000000000000 Binary files a/IRremote/pictures/BoseWaveMusicSystem.jpg and /dev/null differ diff --git a/IRremote/pictures/IR_PWM_by_software_detail.png b/IRremote/pictures/IR_PWM_by_software_detail.png deleted file mode 100644 index 5d5e8d3ee244584598779cf9e765bc9725de1c62..0000000000000000000000000000000000000000 Binary files a/IRremote/pictures/IR_PWM_by_software_detail.png and /dev/null differ diff --git a/IRremote/pictures/IR_PWM_by_software_jitter.png b/IRremote/pictures/IR_PWM_by_software_jitter.png deleted file mode 100644 index 25479711fe9697019045863f43b0395fe49d079b..0000000000000000000000000000000000000000 Binary files a/IRremote/pictures/IR_PWM_by_software_jitter.png and /dev/null differ diff --git a/IRremote/pictures/LGRemote1.jpg b/IRremote/pictures/LGRemote1.jpg deleted file mode 100644 index 11b3debfac3927183be82a510bca5933ff470c09..0000000000000000000000000000000000000000 Binary files a/IRremote/pictures/LGRemote1.jpg and /dev/null differ diff --git a/IRremote/pictures/LG_AKB73315611.jpg b/IRremote/pictures/LG_AKB73315611.jpg deleted file mode 100644 index b907ae609254a9190421306ce73eab9e09a449dd..0000000000000000000000000000000000000000 Binary files a/IRremote/pictures/LG_AKB73315611.jpg and /dev/null differ diff --git a/IRremote/pictures/LG_AKB75415316.jpg b/IRremote/pictures/LG_AKB75415316.jpg deleted file mode 100644 index 83541bf834b2bd4dbcf3e3cd0edd3e36fc65ab49..0000000000000000000000000000000000000000 Binary files a/IRremote/pictures/LG_AKB75415316.jpg and /dev/null differ diff --git a/IRremote/pictures/SloeberDefineSymbols.png b/IRremote/pictures/SloeberDefineSymbols.png deleted file mode 100644 index 10b99acf7dbcb7c1e58d543bfa122953824e44f5..0000000000000000000000000000000000000000 Binary files a/IRremote/pictures/SloeberDefineSymbols.png and /dev/null differ diff --git a/IRremote/sam.cpp b/IRremote/sam.cpp deleted file mode 100644 index 3133dacbef982785a5dfc550aab0abc092f77306..0000000000000000000000000000000000000000 --- a/IRremote/sam.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Support routines for SAM processor boards - -#include "IRremote.h" -#include "IRremoteInt.h" - -#if defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) - -// "Idiot check" -#ifdef USE_DEFAULT_ENABLE_IR_IN -#error Must undef USE_DEFAULT_ENABLE_IR_IN -#endif - -//+============================================================================= -// ATSAMD Timer setup & IRQ functions -// - -// following based on setup from GitHub jdneo/timerInterrupt.ino - -static void setTimerFrequency(int frequencyHz) -{ - int compareValue = (SYSCLOCK / (TIMER_PRESCALER_DIV * frequencyHz)) - 1; - //Serial.println(compareValue); - TcCount16* TC = (TcCount16*) TC3; - // Make sure the count is in a proportional position to where it was - // to prevent any jitter or disconnect when changing the compare value. - TC->COUNT.reg = map(TC->COUNT.reg, 0, TC->CC[0].reg, 0, compareValue); - TC->CC[0].reg = compareValue; - //Serial.print("COUNT.reg "); - //Serial.println(TC->COUNT.reg); - //Serial.print("CC[0].reg "); - //Serial.println(TC->CC[0].reg); - while (TC->STATUS.bit.SYNCBUSY == 1); -} - -static void startTimer() -{ - REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3); - while (GCLK->STATUS.bit.SYNCBUSY == 1); // wait for sync - - TcCount16* TC = (TcCount16*) TC3; - - TC->CTRLA.reg &= ~TC_CTRLA_ENABLE; - while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync - - // Use the 16-bit timer - TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16; - while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync - - // Use match mode so that the timer counter resets when the count matches the compare register - TC->CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ; - while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync - - // Set prescaler to 1024 - //TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1024; - TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV64; - while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync - - setTimerFrequency(1000000 / USECPERTICK); - - // Enable the compare interrupt - TC->INTENSET.reg = 0; - TC->INTENSET.bit.MC0 = 1; - - NVIC_EnableIRQ(TC3_IRQn); - - TC->CTRLA.reg |= TC_CTRLA_ENABLE; - while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync -} - -//+============================================================================= -// initialization -// - -void IRrecv::enableIRIn() -{ - // Interrupt Service Routine - Fires every 50uS - //Serial.println("Starting timer"); - startTimer(); - //Serial.println("Started timer"); - - // Initialize state machine variables - irparams.rcvstate = STATE_IDLE; - irparams.rawlen = 0; - - // Set pin modes - pinMode(irparams.recvpin, INPUT); -} - -void irs(); // Defined in IRRemote as ISR(TIMER_INTR_NAME) - -void TC3_Handler(void) -{ - TcCount16* TC = (TcCount16*) TC3; - // If this interrupt is due to the compare register matching the timer count - // we toggle the LED. - if (TC->INTFLAG.bit.MC0 == 1) { - TC->INTFLAG.bit.MC0 = 1; - irs(); - } -} - -#endif // defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) \ No newline at end of file diff --git a/IRremote/src/IRFeedbackLED.hpp b/IRremote/src/IRFeedbackLED.hpp deleted file mode 100644 index 97611b0836a5e4236a23484916b36960a2c17862..0000000000000000000000000000000000000000 --- a/IRremote/src/IRFeedbackLED.hpp +++ /dev/null @@ -1,159 +0,0 @@ -/** - * @file IRFeedbackLED.hpp - * - * @brief All Feedback LED specific functions are contained in this file. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************* - * MIT License - * - * Copyright (c) 2021-2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_FEEDBACK_LED_HPP -#define _IR_FEEDBACK_LED_HPP - -/** \addtogroup FeedbackLEDFunctions Feedback LED functions - * @{ - */ - -/** - * Contains pin number and enable status of the feedback LED - */ -struct FeedbackLEDControlStruct { - uint8_t FeedbackLEDPin; ///< if 0, then take board specific FEEDBACK_LED_ON() and FEEDBACK_LED_OFF() functions - uint8_t LedFeedbackEnabled; ///< LED_FEEDBACK_ENABLED_FOR_RECEIVE or LED_FEEDBACK_ENABLED_FOR_SEND -> enable blinking of pin on IR processing -}; - -struct FeedbackLEDControlStruct FeedbackLEDControl; ///< The feedback LED control instance - -/** - * Enable blinking of feedback LED (LED_BUILTIN is taken as default) on IR sending and receiving - * Cannot disable it here!!! Use disableLEDFeedbackForReceive() or disableLEDFeedbackForSend() - * @param aFeedbackLEDPin If aFeedbackLEDPin == 0, then take board specific FEEDBACK_LED_ON() and FEEDBACK_LED_ON() and FEEDBACK_LED_OFF() functions - * If FeedbackLEDPin == 0 and no LED_BUILTIN defined, disable LED feedback - * @param aEnableLEDFeedback If LED_FEEDBACK_ENABLED_FOR_RECEIVE or LED_FEEDBACK_ENABLED_FOR_SEND -> enable blinking of Feedback LED - */ -void setLEDFeedback(uint8_t aFeedbackLEDPin, uint8_t aEnableLEDFeedback) { - - FeedbackLEDControl.FeedbackLEDPin = aFeedbackLEDPin; // default is 0 -> use LED_BUILTIN if available, else disable feedback - - if (aEnableLEDFeedback != DO_NOT_ENABLE_LED_FEEDBACK) { - FeedbackLEDControl.LedFeedbackEnabled |= aEnableLEDFeedback; - if (aFeedbackLEDPin != USE_DEFAULT_FEEDBACK_LED_PIN) { - pinModeFast(aFeedbackLEDPin, OUTPUT); -#if defined(LED_BUILTIN) - } else { - pinModeFast(LED_BUILTIN, OUTPUT); -#else - FeedbackLEDControl.LedFeedbackEnabled = LED_FEEDBACK_DISABLED_COMPLETELY; // we have no LED_BUILTIN available -#endif - } - } -} - -/* - * Direct replacement for blink13() - */ -void setLEDFeedback(bool aEnableLEDFeedback) { - bool tEnableLEDFeedback = LED_FEEDBACK_DISABLED_COMPLETELY; - if (aEnableLEDFeedback) { - tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_SEND | LED_FEEDBACK_ENABLED_FOR_RECEIVE; - } - setLEDFeedback(FeedbackLEDControl.FeedbackLEDPin, tEnableLEDFeedback); -} - -void enableLEDFeedback() { - FeedbackLEDControl.LedFeedbackEnabled |= LED_FEEDBACK_ENABLED_FOR_RECEIVE; -} - -void disableLEDFeedback() { - FeedbackLEDControl.LedFeedbackEnabled &= ~(LED_FEEDBACK_ENABLED_FOR_RECEIVE); -} - -void enableLEDFeedbackForSend() { - FeedbackLEDControl.LedFeedbackEnabled |= LED_FEEDBACK_ENABLED_FOR_SEND; -} - -void disableLEDFeedbackForSend() { - FeedbackLEDControl.LedFeedbackEnabled &= ~(LED_FEEDBACK_ENABLED_FOR_SEND); -} - -/** - * Flash LED while receiving or sending IR data. Does not check if enabled, this must be done by the caller. - * Handles the 0 value of FeedbackLEDPin and the macro FEEDBACK_LED_IS_ACTIVE_LOW. - */ -#if defined(ESP32) || defined(ESP8266) -IRAM_ATTR -#endif -void setFeedbackLED(bool aSwitchLedOn) { - if (aSwitchLedOn) { - if (FeedbackLEDControl.FeedbackLEDPin != USE_DEFAULT_FEEDBACK_LED_PIN) { -#if defined(FEEDBACK_LED_IS_ACTIVE_LOW) - digitalWriteFast(FeedbackLEDControl.FeedbackLEDPin, LOW); // Turn user defined pin LED on -#else - digitalWriteFast(FeedbackLEDControl.FeedbackLEDPin, HIGH); // Turn user defined pin LED on -#endif -#if defined(LED_BUILTIN) // use fast macros here - } else { -# if defined(FEEDBACK_LED_IS_ACTIVE_LOW) - digitalWriteFast(LED_BUILTIN, LOW); // For AVR, this generates a single cbi command -# else - digitalWriteFast(LED_BUILTIN, HIGH); // For AVR, this generates a single sbi command -# endif -#endif - } - } else { - if (FeedbackLEDControl.FeedbackLEDPin != USE_DEFAULT_FEEDBACK_LED_PIN) { -#if defined(FEEDBACK_LED_IS_ACTIVE_LOW) - digitalWriteFast(FeedbackLEDControl.FeedbackLEDPin, HIGH); // Turn user defined pin LED off -#else - digitalWriteFast(FeedbackLEDControl.FeedbackLEDPin, LOW); // Turn user defined pin LED off -#endif -#if defined(LED_BUILTIN) - } else { -# if defined(FEEDBACK_LED_IS_ACTIVE_LOW) - digitalWriteFast(LED_BUILTIN, HIGH); // For AVR, this generates a single sbi command -# else - digitalWriteFast(LED_BUILTIN, LOW); // For AVR, this generates a single cbi command -# endif -#endif - } - } -} - -/** - * Old deprecated function name for setLEDFeedback() or enableLEDFeedback() / disableLEDFeedback() - */ -void IRrecv::blink13(uint8_t aEnableLEDFeedback) { - setLEDFeedback(FeedbackLEDControl.FeedbackLEDPin, aEnableLEDFeedback); -} -/** - * Old deprecated function name for setLEDFeedback() - */ -void setBlinkPin(uint8_t aBlinkPin) { - setLEDFeedback(aBlinkPin, FeedbackLEDControl.LedFeedbackEnabled); -} - -/** @}*/ - -#endif // _IR_FEEDBACK_LED_HPP diff --git a/IRremote/src/IRProtocol.h b/IRremote/src/IRProtocol.h deleted file mode 100644 index 42d3e2cb2268f845dae7a8466d33ef52092749e4..0000000000000000000000000000000000000000 --- a/IRremote/src/IRProtocol.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - * @file IRProtocol.h - * @brief Common declarations for receiving and sending. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_PROTOCOL_H -#define _IR_PROTOCOL_H - -/** - * An enum consisting of all supported formats. - * You do NOT need to remove entries from this list when disabling protocols! - * !!!Must be the same order as ProtocolNames in IRReceive.hpp!!! - */ -typedef enum { - UNKNOWN = 0, - PULSE_WIDTH, - PULSE_DISTANCE, - APPLE, - DENON, - JVC, - LG, - LG2, - NEC, - NEC2, /* NEC with full frame as repeat */ - ONKYO, - PANASONIC, - KASEIKYO, - KASEIKYO_DENON, - KASEIKYO_SHARP, - KASEIKYO_JVC, - KASEIKYO_MITSUBISHI, - RC5, - RC6, - SAMSUNG, - SAMSUNG48, - SAMSUNG_LG, - SHARP, - SONY, - /* Now the exotic protocols */ - BANG_OLUFSEN, - BOSEWAVE, - LEGO_PF, - MAGIQUEST, - WHYNTER, - FAST -} decode_type_t; - - -#define SIRCS_12_PROTOCOL 12 -#define SIRCS_15_PROTOCOL 15 -#define SIRCS_20_PROTOCOL 20 - -struct DistanceWidthTimingInfoStruct { - uint16_t HeaderMarkMicros; - uint16_t HeaderSpaceMicros; - uint16_t OneMarkMicros; - uint16_t OneSpaceMicros; - uint16_t ZeroMarkMicros; - uint16_t ZeroSpaceMicros; -}; - -/* - * Definitions for member IRData.flags - */ -#define IRDATA_FLAGS_EMPTY 0x00 -#define IRDATA_FLAGS_IS_REPEAT 0x01 ///< The gap between the preceding frame is as smaller than the maximum gap expected for a repeat. !!!We do not check for changed command or address, because it is almost not possible to press 2 different buttons on the remote within around 100 ms!!! -#define IRDATA_FLAGS_IS_AUTO_REPEAT 0x02 ///< The current repeat frame is a repeat, that is always sent after a regular frame and cannot be avoided. Only specified for protocols DENON, and LEGO. -#define IRDATA_FLAGS_PARITY_FAILED 0x04 ///< The current (autorepeat) frame violated parity check. -#define IRDATA_FLAGS_TOGGLE_BIT 0x08 ///< Is set if RC5 or RC6 toggle bit is set. -#define IRDATA_TOGGLE_BIT_MASK 0x08 ///< deprecated -is set if RC5 or RC6 toggle bit is set. -#define IRDATA_FLAGS_EXTRA_INFO 0x10 ///< There is extra info not contained in address and data (e.g. Kaseikyo unknown vendor ID, or in decodedRawDataArray). -#define IRDATA_FLAGS_WAS_OVERFLOW 0x40 ///< irparams.rawlen is set to 0 in this case to avoid endless OverflowFlag. -#define IRDATA_FLAGS_IS_MSB_FIRST 0x80 ///< Value is mainly determined by the (known) protocol. -#define IRDATA_FLAGS_IS_LSB_FIRST 0x00 - -#define RAW_DATA_ARRAY_SIZE ((((RAW_BUFFER_LENGTH - 2) - 1) / (2 * BITS_IN_RAW_DATA_TYPE)) + 1) // The -2 is for initial gap + stop bit mark, 128 mark + spaces for 64 bit. -/** - * Data structure for the user application, available as decodedIRData. - * Filled by decoders and read by print functions or user application. - */ -struct IRData { - decode_type_t protocol; ///< UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ... - uint16_t address; ///< Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << 8) | tSpaceTicksLong - uint16_t command; ///< Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort - uint16_t extra; ///< Contains upper 16 bit of Magiquest WandID, Kaseikyo unknown vendor ID and Distance protocol (HeaderMarkTicks << 8) | HeaderSpaceTicks. - IRRawDataType decodedRawData; ///< Up to 32/64 bit decoded raw data, to be used for send functions. -#if defined(DECODE_DISTANCE_WIDTH) - // This replaces the address, command, extra and decodedRawData in case of protocol == PULSE_DISTANCE or -rather seldom- protocol == PULSE_WIDTH. - DistanceWidthTimingInfoStruct DistanceWidthTimingInfo; // 12 bytes - IRRawDataType decodedRawDataArray[RAW_DATA_ARRAY_SIZE]; ///< 32/64 bit decoded raw data, to be used for send function. -#endif - uint16_t numberOfBits; ///< Number of bits received for data (address + command + parity) - to determine protocol length if different length are possible. - uint8_t flags; ///< IRDATA_FLAGS_IS_REPEAT, IRDATA_FLAGS_WAS_OVERFLOW etc. See IRDATA_FLAGS_* definitions above - irparams_struct *rawDataPtr; ///< Pointer of the raw timing data to be decoded. Mainly the OverflowFlag and the data buffer filled by receiving ISR. -}; - -struct PulseDistanceWidthProtocolConstants { - decode_type_t ProtocolIndex; - uint_fast8_t FrequencyKHz; - DistanceWidthTimingInfoStruct DistanceWidthTimingInfo; - uint8_t Flags; - unsigned int RepeatPeriodMillis; - void (*SpecialSendRepeatFunction)(); // using non member functions here saves up to 250 bytes for send demo -// void (IRsend::*SpecialSendRepeatFunction)(); -}; -/* - * Definitions for member PulseDistanceWidthProtocolConstants.Flags - */ -#define SUPPRESS_STOP_BIT_FOR_THIS_DATA 0x20 -#define PROTOCOL_IS_MSB_FIRST IRDATA_FLAGS_IS_MSB_FIRST -#define PROTOCOL_IS_LSB_FIRST IRDATA_FLAGS_IS_LSB_FIRST -// 2 definitions for deprecated parameter bool aSendStopBit -#define SEND_STOP_BIT true -#define SEND_NO_STOP_BIT false - -/* - * Carrier frequencies for various protocols - */ -#if !defined(BEO_KHZ) // guard used for unit test, which sends and receive Bang&Olufsen with 38 kHz. -#define BEO_KHZ 455 -#endif -#define SONY_KHZ 40 -#define BOSEWAVE_KHZ 38 -#define DENON_KHZ 38 -#define JVC_KHZ 38 -#define LG_KHZ 38 -#define NEC_KHZ 38 -#define SAMSUNG_KHZ 38 -#define KASEIKYO_KHZ 37 -#define RC5_RC6_KHZ 36 - -#if defined(__AVR__) -const __FlashStringHelper* getProtocolString(decode_type_t aProtocol); -#else -const char* getProtocolString(decode_type_t aProtocol); -#endif -void printIRResultShort(Print *aSerial, IRData *aIRDataPtr, bool aPrintGap); // A static function to be able to print send or copied received data. - -/* - * Convenience functions to convert MSB to LSB values - */ -uint8_t bitreverseOneByte(uint8_t aValue); -uint32_t bitreverse32Bit(uint32_t aInput); - -#endif // _IR_PROTOCOL_H diff --git a/IRremote/src/IRProtocol.hpp b/IRremote/src/IRProtocol.hpp deleted file mode 100644 index 093d2a8f43c4f9dfab4b41befdc0c0d80689f388..0000000000000000000000000000000000000000 --- a/IRremote/src/IRProtocol.hpp +++ /dev/null @@ -1,294 +0,0 @@ -/* - * IRReceive.hpp - * This file is exclusively included by IRremote.h to enable easy configuration of library switches - * - * Contains all protocol functions used by receiver and sender. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2009-2023 Ken Shirriff, Rafi Khan, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_PROTOCOL_HPP -#define _IR_PROTOCOL_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/* - * Check for additional characteristics of timing like length of mark for a constant mark protocol, - * where space length determines the bit value. Requires up to 194 additional bytes of program memory. - */ -//#define DECODE_STRICT_CHECKS -/** \addtogroup Receiving Receiving IR data for multiple protocols - * @{ - */ - -const char string_Unknown[] PROGMEM = "UNKNOWN"; -const char string_PulseWidth[] PROGMEM = "PulseWidth"; -const char string_PulseDistance[] PROGMEM = "PulseDistance"; -const char string_Apple[] PROGMEM = "Apple"; -const char string_Denon[] PROGMEM = "Denon"; -const char string_JVC[] PROGMEM = "JVC"; -const char string_LG[] PROGMEM = "LG"; -const char string_LG2[] PROGMEM = "LG2"; -const char string_NEC[] PROGMEM = "NEC"; -const char string_NEC2[] PROGMEM = "NEC2"; -const char string_Onkyo[] PROGMEM = "Onkyo"; -const char string_Panasonic[] PROGMEM = "Panasonic"; -const char string_Kaseikyo[] PROGMEM = "Kaseikyo"; -const char string_Kaseikyo_Denon[] PROGMEM = "Kaseikyo_Denon"; -const char string_Kaseikyo_Sharp[] PROGMEM = "Kaseikyo_Sharp"; -const char string_Kaseikyo_JVC[] PROGMEM = "Kaseikyo_JVC"; -const char string_Kaseikyo_Mitsubishi[] PROGMEM = "Kaseikyo_Mitsubishi"; -const char string_RC5[] PROGMEM = "RC5"; -const char string_RC6[] PROGMEM = "RC6"; -const char string_Samsung[] PROGMEM = "Samsung"; -const char string_Samsung48[] PROGMEM = "Samsung48"; -const char string_SamsungLG[] PROGMEM = "SamsungLG"; -const char string_Sharp[] PROGMEM = "Sharp"; -const char string_Sony[] PROGMEM = "Sony"; -const char string_BangOlufsen[] PROGMEM = "Bang&Olufsen"; -const char string_BoseWave[] PROGMEM = "BoseWave"; -const char string_Lego[] PROGMEM = "Lego"; -const char string_MagiQuest[] PROGMEM = "MagiQuest"; -const char string_Whynter[] PROGMEM = "Whynter"; -const char string_FAST[] PROGMEM = "FAST"; - -/* - * !!Must be the same order as in decode_type_t in IRProtocol.h!!! - */ -const char *const ProtocolNames[] -PROGMEM = { string_Unknown, string_PulseWidth, string_PulseDistance, string_Apple, string_Denon, string_JVC, string_LG, string_LG2, - string_NEC, string_NEC2, string_Onkyo, string_Panasonic, string_Kaseikyo, string_Kaseikyo_Denon, string_Kaseikyo_Sharp, - string_Kaseikyo_JVC, string_Kaseikyo_Mitsubishi, string_RC5, string_RC6, string_Samsung, string_Samsung48, string_SamsungLG, - string_Sharp, string_Sony -#if !defined(EXCLUDE_EXOTIC_PROTOCOLS) - , string_BangOlufsen, string_BoseWave, string_Lego, string_MagiQuest, string_Whynter, string_FAST -#endif - }; - -#if defined(__AVR__) -const __FlashStringHelper* getProtocolString(decode_type_t aProtocol) { - const char *tProtocolStringPtr = (char*) pgm_read_word(&ProtocolNames[aProtocol]); - return ((__FlashStringHelper*) (tProtocolStringPtr)); -} -#else -const char* getProtocolString(decode_type_t aProtocol) { - return ProtocolNames[aProtocol]; -} -#endif - -#if (__INT_WIDTH__ >= 32) -# if __has_include(<type_traits>) -/* - * This code to handle the missing print(unsigned long long...) function of seeduino core was contributed by sklott - * https://stackoverflow.com/questions/74622227/avoid-calling-of-function-size-t-printprintunsigned-long-long-n-int-base-if - */ -#include <type_traits> - -// If you have C++17 you can just use std::void_t, or use this for all versions -#if __cpp_lib_void_t >= 201411L -template<typename T> -using void_t = std::void_t<T>; -#else -template<typename ... Ts> struct make_void { - typedef void type; -}; -template<typename ... Ts> using void_t = typename make_void<Ts...>::type; -#endif - -// Detecting if we have print(unsigned long long value, int base) / print(0ull, 0) overload -template<typename T, typename = void> -struct has_ull_print: std::false_type { -}; -template<typename T> -struct has_ull_print<T, void_t<decltype(std::declval<T>().print(0ull, 0))>> : std::true_type { -}; - -// Must be namespace, to avoid public and static declarations for class -namespace PrintULL { -template<typename PrintImplType, typename std::enable_if<!has_ull_print<PrintImplType>::value, bool>::type = true> -size_t print(PrintImplType *p, unsigned long long value, int base) { - size_t tLength = p->print(static_cast<uint32_t>(value >> 32), base); - tLength += p->print(static_cast<uint32_t>(value), base); - return tLength; -} - -template<typename PrintImplType, typename std::enable_if<has_ull_print<PrintImplType>::value, bool>::type = true> -size_t print(PrintImplType *p, unsigned long long value, int base) { - return p->print(value, base); -} -} -; -# else -namespace PrintULL { - size_t print(Print *aSerial, unsigned long long n, int base) { - return aSerial->print(n, base); - } -}; -# endif -#endif - -/** - * Function to print decoded result and flags in one line. - * A static function to be able to print data to send or copied received data. - * Ends with println(). - * - * @param aSerial The Print object on which to write, for Arduino you can use &Serial. - * @param aIRDataPtr Pointer to the data to be printed. - * @param aPrintRepeatGap If true also print the gap before repeats. - * - */ -void printIRResultShort(Print *aSerial, IRData *aIRDataPtr, bool aPrintRepeatGap) { - if (aIRDataPtr->flags & IRDATA_FLAGS_WAS_OVERFLOW) { - aSerial->println(F("Overflow")); - return; - } - aSerial->print(F("Protocol=")); - aSerial->print(getProtocolString(aIRDataPtr->protocol)); - if (aIRDataPtr->protocol == UNKNOWN) { -#if defined(DECODE_HASH) - aSerial->print(F(" Hash=0x")); -#if (__INT_WIDTH__ < 32) - aSerial->print(aIRDataPtr->decodedRawData, HEX); -#else - PrintULL::print(aSerial,aIRDataPtr->decodedRawData, HEX); -#endif - -#endif -#if !defined(DISABLE_CODE_FOR_RECEIVER) - aSerial->print(' '); - aSerial->print((aIRDataPtr->rawDataPtr->rawlen + 1) / 2, DEC); - aSerial->println(F(" bits (incl. gap and start) received")); -#endif - } else { -#if defined(DECODE_DISTANCE_WIDTH) - if (aIRDataPtr->protocol != PULSE_DISTANCE && aIRDataPtr->protocol != PULSE_WIDTH) { -#endif - /* - * New decoders have address and command - */ - aSerial->print(F(" Address=0x")); - aSerial->print(aIRDataPtr->address, HEX); - - aSerial->print(F(" Command=0x")); - aSerial->print(aIRDataPtr->command, HEX); - - if (aIRDataPtr->flags & IRDATA_FLAGS_EXTRA_INFO) { - aSerial->print(F(" Extra=0x")); - aSerial->print(aIRDataPtr->extra, HEX); - } - - if (aIRDataPtr->flags & IRDATA_FLAGS_PARITY_FAILED) { - aSerial->print(F(" Parity fail")); - } - - if (aIRDataPtr->flags & IRDATA_FLAGS_TOGGLE_BIT) { - aSerial->print(F(" Toggle=1")); - } -#if defined(DECODE_DISTANCE_WIDTH) - } -#endif - if (aIRDataPtr->flags & (IRDATA_FLAGS_IS_AUTO_REPEAT | IRDATA_FLAGS_IS_REPEAT)) { - aSerial->print(' '); - if (aIRDataPtr->flags & IRDATA_FLAGS_IS_AUTO_REPEAT) { - aSerial->print(F("Auto-")); - } - aSerial->print(F("Repeat")); -#if !defined(DISABLE_CODE_FOR_RECEIVER) - if (aPrintRepeatGap) { - aSerial->print(F(" gap=")); - aSerial->print((uint32_t) aIRDataPtr->rawDataPtr->rawbuf[0] * MICROS_PER_TICK); - aSerial->print(F("us")); - } -#else - (void)aPrintRepeatGap; -#endif - } - - /* - * Print raw data - */ - if (!(aIRDataPtr->flags & IRDATA_FLAGS_IS_REPEAT) || aIRDataPtr->decodedRawData != 0) { - aSerial->print(F(" Raw-Data=0x")); -#if (__INT_WIDTH__ < 32) - aSerial->print(aIRDataPtr->decodedRawData, HEX); -#else - PrintULL::print(aSerial, aIRDataPtr->decodedRawData, HEX); -#endif - /* - * Print number of bits processed - */ - aSerial->print(' '); - aSerial->print(aIRDataPtr->numberOfBits, DEC); - aSerial->print(F(" bits")); - - if (aIRDataPtr->flags & IRDATA_FLAGS_IS_MSB_FIRST) { - aSerial->println(F(" MSB first")); - } else { - aSerial->println(F(" LSB first")); - } - - } else { - aSerial->println(); - } - } -} - -/********************************************************************************************************************** - * Function to bit reverse OLD MSB values of e.g. NEC. - **********************************************************************************************************************/ -uint8_t bitreverseOneByte(uint8_t aValue) { -// uint8_t tReversedValue; -// return __builtin_avr_insert_bits(0x01234567, aValue, tReversedValue); -// 76543210 - aValue = (aValue >> 4) | (aValue << 4); // Swap in groups of 4 -// 32107654 - aValue = ((aValue & 0xcc) >> 2) | ((aValue & 0x33) << 2); // Swap in groups of 2 -// 10325476 - aValue = ((aValue & 0xaa) >> 1) | ((aValue & 0x55) << 1); // Swap bit pairs -// 01234567 - return aValue; -} - -uint32_t bitreverse32Bit(uint32_t aInput) { -// __builtin_avr_insert_bits(); - LongUnion tValue; - tValue.UByte.HighByte = bitreverseOneByte(aInput); - tValue.UByte.MidHighByte = bitreverseOneByte(aInput >> 8); - tValue.UByte.MidLowByte = bitreverseOneByte(aInput >> 16); - tValue.UByte.LowByte = bitreverseOneByte(aInput >> 24); - return tValue.ULong; -} - -/** @}*/ - -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_PROTOCOL_HPP diff --git a/IRremote/src/IRReceive.hpp b/IRremote/src/IRReceive.hpp deleted file mode 100644 index 227a3ce57ec9384647dd87f5b24bba83042948b0..0000000000000000000000000000000000000000 --- a/IRremote/src/IRReceive.hpp +++ /dev/null @@ -1,1757 +0,0 @@ -/* - * IRReceive.hpp - * This file is exclusively included by IRremote.h to enable easy configuration of library switches - * - * Contains all IRrecv class functions as well as other receiver related functions. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2009-2023 Ken Shirriff, Rafi Khan, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_RECEIVE_HPP -#define _IR_RECEIVE_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -//#define LOCAL_DEBUG // -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -#if defined(TRACE) && !defined(LOCAL_TRACE) -#define LOCAL_TRACE -#else -//#define LOCAL_TRACE // This enables debug output only for this file -#endif -/* - * Low level hardware timing measurement - */ -//#define _IR_MEASURE_TIMING // for ISR -//#define _IR_TIMING_TEST_PIN 7 // "pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);" is executed at start() -// -/* - * Check for additional characteristics of timing like length of mark for a constant mark protocol, - * where space length determines the bit value. Requires up to 194 additional bytes of program memory. - */ -//#define DECODE_STRICT_CHECKS -/** \addtogroup Receiving Receiving IR data for multiple protocols - * @{ - */ -/** - * The receiver instance - */ -IRrecv IrReceiver; - -/* - * The control structure instance - */ -struct irparams_struct irparams; // the irparams instance - -/** - * Instantiate the IRrecv class. Multiple instantiation is not supported. - * @param IRReceivePin Arduino pin to use. No sanity check is made. - */ -IRrecv::IRrecv() { - decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc. - setReceivePin(0); -#if !defined(NO_LED_FEEDBACK_CODE) - setLEDFeedback(0, DO_NOT_ENABLE_LED_FEEDBACK); -#endif -} - -IRrecv::IRrecv(uint_fast8_t aReceivePin) { - decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc. - setReceivePin(aReceivePin); -#if !defined(NO_LED_FEEDBACK_CODE) - setLEDFeedback(0, DO_NOT_ENABLE_LED_FEEDBACK); -#endif -} - -/** - * Instantiate the IRrecv class. Multiple instantiation is not supported. - * @param aReceivePin Arduino pin to use, where a demodulating IR receiver is connected. - * @param aFeedbackLEDPin if 0, then take board specific FEEDBACK_LED_ON() and FEEDBACK_LED_OFF() functions - */ -IRrecv::IRrecv(uint_fast8_t aReceivePin, uint_fast8_t aFeedbackLEDPin) { - decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc. - setReceivePin(aReceivePin); -#if !defined(NO_LED_FEEDBACK_CODE) - setLEDFeedback(aFeedbackLEDPin, DO_NOT_ENABLE_LED_FEEDBACK); -#else - (void) aFeedbackLEDPin; -#endif -} - -/********************************************************************************************************************** - * Interrupt Service Routine - Called every 50 us - * - * Duration in ticks of 50 us of alternating SPACE, MARK are recorded in irparams.rawbuf array. - * 'rawlen' counts the number of entries recorded so far. - * First entry is the SPACE between transmissions. - * - * As soon as one SPACE entry gets longer than RECORD_GAP_TICKS, state switches to STOP (frame received). Timing of SPACE continues. - * A call of resume() switches from STOP to IDLE. - * As soon as first MARK arrives in IDLE, gap width is recorded and new logging starts. - * - * With digitalRead and Feedback LED - * 15 pushs, 1 in, 1 eor before start of code = 2 us @16MHz + * 7.2 us computation time (6us idle time) + * pop + reti = 2.25 us @16MHz => 10.3 to 11.5 us @16MHz - * With portInputRegister and mask and Feedback LED code commented - * 9 pushs, 1 in, 1 eor before start of code = 1.25 us @16MHz + * 2.25 us computation time + * pop + reti = 1.5 us @16MHz => 5 us @16MHz - * => Minimal CPU frequency is 4 MHz - * - **********************************************************************************************************************/ -#if defined(ESP8266) || defined(ESP32) -IRAM_ATTR -#endif -void IRReceiveTimerInterruptHandler() { -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) - digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles -#endif -// 7 - 8.5 us for ISR body (without pushes and pops) for ATmega328 @16MHz - -#if defined(TIMER_REQUIRES_RESET_INTR_PENDING) - timerResetInterruptPending(); // reset TickCounterForISR interrupt flag if required (currently only for Teensy and ATmega4809) -#endif - -// Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] -#if defined(__AVR__) - uint8_t tIRInputLevel = *irparams.IRReceivePinPortInputRegister & irparams.IRReceivePinMask; -#else - uint_fast8_t tIRInputLevel = (uint_fast8_t) digitalReadFast(irparams.IRReceivePin); -#endif - - /* - * Increase TickCounter and clip it at maximum 0xFFFF / 3.2 seconds at 50 us ticks - */ - if (irparams.TickCounterForISR < UINT16_MAX) { - irparams.TickCounterForISR++; // One more 50uS tick - } - - /* - * Due to a ESP32 compiler bug https://github.com/espressif/esp-idf/issues/1552 no switch statements are possible for ESP32 - * So we change the code to if / else if - */ -// switch (irparams.StateForISR) { -// - if (irparams.StateForISR == IR_REC_STATE_IDLE) { - /* - * Here we are just resumed and maybe in the middle of a transmission - */ - if (tIRInputLevel == INPUT_MARK) { - // check if we did not start in the middle of a transmission by checking the minimum length of leading space - if (irparams.TickCounterForISR > RECORD_GAP_TICKS) { -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) -// digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles -#endif - /* - * Gap between two transmissions just ended; Record gap duration + start recording transmission - * Initialize all state machine variables - */ - irparams.OverflowFlag = false; - irparams.rawbuf[0] = irparams.TickCounterForISR; - irparams.rawlen = 1; - irparams.StateForISR = IR_REC_STATE_MARK; - } // otherwise stay in idle state - irparams.TickCounterForISR = 0; // reset counter in both cases - } - - } else if (irparams.StateForISR == IR_REC_STATE_MARK) { // Timing mark - if (tIRInputLevel != INPUT_MARK) { - /* - * Mark ended here. Record mark time in rawbuf array - */ -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) -// digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles -#endif - irparams.rawbuf[irparams.rawlen++] = irparams.TickCounterForISR; // record mark - irparams.StateForISR = IR_REC_STATE_SPACE; - irparams.TickCounterForISR = 0; // This resets the tick counter also at end of frame :-) - } - - } else if (irparams.StateForISR == IR_REC_STATE_SPACE) { // Timing space - if (tIRInputLevel == INPUT_MARK) { - /* - * Space ended here. Check for overflow and record space time in rawbuf array - */ - if (irparams.rawlen >= RAW_BUFFER_LENGTH) { - // Flag up a read OverflowFlag; Stop the state machine - irparams.OverflowFlag = true; - irparams.StateForISR = IR_REC_STATE_STOP; -#if !IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK - /* - * Call callback if registered (not NULL) - */ - if (irparams.ReceiveCompleteCallbackFunction != NULL) { - irparams.ReceiveCompleteCallbackFunction(); - } -#endif - } else { -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) -// digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles -#endif - irparams.rawbuf[irparams.rawlen++] = irparams.TickCounterForISR; // record space - irparams.StateForISR = IR_REC_STATE_MARK; - } - irparams.TickCounterForISR = 0; - - } else if (irparams.TickCounterForISR > RECORD_GAP_TICKS) { - /* - * Maximum space duration reached here. - * Current code is ready for processing! - * We received a long space, which indicates gap between codes. - * Switch to IR_REC_STATE_STOP - * Don't reset TickCounterForISR; keep counting width of next leading space - */ - irparams.StateForISR = IR_REC_STATE_STOP; -#if !IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK - /* - * Call callback if registered (not NULL) - */ - if (irparams.ReceiveCompleteCallbackFunction != NULL) { - irparams.ReceiveCompleteCallbackFunction(); - } -#endif - } - } else if (irparams.StateForISR == IR_REC_STATE_STOP) { - /* - * Complete command received - * stay here until resume() is called, which switches state to IR_REC_STATE_IDLE - */ -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) -// digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles -#endif - if (tIRInputLevel == INPUT_MARK) { - // Reset gap TickCounterForISR, to prepare for detection if we are in the middle of a transmission after call of resume() - irparams.TickCounterForISR = 0; - } - } - -#if !defined(NO_LED_FEEDBACK_CODE) - if (FeedbackLEDControl.LedFeedbackEnabled == LED_FEEDBACK_ENABLED_FOR_RECEIVE) { - setFeedbackLED(tIRInputLevel == INPUT_MARK); - } -#endif - -#ifdef _IR_MEASURE_TIMING - digitalWriteFast(_IR_TIMING_TEST_PIN, LOW); // 2 clock cycles -#endif - -} - -/* - * The ISR, which calls the interrupt handler - */ -#if defined(TIMER_INTR_NAME) || defined(ISR) -# if defined(TIMER_INTR_NAME) -ISR (TIMER_INTR_NAME) // for ISR definitions -# elif defined(ISR) -ISR() -// for functions definitions which are called by separate (board specific) ISR -# endif -{ - IRReceiveTimerInterruptHandler(); -} -#endif - -/********************************************************************************************************************** - * Stream like API - **********************************************************************************************************************/ -/** - * Initializes the receive and feedback pin - * @param aReceivePin The Arduino pin number, where a demodulating IR receiver is connected. - * @param aEnableLEDFeedback if true / ENABLE_LED_FEEDBACK, then let the feedback led blink on receiving IR signal - * @param aFeedbackLEDPin if 0 / USE_DEFAULT_FEEDBACK_LED_PIN, then take board specific FEEDBACK_LED_ON() and FEEDBACK_LED_OFF() functions - */ -void IRrecv::begin(uint_fast8_t aReceivePin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) { - - setReceivePin(aReceivePin); -#if !defined(NO_LED_FEEDBACK_CODE) - bool tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK; - if (aEnableLEDFeedback) { - tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_RECEIVE; - } - setLEDFeedback(aFeedbackLEDPin, tEnableLEDFeedback); -#else - (void) aEnableLEDFeedback; - (void) aFeedbackLEDPin; -#endif - -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) - pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT); -#endif - start(); -} - -/** - * Sets / changes the receiver pin number - */ -void IRrecv::setReceivePin(uint_fast8_t aReceivePinNumber) { - irparams.IRReceivePin = aReceivePinNumber; -#if defined(__AVR__) - irparams.IRReceivePinMask = digitalPinToBitMask(aReceivePinNumber); - irparams.IRReceivePinPortInputRegister = portInputRegister(digitalPinToPort(aReceivePinNumber)); -#endif - // Set pin mode once. pinModeFast makes no difference here :-( - pinMode(aReceivePinNumber, INPUT); // Seems to be at least required by ESP32 -} - -/** - * Sets the function to call if a protocol message has arrived - */ -void IRrecv::registerReceiveCompleteCallback(void (*aReceiveCompleteCallbackFunction)(void)) { - irparams.ReceiveCompleteCallbackFunction = aReceiveCompleteCallbackFunction; -} - -/** - * Start the receiving process. - * This configures the timer and the state machine for IR reception - * and enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us. - */ -void IRrecv::start() { - - // Setup for cyclic 50 us interrupt - timerConfigForReceive(); // no interrupts enabled here! - - // Initialize state machine state - resume(); - - // Timer interrupt is enabled after state machine reset - timerEnableReceiveInterrupt(); // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us. -#ifdef _IR_MEASURE_TIMING - pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT); -#endif -} -/** - * Alias for start(). - */ -void IRrecv::enableIRIn() { - start(); -} - -/** - * Configures the timer and the state machine for IR reception. - * The tick counter value is already at 100 when decode() gets true, because of the 5000 us minimal gap defined in RECORD_GAP_MICROS. - * @param aMicrosecondsToAddToGapCounter To compensate for the amount of microseconds the timer was stopped / disabled. - */ -void IRrecv::start(uint32_t aMicrosecondsToAddToGapCounter) { - irparams.TickCounterForISR += aMicrosecondsToAddToGapCounter / MICROS_PER_TICK; - start(); -} -void IRrecv::startWithTicksToAdd(uint16_t aTicksToAddToGapCounter) { - irparams.TickCounterForISR += aTicksToAddToGapCounter; - start(); -} - -void IRrecv::addTicksToInternalTickCounter(uint16_t aTicksToAddToInternalTickCounter) { - irparams.TickCounterForISR += aTicksToAddToInternalTickCounter; -} - -void IRrecv::addMicrosToInternalTickCounter(uint16_t aMicrosecondsToAddToInternalTickCounter) { - irparams.TickCounterForISR += aMicrosecondsToAddToInternalTickCounter / MICROS_PER_TICK; -} -/** - * Restarts receiver after send. Is a NOP if sending does not require a timer. - */ -void IRrecv::restartAfterSend() { -#if defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER) - start(); -#endif -} - -/** - * Disables the timer for IR reception. - */ -void IRrecv::stop() { - timerDisableReceiveInterrupt(); -} -/** - * Alias for stop(). - */ -void IRrecv::disableIRIn() { - stop(); -} -/** - * Alias for stop(). - */ -void IRrecv::end() { - stop(); -} - -/** - * Returns status of reception - * @return true if no reception is on-going. - */ -bool IRrecv::isIdle() { - return (irparams.StateForISR == IR_REC_STATE_IDLE || irparams.StateForISR == IR_REC_STATE_STOP) ? true : false; -} - -/** - * Restart the ISR (Interrupt Service Routine) state machine, to enable receiving of the next IR frame - */ -void IRrecv::resume() { - // check allows to call resume at arbitrary places or more than once - if (irparams.StateForISR == IR_REC_STATE_STOP) { - irparams.StateForISR = IR_REC_STATE_IDLE; - } -} - -/** - * Is internally called by decode before calling decoders. - * Must be used to setup data, if you call decoders manually. - */ -void IRrecv::initDecodedIRData() { - - if (irparams.OverflowFlag) { - decodedIRData.flags = IRDATA_FLAGS_WAS_OVERFLOW; -#if defined(LOCAL_DEBUG) - Serial.print(F("Overflow happened, try to increase the \"RAW_BUFFER_LENGTH\" value of ")); - Serial.print(RAW_BUFFER_LENGTH); - Serial.println(F(" with #define RAW_BUFFER_LENGTH=<biggerValue>")); -#endif - - } else { - decodedIRData.flags = IRDATA_FLAGS_EMPTY; - // save last protocol, command and address for repeat handling (where they are compared or copied back :-)) - lastDecodedProtocol = decodedIRData.protocol; // repeat patterns can be equal between protocols (e.g. NEC and LG), so we must keep the original one - lastDecodedCommand = decodedIRData.command; - lastDecodedAddress = decodedIRData.address; - - } - decodedIRData.protocol = UNKNOWN; - decodedIRData.command = 0; - decodedIRData.address = 0; - decodedIRData.decodedRawData = 0; - decodedIRData.numberOfBits = 0; -} - -/** - * Returns true if IR receiver data is available. - */ -bool IRrecv::available() { - return (irparams.StateForISR == IR_REC_STATE_STOP); -} - -/** - * If IR receiver data is available, returns pointer to IrReceiver.decodedIRData, else NULL. - */ -IRData* IRrecv::read() { - if (irparams.StateForISR != IR_REC_STATE_STOP) { - return NULL; - } - if (decode()) { - return &decodedIRData; - } else { - return NULL; - } -} - -/** - * The main decode function, attempts to decode the recently receive IR signal. - * The set of decoders used is determined by active definitions of the DECODE_<PROTOCOL> macros. - * Results of decoding are stored in IrReceiver.decodedIRData.* like e.g. IrReceiver.decodedIRData.command. - * @return false if no IR receiver data available, true if data available. - */ -bool IRrecv::decode() { - if (irparams.StateForISR != IR_REC_STATE_STOP) { - return false; - } - - initDecodedIRData(); // sets IRDATA_FLAGS_WAS_OVERFLOW - - if (decodedIRData.flags & IRDATA_FLAGS_WAS_OVERFLOW) { - /* - * Set OverflowFlag flag and return true here, to let the loop call resume or print raw data. - */ - decodedIRData.protocol = UNKNOWN; - return true; - } - -#if defined(DECODE_NEC) || defined(DECODE_ONKYO) - IR_TRACE_PRINTLN(F("Attempting NEC/Onkyo decode")); - if (decodeNEC()) { - return true; - } -#endif - -#if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO) - IR_TRACE_PRINTLN(F("Attempting Panasonic/Kaseikyo decode")); - if (decodeKaseikyo()) { - return true; - } -#endif - -#if defined(DECODE_DENON) - IR_TRACE_PRINTLN(F("Attempting Denon/Sharp decode")); - if (decodeDenon()) { - return true; - } -#endif - -#if defined(DECODE_SONY) - IR_TRACE_PRINTLN(F("Attempting Sony decode")); - if (decodeSony()) { - return true; - } -#endif - -#if defined(DECODE_RC5) - IR_TRACE_PRINTLN(F("Attempting RC5 decode")); - if (decodeRC5()) { - return true; - } -#endif - -#if defined(DECODE_RC6) - IR_TRACE_PRINTLN(F("Attempting RC6 decode")); - if (decodeRC6()) { - return true; - } -#endif - -#if defined(DECODE_LG) - IR_TRACE_PRINTLN(F("Attempting LG decode")); - if (decodeLG()) { - return true; - } -#endif - -#if defined(DECODE_JVC) - IR_TRACE_PRINTLN(F("Attempting JVC decode")); - if (decodeJVC()) { - return true; - } -#endif - -#if defined(DECODE_SAMSUNG) - IR_TRACE_PRINTLN(F("Attempting Samsung decode")); - if (decodeSamsung()) { - return true; - } -#endif - /* - * Start of the exotic protocols - */ - -#if defined(DECODE_BEO) - IR_TRACE_PRINTLN(F("Attempting Bang & Olufsen decode")); - if (decodeBangOlufsen()) { - return true; - } -#endif - -#if defined(DECODE_FAST) - IR_TRACE_PRINTLN(F("Attempting FAST decode")); - if (decodeFAST()) { - return true; - } -#endif - -#if defined(DECODE_WHYNTER) - IR_TRACE_PRINTLN(F("Attempting Whynter decode")); - if (decodeWhynter()) { - return true; - } -#endif - -#if defined(DECODE_LEGO_PF) - IR_TRACE_PRINTLN(F("Attempting Lego Power Functions")); - if (decodeLegoPowerFunctions()) { - return true; - } -#endif - -#if defined(DECODE_BOSEWAVE) - IR_TRACE_PRINTLN(F("Attempting Bosewave decode")); - if (decodeBoseWave()) { - return true; - } -#endif - -#if defined(DECODE_MAGIQUEST) - IR_TRACE_PRINTLN(F("Attempting MagiQuest decode")); - if (decodeMagiQuest()) { - return true; - } -#endif - - /* - * Try the universal decoder for pulse distance protocols - */ -#if defined(DECODE_DISTANCE_WIDTH) - IR_TRACE_PRINTLN(F("Attempting universal Distance Width decode")); - if (decodeDistanceWidth()) { - return true; - } -#endif - - /* - * Last resort is the universal hash decode which always return true - */ -#if defined(DECODE_HASH) - IR_TRACE_PRINTLN(F("Hash decode")); - // decodeHash returns a hash on any input. - // Thus, it needs to be last in the list. - // If you add any decodes, add them before this. - if (decodeHash()) { - return true; - } -#endif - - /* - * Return true here, to let the loop decide to call resume or to print raw data. - */ - return true; -} - -/********************************************************************************************************************** - * Common decode functions - **********************************************************************************************************************/ -/** - * Decode pulse distance width protocols. - * - * We can have the following protocol timings - * Pulse distance: Pulses/marks are constant, pause/spaces have different length, like NEC. - * Pulse width: Pulses/marks have different length, pause/spaces are constant, like Sony. - * Pulse distance width: Pulses/marks and pause/spaces have different length, often the bit length is constant, like MagiQuest. - * Pulse distance width can be decoded like pulse width decoder, if this decoder does not check the length of pause/spaces. - * - * Input is IrReceiver.decodedIRData.rawDataPtr->rawbuf[] - * Output is IrReceiver.decodedIRData.decodedRawData - * - * Assume pulse distance if aOneMarkMicros == aZeroMarkMicros - * - * @param aNumberOfBits Number of bits to decode from decodedIRData.rawDataPtr->rawbuf[] array. - * @param aStartOffset Offset in decodedIRData.rawDataPtr->rawbuf[] to start decoding. Must point to a mark. - * @param aOneMarkMicros Taken as constant BitMarkMicros for pulse distance. - * @param aZeroMarkMicros Not required if DECODE_STRICT_CHECKS is not defined. - * @param aOneSpaceMicros Taken as (constant) BitSpaceMicros for pulse width. - * @param aZeroSpaceMicros Not required if DECODE_STRICT_CHECKS is not defined. - * @param aMSBfirst If true send Most Significant Bit first, else send Least Significant Bit (lowest bit) first. - * @return true If decoding was successful - */ -bool IRrecv::decodePulseDistanceWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, uint16_t aOneMarkMicros, - uint16_t aZeroMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroSpaceMicros, bool aMSBfirst) { - - auto *tRawBufPointer = &decodedIRData.rawDataPtr->rawbuf[aStartOffset]; - - bool isPulseDistanceProtocol = (aOneMarkMicros == aZeroMarkMicros); // If true, we have a constant mark -> pulse distance protocol - - IRRawDataType tDecodedData = 0; // For MSB first tDecodedData is shifted left each loop - IRRawDataType tMask = 1UL; // Mask is only used for LSB first - - for (uint_fast8_t i = aNumberOfBits; i > 0; i--) { - // get one mark and space pair - unsigned int tMarkTicks; - unsigned int tSpaceTicks; - bool tBitValue; - - if (isPulseDistanceProtocol) { - /* - * Pulse distance here, it is not required to check constant mark duration (aOneMarkMicros) and zero space duration. - */ -#if defined DECODE_STRICT_CHECKS - tMarkTicks = *tRawBufPointer++; -#else - (void) aZeroSpaceMicros; - tRawBufPointer++; -#endif - tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-) - tBitValue = matchSpace(tSpaceTicks, aOneSpaceMicros); // Check for variable length space indicating a 1 or 0 - -#if defined DECODE_STRICT_CHECKS - // Check for constant length mark - if (!matchMark(tMarkTicks, aOneMarkMicros)) { -# if defined(LOCAL_DEBUG) - Serial.print(F("Mark=")); - Serial.print(tMarkTicks * MICROS_PER_TICK); - Serial.print(F(" is not ")); - Serial.print(aOneMarkMicros); - Serial.print(F(". Index=")); - Serial.print(aNumberOfBits - i); - Serial.print(' '); -# endif - return false; - } -#endif - - } else { - /* - * Pulse width here, it is not required to check (constant) space duration and zero mark duration. - */ - tMarkTicks = *tRawBufPointer++; - tBitValue = matchMark(tMarkTicks, aOneMarkMicros); // Check for variable length mark indicating a 1 or 0 - -#if defined DECODE_STRICT_CHECKS - tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-) -#else - (void) aZeroMarkMicros; - (void) aZeroSpaceMicros; - tRawBufPointer++; -#endif - } - - if (aMSBfirst) { - tDecodedData <<= 1; - } - - if (tBitValue) { - // It's a 1 -> set the bit - if (aMSBfirst) { - tDecodedData |= 1; - } else { - tDecodedData |= tMask; - } - IR_TRACE_PRINTLN('1'); - } else { -#if defined DECODE_STRICT_CHECKS - /* - * Additionally check length of length parameter which determine a zero - */ - if (isPulseDistanceProtocol) { - if (!matchSpace(tSpaceTicks, aZeroSpaceMicros)) { -# if defined(LOCAL_DEBUG) - Serial.print(F("Space=")); - Serial.print(tSpaceTicks * MICROS_PER_TICK); - Serial.print(F(" is not ")); - Serial.print(aOneSpaceMicros); - Serial.print(F(" or ")); - Serial.print(aZeroSpaceMicros); - Serial.print(F(". Index=")); - Serial.print(aNumberOfBits - i); - Serial.print(' '); -# endif - return false; - } - } else { - if (!matchMark(tMarkTicks, aZeroMarkMicros)) { -# if defined(LOCAL_DEBUG) - Serial.print(F("Mark=")); - Serial.print(tMarkTicks * MICROS_PER_TICK); - Serial.print(F(" is not ")); - Serial.print(aOneMarkMicros); - Serial.print(F(" or ")); - Serial.print(aZeroMarkMicros); - Serial.print(F(". Index=")); - Serial.print(aNumberOfBits - i); - Serial.print(' '); -# endif - return false; - } - } -#endif - // do not set the bit - IR_TRACE_PRINTLN('0'); - } -#if defined DECODE_STRICT_CHECKS - // If we have no stop bit, assume that last space, which is not recorded, is correct, since we can not check it - if (aZeroSpaceMicros == aOneSpaceMicros - && tRawBufPointer < &decodedIRData.rawDataPtr->rawbuf[decodedIRData.rawDataPtr->rawlen]) { - // Check for constant length space (of pulse width protocol) here - if (!matchSpace(tSpaceTicks, aOneSpaceMicros)) { -# if defined(LOCAL_DEBUG) - Serial.print(F("Space=")); - Serial.print(tSpaceTicks * MICROS_PER_TICK); - Serial.print(F(" is not ")); - Serial.print(aOneSpaceMicros); - Serial.print(F(". Index=")); - Serial.print(aNumberOfBits - i); - Serial.print(' '); -# endif - return false; - } - } -#endif - tMask <<= 1; - } - decodedIRData.decodedRawData = tDecodedData; - return true; -} - -/** - * Decode pulse distance protocols for PulseDistanceWidthProtocolConstants. - * @return true if decoding was successful - */ -bool IRrecv::decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits, - uint_fast8_t aStartOffset) { - - return decodePulseDistanceWidthData(aNumberOfBits, aStartOffset, aProtocolConstants->DistanceWidthTimingInfo.OneMarkMicros, - aProtocolConstants->DistanceWidthTimingInfo.ZeroMarkMicros, aProtocolConstants->DistanceWidthTimingInfo.OneSpaceMicros, - aProtocolConstants->DistanceWidthTimingInfo.ZeroSpaceMicros, aProtocolConstants->Flags); -} - -/* - * Static variables for the getBiphaselevel function - */ -uint_fast8_t sBiphaseDecodeRawbuffOffset; // Index into raw timing array -uint16_t sBiphaseCurrentTimingIntervals; // 1, 2 or 3. Number of aBiphaseTimeUnit intervals of the current rawbuf[sBiphaseDecodeRawbuffOffset] timing. -uint_fast8_t sBiphaseUsedTimingIntervals; // Number of already used intervals of sCurrentTimingIntervals. -uint16_t sBiphaseTimeUnit; - -void IRrecv::initBiphaselevel(uint_fast8_t aRCDecodeRawbuffOffset, uint16_t aBiphaseTimeUnit) { - sBiphaseDecodeRawbuffOffset = aRCDecodeRawbuffOffset; - sBiphaseTimeUnit = aBiphaseTimeUnit; - sBiphaseUsedTimingIntervals = 0; -} - -/** - * Gets the level of one time interval (aBiphaseTimeUnit) at a time from the raw buffer. - * The RC5/6 decoding is easier if the data is broken into time intervals. - * E.g. if the buffer has mark for 2 time intervals and space for 1, - * successive calls to getBiphaselevel will return 1, 1, 0. - * - * _ _ _ _ _ _ _ _ _ _ _ _ _ - * _____| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| | - * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ Significant clock edge - * _ _ _ ___ _ ___ ___ _ - Mark - * Data _____| |___| |_| |_| |_| |___| |___| |_| | - Data starts with a mark->space bit - * 1 0 0 0 1 1 0 1 0 1 1 - Space - * A mark to space at a significant clock edge results in a 1 - * A space to mark at a significant clock edge results in a 0 (for RC6) - * Returns current level [MARK or SPACE] or -1 for error (measured time interval is not a multiple of sBiphaseTimeUnit). - */ -uint_fast8_t IRrecv::getBiphaselevel() { - uint_fast8_t tLevelOfCurrentInterval; // 0 (SPACE) or 1 (MARK) - - if (sBiphaseDecodeRawbuffOffset >= decodedIRData.rawDataPtr->rawlen) { - return SPACE; // After end of recorded buffer, assume space. - } - - tLevelOfCurrentInterval = (sBiphaseDecodeRawbuffOffset) & 1; // on odd rawbuf offsets we have mark timings - - /* - * Setup data if sUsedTimingIntervals is 0 - */ - if (sBiphaseUsedTimingIntervals == 0) { - uint16_t tCurrentTimingWith = decodedIRData.rawDataPtr->rawbuf[sBiphaseDecodeRawbuffOffset]; - uint16_t tMarkExcessCorrection = (tLevelOfCurrentInterval == MARK) ? MARK_EXCESS_MICROS : -MARK_EXCESS_MICROS; - - if (matchTicks(tCurrentTimingWith, sBiphaseTimeUnit + tMarkExcessCorrection)) { - sBiphaseCurrentTimingIntervals = 1; - } else if (matchTicks(tCurrentTimingWith, (2 * sBiphaseTimeUnit) + tMarkExcessCorrection)) { - sBiphaseCurrentTimingIntervals = 2; - } else if (matchTicks(tCurrentTimingWith, (3 * sBiphaseTimeUnit) + tMarkExcessCorrection)) { - sBiphaseCurrentTimingIntervals = 3; - } else { - return -1; - } - } - -// We use another interval from tCurrentTimingIntervals - sBiphaseUsedTimingIntervals++; - -// keep track of current timing offset - if (sBiphaseUsedTimingIntervals >= sBiphaseCurrentTimingIntervals) { - // we have used all intervals of current timing, switch to next timing value - sBiphaseUsedTimingIntervals = 0; - sBiphaseDecodeRawbuffOffset++; - } - - IR_TRACE_PRINTLN(tLevelOfCurrentInterval); - - return tLevelOfCurrentInterval; -} - -#if defined(DECODE_HASH) -/********************************************************************************************************************** - * Internal Hash decode function - **********************************************************************************************************************/ -/** - * Compare two (tick) values for Hash decoder - * Use a tolerance of 20% to enable e.g. 500 and 600 (NEC timing) to be equal - * @return 0 if newval is shorter, 1 if newval is equal, and 2 if newval is longer - */ -uint_fast8_t IRrecv::compare(uint16_t oldval, uint16_t newval) { - if (newval * 10 < oldval * 8) { - return 0; - } - if (oldval * 10 < newval * 8) { - return 2; - } - return 1; -} - -#define FNV_PRIME_32 16777619 ///< used for decodeHash() -#define FNV_BASIS_32 2166136261 ///< used for decodeHash() - -/** - * decodeHash - decode an arbitrary IR code. - * Instead of decoding using a standard encoding scheme - * (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. - * - * The algorithm: look at the sequence of MARK signals, and see if each one - * is shorter (0), the same length (1), or longer (2) than the previous. - * Do the same with the SPACE signals. Hash the resulting sequence of 0's, - * 1's, and 2's to a 32-bit value. This will give a unique value for each - * different code (probably), for most code systems. - * - * Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param - * Converts the raw code values into a 32-bit hash code. - * Hopefully this code is unique for each button. - * This isn't a "real" decoding, just an arbitrary value. - * - * see: http://www.righto.com/2010/01/using-arbitrary-remotes-with-arduino.html - */ -bool IRrecv::decodeHash() { - unsigned long hash = FNV_BASIS_32; // the result is the same no matter if we use a long or unsigned long variable - -// Require at least 6 samples to prevent triggering on noise - if (decodedIRData.rawDataPtr->rawlen < 6) { - return false; - } -#if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR - uint_fast8_t i; -#else - unsigned int i; -#endif - for (i = 1; (i + 2) < decodedIRData.rawDataPtr->rawlen; i++) { - uint_fast8_t value = compare(decodedIRData.rawDataPtr->rawbuf[i], decodedIRData.rawDataPtr->rawbuf[i + 2]); - // Add value into the hash - hash = (hash * FNV_PRIME_32) ^ value; - } - - decodedIRData.decodedRawData = hash; - decodedIRData.numberOfBits = 32; - decodedIRData.protocol = UNKNOWN; - - return true; -} - -bool IRrecv::decodeHashOld(decode_results *aResults) { - unsigned long hash = FNV_BASIS_32; - -// Require at least 6 samples to prevent triggering on noise - if (aResults->rawlen < 6) { - return false; - } - - for (uint8_t i = 3; i < aResults->rawlen; i++) { - uint_fast8_t value = compare(aResults->rawbuf[i - 2], aResults->rawbuf[i]); - // Add value into the hash - hash = (hash * FNV_PRIME_32) ^ value; - } - - aResults->value = hash; - aResults->bits = 32; - aResults->decode_type = UNKNOWN; - decodedIRData.protocol = UNKNOWN; - - return true; -} -#endif // DECODE_HASH - -/********************************************************************************************************************** - * Match functions - **********************************************************************************************************************/ - -/* - * returns true if values do match - */ -bool IRrecv::checkHeader(PulseDistanceWidthProtocolConstants *aProtocolConstants) { -// Check header "mark" and "space" - if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], aProtocolConstants->DistanceWidthTimingInfo.HeaderMarkMicros)) { -#if defined(LOCAL_TRACE) - Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex)); - Serial.println(F(": Header mark length is wrong")); -#endif - return false; - } - if (!matchSpace(decodedIRData.rawDataPtr->rawbuf[2], aProtocolConstants->DistanceWidthTimingInfo.HeaderSpaceMicros)) { -#if defined(LOCAL_TRACE) - Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex)); - Serial.println(F(": Header space length is wrong")); -#endif - return false; - } - return true; -} - -/* - * Do not check for same address and command, because it is almost not possible to press 2 different buttons on the remote within around 100 ms. - * And if really required, it can be enabled here, or done manually in user program. - * And we have still no RC6 toggle bit check for detecting a second press on the same button. - */ -void IRrecv::checkForRepeatSpaceTicksAndSetFlag(uint16_t aMaximumRepeatSpaceTicks) { - if (decodedIRData.rawDataPtr->rawbuf[0] < aMaximumRepeatSpaceTicks -#if defined(ENABLE_FULL_REPEAT_CHECK) - && decodedIRData.address == lastDecodedAddress && decodedIRData.command == lastDecodedCommand /* requires around 85 bytes program space */ -#endif - ) { - decodedIRData.flags |= IRDATA_FLAGS_IS_REPEAT; - } -} - -/** - * Match function without compensating for marks exceeded or spaces shortened by demodulator hardware - * Currently not used - */ -bool matchTicks(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) { -#if defined(LOCAL_TRACE) - Serial.print(F("Testing: ")); - Serial.print(TICKS_LOW(aMatchValueMicros), DEC); - Serial.print(F(" <= ")); - Serial.print(aMeasuredTicks, DEC); - Serial.print(F(" <= ")); - Serial.print(TICKS_HIGH(aMatchValueMicros), DEC); -#endif - bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros)) && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros))); -#if defined(LOCAL_TRACE) - if (passed) { - Serial.println(F(" => passed")); - } else { - Serial.println(F(" => FAILED")); - } -#endif - return passed; -} - -bool MATCH(uint16_t measured_ticks, uint16_t desired_us) { - return matchTicks(measured_ticks, desired_us); -} - -/** - * Compensate for marks exceeded by demodulator hardware - */ -bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) { -#if defined(LOCAL_TRACE) - Serial.print(F("Testing mark (actual vs desired): ")); - Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC); - Serial.print(F("us vs ")); - Serial.print(aMatchValueMicros, DEC); - Serial.print(F("us: ")); - Serial.print(TICKS_LOW(aMatchValueMicros + MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC); - Serial.print(F(" <= ")); - Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC); - Serial.print(F(" <= ")); - Serial.print(TICKS_HIGH(aMatchValueMicros + MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC); -#endif - // compensate for marks exceeded by demodulator hardware - bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros + MARK_EXCESS_MICROS)) - && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros + MARK_EXCESS_MICROS))); -#if defined(LOCAL_TRACE) - if (passed) { - Serial.println(F(" => passed")); - } else { - Serial.println(F(" => FAILED")); - } -#endif - return passed; -} - -bool MATCH_MARK(uint16_t measured_ticks, uint16_t desired_us) { - return matchMark(measured_ticks, desired_us); -} - -/** - * Compensate for spaces shortened by demodulator hardware - */ -bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) { -#if defined(LOCAL_TRACE) - Serial.print(F("Testing space (actual vs desired): ")); - Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC); - Serial.print(F("us vs ")); - Serial.print(aMatchValueMicros, DEC); - Serial.print(F("us: ")); - Serial.print(TICKS_LOW(aMatchValueMicros - MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC); - Serial.print(F(" <= ")); - Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC); - Serial.print(F(" <= ")); - Serial.print(TICKS_HIGH(aMatchValueMicros - MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC); -#endif - // compensate for spaces shortened by demodulator hardware - bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros - MARK_EXCESS_MICROS)) - && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros - MARK_EXCESS_MICROS))); -#if defined(LOCAL_TRACE) - if (passed) { - Serial.println(F(" => passed")); - } else { - Serial.println(F(" => FAILED")); - } -#endif - return passed; -} - -bool MATCH_SPACE(uint16_t measured_ticks, uint16_t desired_us) { - return matchSpace(measured_ticks, desired_us); -} - -/** - * Getter function for MARK_EXCESS_MICROS - */ -int getMarkExcessMicros() { - return MARK_EXCESS_MICROS; -} - -/* - * Check if protocol is not detected and detected space between two transmissions - * is smaller than known value for protocols (Sony with around 24 ms) - * @return true, if CheckForRecordGapsMicros() has printed a message, i.e. gap < 15ms (RECORD_GAP_MICROS_WARNING_THRESHOLD) - */ -bool IRrecv::checkForRecordGapsMicros(Print *aSerial) { - /* - * Check if protocol is not detected and detected space between two transmissions - * is smaller than known value for protocols (Sony with around 24 ms) - */ - if (decodedIRData.protocol <= PULSE_DISTANCE - && decodedIRData.rawDataPtr->rawbuf[0] < (RECORD_GAP_MICROS_WARNING_THRESHOLD / MICROS_PER_TICK)) { - aSerial->println(); - aSerial->print(F("Space of ")); - aSerial->print(decodedIRData.rawDataPtr->rawbuf[0] * MICROS_PER_TICK); - aSerial->print(F(" us between two detected transmission is smaller than the minimal gap of ")); - aSerial->print(RECORD_GAP_MICROS_WARNING_THRESHOLD); - aSerial->println(F(" us known for implemented protocols like NEC, Sony, RC% etc..")); - aSerial->println(F("But it can be OK for some yet unsupported protocols, and especially for repeats.")); - aSerial->println(F("If you get unexpected results, try to increase the RECORD_GAP_MICROS in IRremote.h.")); - aSerial->println(); - return true; - } - return false; -} - -/********************************************************************************************************************** - * Print functions - * Since a library should not allocate the "Serial" object, all functions require a pointer to a Print object. - **********************************************************************************************************************/ -void IRrecv::printActiveIRProtocols(Print *aSerial) { -// call no class function with same name - ::printActiveIRProtocols(aSerial); -} -void printActiveIRProtocols(Print *aSerial) { -#if defined(DECODE_ONKYO) - aSerial->print(F("Onkyo, ")); -#elif defined(DECODE_NEC) - aSerial->print(F("NEC/NEC2/Onkyo/Apple, ")); -#endif -#if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO) - aSerial->print(F("Panasonic/Kaseikyo, ")); -#endif -#if defined(DECODE_DENON) - aSerial->print(F("Denon/Sharp, ")); -#endif -#if defined(DECODE_SONY) - aSerial->print(F("Sony, ")); -#endif -#if defined(DECODE_RC5) - aSerial->print(F("RC5, ")); -#endif -#if defined(DECODE_RC6) - aSerial->print(F("RC6, ")); -#endif -#if defined(DECODE_LG) - aSerial->print(F("LG, ")); -#endif -#if defined(DECODE_JVC) - aSerial->print(F("JVC, ")); -#endif -#if defined(DECODE_SAMSUNG) - aSerial->print(F("Samsung, ")); -#endif - /* - * Start of the exotic protocols - */ -#if defined(DECODE_BEO) - aSerial->print(F("Bang & Olufsen, ")); -#endif -#if defined(DECODE_FAST) - aSerial->print(F("FAST, ")); -#endif -#if defined(DECODE_WHYNTER) - aSerial->print(F("Whynter, ")); -#endif -#if defined(DECODE_LEGO_PF) - aSerial->print(F("Lego Power Functions, ")); -#endif -#if defined(DECODE_BOSEWAVE) - aSerial->print(F("Bosewave , ")); -#endif -#if defined(DECODE_MAGIQUEST) - aSerial->print(F("MagiQuest, ")); -#endif -#if defined(DECODE_DISTANCE_WIDTH) - aSerial->print(F("Universal Pulse Distance Width, ")); -#endif -#if defined(DECODE_HASH) - aSerial->print(F("Hash ")); -#endif -#if defined(NO_DECODER) // for sending raw only - (void)aSerial; // to avoid compiler warnings -#endif -} - -/** - * Function to print values and flags of IrReceiver.decodedIRData in one line. - * Ends with println(). - * - * @param aSerial The Print object on which to write, for Arduino you can use &Serial. - * @param aPrintRepeatGap If true also print the gap before repeats. - * @param aCheckForRecordGapsMicros If true, call CheckForRecordGapsMicros() which may do a long printout, - * which in turn may block the proper detection of repeats.* - * @return true, if CheckForRecordGapsMicros() has printed a message, i.e. gap < 15ms (RECORD_GAP_MICROS_WARNING_THRESHOLD). - */ -bool IRrecv::printIRResultShort(Print *aSerial, bool aPrintRepeatGap, bool aCheckForRecordGapsMicros) { -// call no class function with same name - ::printIRResultShort(aSerial, &decodedIRData, aPrintRepeatGap); - if (aCheckForRecordGapsMicros && decodedIRData.protocol != UNKNOWN) { - return checkForRecordGapsMicros(aSerial); - } - return false; -} - -void IRrecv::printDistanceWidthTimingInfo(Print *aSerial, DistanceWidthTimingInfoStruct *aDistanceWidthTimingInfo) { - aSerial->print(aDistanceWidthTimingInfo->HeaderMarkMicros); - aSerial->print(F(", ")); - aSerial->print(aDistanceWidthTimingInfo->HeaderSpaceMicros); - aSerial->print(F(", ")); - aSerial->print(aDistanceWidthTimingInfo->OneMarkMicros); - aSerial->print(F(", ")); - aSerial->print(aDistanceWidthTimingInfo->OneSpaceMicros); - aSerial->print(F(", ")); - aSerial->print(aDistanceWidthTimingInfo->ZeroMarkMicros); - aSerial->print(F(", ")); - aSerial->print(aDistanceWidthTimingInfo->ZeroSpaceMicros); -} - -uint32_t IRrecv::getTotalDurationOfRawData() { - uint16_t tSumOfDurationTicks = 0; - for (uint_fast8_t i = 1; i < decodedIRData.rawDataPtr->rawlen; i++) { - tSumOfDurationTicks += decodedIRData.rawDataPtr->rawbuf[i]; - } - return tSumOfDurationTicks * (uint32_t) MICROS_PER_TICK; -} - -/** - * Function to print values and flags of IrReceiver.decodedIRData in one line. - * Ends with println(). - * - * @param aSerial The Print object on which to write, for Arduino you can use &Serial. - */ -void IRrecv::printIRSendUsage(Print *aSerial) { - if (decodedIRData.protocol != UNKNOWN - && (decodedIRData.flags & (IRDATA_FLAGS_IS_AUTO_REPEAT | IRDATA_FLAGS_IS_REPEAT)) == 0x00) { -#if defined(DECODE_DISTANCE_WIDTH) - aSerial->print(F("Send with:")); - uint_fast8_t tNumberOfArrayData = 0; - if (decodedIRData.protocol == PULSE_DISTANCE || decodedIRData.protocol == PULSE_WIDTH) { -# if __INT_WIDTH__ < 32 - tNumberOfArrayData = ((decodedIRData.numberOfBits - 1) / 32) + 1; - if(tNumberOfArrayData > 1) { - aSerial->println(); - aSerial->print(F(" uint32_t tRawData[]={0x")); -# else - tNumberOfArrayData = ((decodedIRData.numberOfBits - 1) / 64) + 1; - if(tNumberOfArrayData > 1) { - aSerial->println(); - aSerial->print(F(" uint64_t tRawData[]={0x")); -# endif - for (uint_fast8_t i = 0; i < tNumberOfArrayData; ++i) { -# if (__INT_WIDTH__ < 32) - aSerial->print(decodedIRData.decodedRawDataArray[i], HEX); -# else - PrintULL::print(aSerial, decodedIRData.decodedRawDataArray[i], HEX); -# endif - if (i != tNumberOfArrayData - 1) { - aSerial->print(F(", 0x")); - } - } - aSerial->println(F("};")); - aSerial->print(F(" ")); - } - } - aSerial->print(F(" IrSender.send")); -#else - aSerial->print(F("Send with: IrSender.send")); -#endif - -#if defined(DECODE_DISTANCE_WIDTH) - if (decodedIRData.protocol != PULSE_DISTANCE && decodedIRData.protocol != PULSE_WIDTH) { -#endif - aSerial->print(getProtocolString()); - aSerial->print(F("(0x")); -#if defined(DECODE_MAGIQUEST) - if (decodedIRData.protocol == MAGIQUEST) { -# if (__INT_WIDTH__ < 32) - aSerial->print(decodedIRData.decodedRawData, HEX); -# else - PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX); -# endif - } else { - aSerial->print(decodedIRData.address, HEX); - } -#else - /* - * New decoders have address and command - */ - aSerial->print(decodedIRData.address, HEX); -#endif - - aSerial->print(F(", 0x")); - aSerial->print(decodedIRData.command, HEX); - if (decodedIRData.protocol == SONY) { - aSerial->print(F(", 2, ")); - aSerial->print(decodedIRData.numberOfBits); - } else { - aSerial->print(F(", <numberOfRepeats>")); - } - -#if defined(DECODE_DISTANCE_WIDTH) - } else { - /* - * Pulse distance or pulse width here - */ - aSerial->print("PulseDistanceWidth"); - if(tNumberOfArrayData > 1) { - aSerial->print("FromArray(38, "); - } else { - aSerial->print("(38, "); - } - printDistanceWidthTimingInfo(aSerial, &decodedIRData.DistanceWidthTimingInfo); - - if(tNumberOfArrayData > 1) { - aSerial->print(F(", &tRawData[0], ")); - } else { - aSerial->print(F(", 0x")); -# if (__INT_WIDTH__ < 32) - aSerial->print(decodedIRData.decodedRawData, HEX); -# else - PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX); -# endif - aSerial->print(F(", ")); - } - aSerial->print(decodedIRData.numberOfBits);// aNumberOfBits - aSerial->print(F(", PROTOCOL_IS_")); - - if (decodedIRData.flags & IRDATA_FLAGS_IS_MSB_FIRST) { - aSerial->print('M'); - } else { - aSerial->print('L'); - } - aSerial->print(F("SB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>")); - } -#endif -#if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO) - if ((decodedIRData.flags & IRDATA_FLAGS_EXTRA_INFO) && decodedIRData.protocol == KASEIKYO) { - aSerial->print(F(", 0x")); - aSerial->print(decodedIRData.extra, HEX); - } -#endif - aSerial->print(F(");")); - aSerial->println(); - } -} - -/** - * Function to print protocol number, address, command, raw data and repeat flag of IrReceiver.decodedIRData in one short line. - * Does not print a Newline / does not end with println(). - * - * @param aSerial The Print object on which to write, for Arduino you can use &Serial. - */ -void IRrecv::printIRResultMinimal(Print *aSerial) { - aSerial->print(F("P=")); - aSerial->print(decodedIRData.protocol); - if (decodedIRData.protocol == UNKNOWN) { -#if defined(DECODE_HASH) - aSerial->print(F(" #=0x")); -# if (__INT_WIDTH__ < 32) - aSerial->print(decodedIRData.decodedRawData, HEX); -# else - PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX); -# endif -#endif - aSerial->print(' '); - aSerial->print((decodedIRData.rawDataPtr->rawlen + 1) / 2, DEC); - aSerial->println(F(" bits received")); - } else { - /* - * New decoders have address and command - */ - aSerial->print(F(" A=0x")); - aSerial->print(decodedIRData.address, HEX); - - aSerial->print(F(" C=0x")); - aSerial->print(decodedIRData.command, HEX); - - aSerial->print(F(" Raw=0x")); -#if (__INT_WIDTH__ < 32) - aSerial->print(decodedIRData.decodedRawData, HEX); -#else - PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX); -#endif - - if (decodedIRData.flags & (IRDATA_FLAGS_IS_AUTO_REPEAT | IRDATA_FLAGS_IS_REPEAT)) { - aSerial->print(F(" R")); - } - } -} - -/** - * Dump out the timings in IrReceiver.decodedIRData.rawDataPtr->rawbuf[] array 8 values per line. - * - * @param aSerial The Print object on which to write, for Arduino you can use &Serial. - * @param aOutputMicrosecondsInsteadOfTicks Output the (rawbuf_values * MICROS_PER_TICK) for better readability. - */ -void IRrecv::printIRResultRawFormatted(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks) { - - uint8_t tRawlen = decodedIRData.rawDataPtr->rawlen; // Get it once here in order to print quite consistent data, even if ISR is running -// Print Raw data - aSerial->print(F("rawData[")); - aSerial->print(tRawlen, DEC); - aSerial->println(F("]: ")); - - /* - * Print initial gap - */ - aSerial->print(F(" -")); - if (aOutputMicrosecondsInsteadOfTicks) { - aSerial->println((uint32_t) decodedIRData.rawDataPtr->rawbuf[0] * MICROS_PER_TICK, DEC); - } else { - aSerial->println(decodedIRData.rawDataPtr->rawbuf[0], DEC); - } -#if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR - uint_fast8_t i; -#else - unsigned int i; -#endif - -// Newline is printed every 8. value, if tCounterForNewline % 8 == 0 - uint_fast8_t tCounterForNewline = 6; // first newline is after the 2 values of the start bit - -// check if we have a protocol with no or 8 start bits -#if defined(DECODE_DENON) || defined(DECODE_MAGIQUEST) - if ( -# if defined(DECODE_DENON) - decodedIRData.protocol == DENON || decodedIRData.protocol == SHARP || -# endif -# if defined(DECODE_MAGIQUEST) - decodedIRData.protocol == MAGIQUEST || -# endif - false) { - tCounterForNewline = 0; // no or 8 start bits - } -#endif - - uint32_t tDuration; - uint16_t tSumOfDurationTicks = 0; - for (i = 1; i < tRawlen; i++) { - auto tCurrentTicks = decodedIRData.rawDataPtr->rawbuf[i]; - if (aOutputMicrosecondsInsteadOfTicks) { - tDuration = tCurrentTicks * MICROS_PER_TICK; - } else { - tDuration = tCurrentTicks; - } - tSumOfDurationTicks += tCurrentTicks; // compute length of protocol frame - - if (!(i & 1)) { // even - aSerial->print('-'); - } else { // odd - aSerial->print(F(" +")); - } - - // padding only for big values - if (aOutputMicrosecondsInsteadOfTicks && tDuration < 1000) { - aSerial->print(' '); - } - if (aOutputMicrosecondsInsteadOfTicks && tDuration < 100) { - aSerial->print(' '); - } - if (tDuration < 10) { - aSerial->print(' '); - } - aSerial->print(tDuration, DEC); - - if ((i & 1) && (i + 1) < tRawlen) { - aSerial->print(','); //',' not required for last one - } - - tCounterForNewline++; - if ((tCounterForNewline % 8) == 0) { - aSerial->println(); - } - } - - aSerial->println(); - aSerial->print("Sum: "); - if (aOutputMicrosecondsInsteadOfTicks) { - aSerial->println((uint32_t) tSumOfDurationTicks * MICROS_PER_TICK, DEC); - } else { - aSerial->println(tSumOfDurationTicks, DEC); - } -} - -/** - * Dump out the IrReceiver.decodedIRData.rawDataPtr->rawbuf[] to be used as C definition for sendRaw(). - * - * Compensate received values by MARK_EXCESS_MICROS, like it is done for decoding! - * Print ticks in 8 bit format to save space. - * Maximum is 255*50 microseconds = 12750 microseconds = 12.75 ms, which hardly ever occurs inside an IR sequence. - * Recording of IRremote anyway stops at a gap of RECORD_GAP_MICROS (5 ms). - * - * @param aSerial The Print object on which to write, for Arduino you can use &Serial. - * @param aOutputMicrosecondsInsteadOfTicks Output the (rawbuf_values * MICROS_PER_TICK) for better readability. - */ -void IRrecv::compensateAndPrintIRResultAsCArray(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks) { -// Start declaration - if (aOutputMicrosecondsInsteadOfTicks) { - aSerial->print(F("uint16_t rawData[")); // variable type, array name - } else { - aSerial->print(F("uint8_t rawTicks[")); // variable type, array name - } - - aSerial->print(decodedIRData.rawDataPtr->rawlen - 1, DEC); // array size - aSerial->print(F("] = {")); // Start declaration - -// Dump data -#if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR - uint_fast8_t i; -#else - unsigned int i; -#endif - for (i = 1; i < decodedIRData.rawDataPtr->rawlen; i++) { - uint32_t tDuration = decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK; - - if (i & 1) { - // Mark - tDuration -= MARK_EXCESS_MICROS; - } else { - tDuration += MARK_EXCESS_MICROS; - } - - if (aOutputMicrosecondsInsteadOfTicks) { - aSerial->print(tDuration); - } else { - unsigned int tTicks = (tDuration + (MICROS_PER_TICK / 2)) / MICROS_PER_TICK; - /* - * Clip to 8 bit value - */ - tTicks = (tTicks > UINT8_MAX) ? UINT8_MAX : tTicks; - aSerial->print(tTicks); - } - if (i + 1 < decodedIRData.rawDataPtr->rawlen) - aSerial->print(','); // ',' not required on last one - if (!(i & 1)) - aSerial->print(' '); - } - -// End declaration - aSerial->print(F("};")); // - -// Comment - aSerial->print(F(" // ")); - printIRResultShort(aSerial); - -// Newline - aSerial->println(""); -} - -/** - * Store the decodedIRData to be used for sendRaw(). - * - * Compensate received values by MARK_EXCESS_MICROS, like it is done for decoding and store it in an array provided. - * - * Maximum for uint8_t is 255*50 microseconds = 12750 microseconds = 12.75 ms, which hardly ever occurs inside an IR sequence. - * Recording of IRremote anyway stops at a gap of RECORD_GAP_MICROS (5 ms). - * @param aArrayPtr Address of an array provided by the caller. - */ -void IRrecv::compensateAndStoreIRResultInArray(uint8_t *aArrayPtr) { - -// Store data, skip leading space# -#if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR - uint_fast8_t i; -#else - unsigned int i; -#endif - for (i = 1; i < decodedIRData.rawDataPtr->rawlen; i++) { - uint32_t tDuration = decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK; - if (i & 1) { - // Mark - tDuration -= MARK_EXCESS_MICROS; - } else { - tDuration += MARK_EXCESS_MICROS; - } - - unsigned int tTicks = (tDuration + (MICROS_PER_TICK / 2)) / MICROS_PER_TICK; - *aArrayPtr = (tTicks > UINT8_MAX) ? UINT8_MAX : tTicks; // we store it in an 8 bit array - aArrayPtr++; - } -} - -/** - * Print results as C variables to be used for sendXXX() - * @param aSerial The Print object on which to write, for Arduino you can use &Serial. - */ -void IRrecv::printIRResultAsCVariables(Print *aSerial) { -// Now dump "known" codes - if (decodedIRData.protocol != UNKNOWN) { - - /* - * New decoders have address and command - */ - aSerial->print(F("uint16_t")); - aSerial->print(F(" address = 0x")); - aSerial->print(decodedIRData.address, HEX); - aSerial->println(';'); - - aSerial->print(F("uint16_t")); - aSerial->print(F(" command = 0x")); - aSerial->print(decodedIRData.command, HEX); - aSerial->println(';'); - - // All protocols have raw data -#if __INT_WIDTH__ < 32 - aSerial->print(F("uint32_t rawData = 0x")); -#else - aSerial->print(F("uint64_t rawData = 0x")); -#endif -#if (__INT_WIDTH__ < 32) - aSerial->print(decodedIRData.decodedRawData, HEX); -#else - PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX); -#endif - aSerial->println(';'); - aSerial->println(); - } -} - -#if defined(__AVR__) -const __FlashStringHelper* IRrecv::getProtocolString() { -// call no class function with same name - return ::getProtocolString(decodedIRData.protocol); -} -#else -const char* IRrecv::getProtocolString() { - // call no class function with same name - return ::getProtocolString(decodedIRData.protocol); -} -#endif - -/********************************************************************************************************************** - * The OLD and DEPRECATED decode function with parameter aResults, kept for backward compatibility to old 2.0 tutorials - * This function calls the old MSB first decoders and fills only the 3 variables: - * aResults->value - * aResults->bits - * aResults->decode_type - **********************************************************************************************************************/ -bool IRrecv::decode_old(decode_results *aResults) { - - if (irparams.StateForISR != IR_REC_STATE_STOP) { - return false; - } - -// copy for usage by legacy programs - aResults->rawbuf = irparams.rawbuf; - aResults->rawlen = irparams.rawlen; - if (irparams.OverflowFlag) { - // Copy overflow flag to decodedIRData.flags - irparams.OverflowFlag = false; - irparams.rawlen = 0; // otherwise we have OverflowFlag again at next ISR call - IR_DEBUG_PRINTLN(F("Overflow happened")); - } - aResults->overflow = irparams.OverflowFlag; - aResults->value = 0; - - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; // for print - -#if defined(DECODE_NEC) - IR_DEBUG_PRINTLN(F("Attempting old NEC decode")); - if (decodeNECMSB(aResults)) { - return true; - } -#endif - -#if defined(DECODE_SONY) - IR_DEBUG_PRINTLN(F("Attempting old Sony decode")); - if (decodeSonyMSB(aResults)) { - return true; - } -#endif - -#if defined(DECODE_RC5) - IR_DEBUG_PRINTLN(F("Attempting RC5 decode")); - if (decodeRC5()) { - aResults->bits = decodedIRData.numberOfBits; - aResults->value = decodedIRData.decodedRawData; - aResults->decode_type = RC5; - - return true; - } -#endif - -#if defined(DECODE_RC6) - IR_DEBUG_PRINTLN(F("Attempting RC6 decode")); - if (decodeRC6()) { - aResults->bits = decodedIRData.numberOfBits; - aResults->value = decodedIRData.decodedRawData; - aResults->decode_type = RC6; - return true; - } -#endif - -// Removed bool IRrecv::decodePanasonicMSB(decode_results *aResults) since implementations was wrong (wrong length), and nobody recognized it - -#if defined(DECODE_LG) - IR_DEBUG_PRINTLN(F("Attempting old LG decode")); - if (decodeLGMSB(aResults)) {return true;} -#endif - -#if defined(DECODE_JVC) - IR_DEBUG_PRINTLN(F("Attempting old JVC decode")); - if (decodeJVCMSB(aResults)) { - return true; - } -#endif - -#if defined(DECODE_SAMSUNG) - IR_DEBUG_PRINTLN(F("Attempting old SAMSUNG decode")); - if (decodeSAMSUNG(aResults)) { - return true; - } -#endif - -#if defined(DECODE_DENON) - IR_DEBUG_PRINTLN(F("Attempting old Denon decode")); - if (decodeDenonOld(aResults)) { - return true; - } -#endif - -// decodeHash returns a hash on any input. -// Thus, it needs to be last in the list. -// If you add any decodes, add them before this. - if (decodeHashOld(aResults)) { - return true; - } -// Throw away and start over - resume(); - return false; -} - -/** @}*/ -#if defined(_IR_MEASURE_TIMING) -#undef _IR_MEASURE_TIMING -#endif -#if defined(LOCAL_TRACE) -#undef LOCAL_TRACE -#endif -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_RECEIVE_HPP diff --git a/IRremote/src/IRSend.hpp b/IRremote/src/IRSend.hpp deleted file mode 100644 index 70881469826840e6755922944f3591b4aa042584..0000000000000000000000000000000000000000 --- a/IRremote/src/IRSend.hpp +++ /dev/null @@ -1,1242 +0,0 @@ -/* - * IRSend.hpp - * - * Contains common functions for sending - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2009-2023 Ken Shirriff, Rafi Khan, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_SEND_HPP -#define _IR_SEND_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -#if defined(TRACE) && !defined(LOCAL_TRACE) -#define LOCAL_TRACE -#else -//#define LOCAL_TRACE // This enables debug output only for this file -#endif - -/* - * Low level hardware timing measurement - */ -//#define _IR_MEASURE_TIMING // for mark() -//#define _IR_TIMING_TEST_PIN 7 // "pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);" is executed at begin() -// -/* - * This improves readability of code by avoiding a lot of #if defined clauses - */ -#if defined(IR_SEND_PIN) -#define sendPin IR_SEND_PIN -#endif - -/** \addtogroup Sending Sending IR data for multiple protocols - * @{ - */ - -// The sender instance -IRsend IrSender; - -IRsend::IRsend() { // @suppress("Class members should be properly initialized") -#if !defined(IR_SEND_PIN) - sendPin = 0; -#endif - -#if !defined(NO_LED_FEEDBACK_CODE) - setLEDFeedback(0, DO_NOT_ENABLE_LED_FEEDBACK); -#endif -} - -#if defined(IR_SEND_PIN) -/** - * Only required to set LED feedback - * Simple start with defaults - LED feedback enabled! Used if IR_SEND_PIN is defined. Saves program memory. - */ -void IRsend::begin(){ -# if !defined(NO_LED_FEEDBACK_CODE) - setLEDFeedback(USE_DEFAULT_FEEDBACK_LED_PIN, LED_FEEDBACK_ENABLED_FOR_SEND); -# endif -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) - pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT); -#endif -} - -/** - * Only required to set LED feedback - * @param aEnableLEDFeedback If true / ENABLE_LED_FEEDBACK, the feedback LED is activated while receiving or sending a PWM signal /a mark - * @param aFeedbackLEDPin If 0 / USE_DEFAULT_FEEDBACK_LED_PIN, then take board specific FEEDBACK_LED_ON() and FEEDBACK_LED_OFF() functions - */ -void IRsend::begin(bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) { -#if !defined(NO_LED_FEEDBACK_CODE) - bool tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK; - if(aEnableLEDFeedback) { - tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_SEND; - } - setLEDFeedback(aFeedbackLEDPin, tEnableLEDFeedback); -#else - (void) aEnableLEDFeedback; - (void) aFeedbackLEDPin; -#endif -} - -#else // defined(IR_SEND_PIN) -IRsend::IRsend(uint_fast8_t aSendPin) { // @suppress("Class members should be properly initialized") - sendPin = aSendPin; -# if !defined(NO_LED_FEEDBACK_CODE) - setLEDFeedback(0, DO_NOT_ENABLE_LED_FEEDBACK); -# endif -} - -/** - * Initializes the send pin and enable LED feedback with board specific FEEDBACK_LED_ON() and FEEDBACK_LED_OFF() functions - * @param aSendPin The Arduino pin number, where a IR sender diode is connected. - */ -void IRsend::begin(uint_fast8_t aSendPin) { - sendPin = aSendPin; -# if !defined(NO_LED_FEEDBACK_CODE) - setLEDFeedback(USE_DEFAULT_FEEDBACK_LED_PIN, LED_FEEDBACK_ENABLED_FOR_SEND); -# endif -} - -void IRsend::setSendPin(uint_fast8_t aSendPin) { - sendPin = aSendPin; -} - -/** - * Initializes the send and feedback pin - * @param aSendPin The Arduino pin number, where a IR sender diode is connected. - * @param aEnableLEDFeedback If true the feedback LED is activated while receiving or sending a PWM signal /a mark - * @param aFeedbackLEDPin If 0 / USE_DEFAULT_FEEDBACK_LED_PIN, then take board specific FEEDBACK_LED_ON() and FEEDBACK_LED_OFF() functions - */ -void IRsend::begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) { -#if defined(IR_SEND_PIN) - (void) aSendPin; // for backwards compatibility -#else - sendPin = aSendPin; -#endif - -#if !defined(NO_LED_FEEDBACK_CODE) - bool tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK; - if (aEnableLEDFeedback) { - tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_SEND; - } - setLEDFeedback(aFeedbackLEDPin, tEnableLEDFeedback); -#else - (void) aEnableLEDFeedback; - (void) aFeedbackLEDPin; -#endif -} -#endif // defined(IR_SEND_PIN) - -/** - * Interprets and sends a IRData structure. - * @param aIRSendData The values of protocol, address, command and repeat flag are taken for sending. - * @param aNumberOfRepeats Number of repeats to send after the initial data if data is no repeat. - * @return 1 if data sent, 0 if no data sent (i.e. for BANG_OLUFSEN, which is currently not supported here) - */ -/** - * Interprets and sends a IRData structure. - * @param aIRSendData The values of protocol, address, command and repeat flag are taken for sending. - * @param aNumberOfRepeats Number of repeats to send after the initial data if data is no repeat. - * @return 1 if data sent, 0 if no data sent (i.e. for BANG_OLUFSEN, which is currently not supported here) - */ -size_t IRsend::write(IRData *aIRSendData, int_fast8_t aNumberOfRepeats) { - - auto tProtocol = aIRSendData->protocol; - auto tAddress = aIRSendData->address; - auto tCommand = aIRSendData->command; - bool tIsRepeat = (aIRSendData->flags & IRDATA_FLAGS_IS_REPEAT); - if (tIsRepeat) { - aNumberOfRepeats = -1; // if aNumberOfRepeats < 0 then only a special repeat frame will be sent - } -// switch (tProtocol) { // 26 bytes bigger than if, else if, else -// case NEC: -// sendNEC(tAddress, tCommand, aNumberOfRepeats, tSendRepeat); -// break; -// case SAMSUNG: -// sendSamsung(tAddress, tCommand, aNumberOfRepeats); -// break; -// case SONY: -// sendSony(tAddress, tCommand, aNumberOfRepeats, aIRSendData->numberOfBits); -// break; -// case PANASONIC: -// sendPanasonic(tAddress, tCommand, aNumberOfRepeats); -// break; -// case DENON: -// sendDenon(tAddress, tCommand, aNumberOfRepeats); -// break; -// case SHARP: -// sendSharp(tAddress, tCommand, aNumberOfRepeats); -// break; -// case JVC: -// sendJVC((uint8_t) tAddress, (uint8_t) tCommand, aNumberOfRepeats); // casts are required to specify the right function -// break; -// case RC5: -// sendRC5(tAddress, tCommand, aNumberOfRepeats, !tSendRepeat); // No toggle for repeats -// break; -// case RC6: -// // No toggle for repeats// sendRC6(tAddress, tCommand, aNumberOfRepeats, !tSendRepeat); // No toggle for repeats -// break; -// default: -// break; -// } - - /* - * Order of protocols is in guessed relevance :-) - */ - if (tProtocol == NEC) { - sendNEC(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == SAMSUNG) { - sendSamsung(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == SAMSUNG48) { - sendSamsung48(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == SAMSUNG_LG) { - sendSamsungLG(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == SONY) { - sendSony(tAddress, tCommand, aNumberOfRepeats, aIRSendData->numberOfBits); - - } else if (tProtocol == PANASONIC) { - sendPanasonic(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == DENON) { - sendDenon(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == SHARP) { - sendSharp(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == LG) { - sendLG(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == JVC) { - sendJVC((uint8_t) tAddress, (uint8_t) tCommand, aNumberOfRepeats); // casts are required to specify the right function - - } else if (tProtocol == RC5) { - sendRC5(tAddress, tCommand, aNumberOfRepeats, !tIsRepeat); // No toggle for repeats - - } else if (tProtocol == RC6) { - sendRC6(tAddress, tCommand, aNumberOfRepeats, !tIsRepeat); // No toggle for repeats - - } else if (tProtocol == KASEIKYO_JVC) { - sendKaseikyo_JVC(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == KASEIKYO_DENON) { - sendKaseikyo_Denon(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == KASEIKYO_SHARP) { - sendKaseikyo_Sharp(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == KASEIKYO_MITSUBISHI) { - sendKaseikyo_Mitsubishi(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == NEC2) { - sendNEC2(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == ONKYO) { - sendOnkyo(tAddress, tCommand, aNumberOfRepeats); - - } else if (tProtocol == APPLE) { - sendApple(tAddress, tCommand, aNumberOfRepeats); - -#if !defined(EXCLUDE_EXOTIC_PROTOCOLS) - } else if (tProtocol == BOSEWAVE) { - sendBoseWave(tCommand, aNumberOfRepeats); - - } else if (tProtocol == MAGIQUEST) { - // we have a 32 bit ID/address - sendMagiQuest(aIRSendData->decodedRawData, tCommand); - - } else if (tProtocol == FAST) { - // We have only 8 bit command - sendFAST(tCommand, aNumberOfRepeats); - - } else if (tProtocol == LEGO_PF) { - sendLegoPowerFunctions(tAddress, tCommand, tCommand >> 4, tIsRepeat); // send 5 autorepeats -#endif - - } else { - return 0; // Not supported by write. E.g for BANG_OLUFSEN - } - return 1; -} - -/** - * Simple version of write without support for MAGIQUEST and numberOfBits for SONY protocol - * @param aNumberOfRepeats If aNumberOfRepeats < 0 then only a special repeat frame without leading and trailing space - * will be sent by calling NECProtocolConstants.SpecialSendRepeatFunction(). - */ -size_t IRsend::write(decode_type_t aProtocol, uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats) { - -// switch (aProtocol) { // 26 bytes bigger than if, else if, else -// case NEC: -// sendNEC(aAddress, aCommand, aNumberOfRepeats, tSendRepeat); -// break; -// case SAMSUNG: -// sendSamsung(aAddress, aCommand, aNumberOfRepeats); -// break; -// case SONY: -// sendSony(aAddress, aCommand, aNumberOfRepeats, aIRSendData->numberOfBits); -// break; -// case PANASONIC: -// sendPanasonic(aAddress, aCommand, aNumberOfRepeats); -// break; -// case DENON: -// sendDenon(aAddress, aCommand, aNumberOfRepeats); -// break; -// case SHARP: -// sendSharp(aAddress, aCommand, aNumberOfRepeats); -// break; -// case JVC: -// sendJVC((uint8_t) aAddress, (uint8_t) aCommand, aNumberOfRepeats); // casts are required to specify the right function -// break; -// case RC5: -// sendRC5(aAddress, aCommand, aNumberOfRepeats, !tSendRepeat); // No toggle for repeats -// break; -// case RC6: -// // No toggle for repeats// sendRC6(aAddress, aCommand, aNumberOfRepeats, !tSendRepeat); // No toggle for repeats -// break; -// default: -// break; -// } - - /* - * Order of protocols is in guessed relevance :-) - */ - if (aProtocol == NEC) { - sendNEC(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == SAMSUNG) { - sendSamsung(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == SAMSUNG48) { - sendSamsung48(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == SAMSUNG_LG) { - sendSamsungLG(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == SONY) { - sendSony(aAddress, aCommand, aNumberOfRepeats, SIRCS_12_PROTOCOL); - - } else if (aProtocol == PANASONIC) { - sendPanasonic(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == DENON) { - sendDenon(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == SHARP) { - sendSharp(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == LG) { - sendLG(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == JVC) { - sendJVC((uint8_t) aAddress, (uint8_t) aCommand, aNumberOfRepeats); // casts are required to specify the right function - - } else if (aProtocol == RC5) { - sendRC5(aAddress, aCommand, aNumberOfRepeats, (aNumberOfRepeats > 0)); // No toggle for repeats - - } else if (aProtocol == RC6) { - sendRC6(aAddress, aCommand, aNumberOfRepeats, (aNumberOfRepeats > 0)); // No toggle for repeats - - } else if (aProtocol == KASEIKYO_JVC) { - sendKaseikyo_JVC(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == KASEIKYO_DENON) { - sendKaseikyo_Denon(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == KASEIKYO_SHARP) { - sendKaseikyo_Sharp(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == KASEIKYO_MITSUBISHI) { - sendKaseikyo_Mitsubishi(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == NEC2) { - sendNEC2(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == ONKYO) { - sendOnkyo(aAddress, aCommand, aNumberOfRepeats); - - } else if (aProtocol == APPLE) { - sendApple(aAddress, aCommand, aNumberOfRepeats); - -#if !defined(EXCLUDE_EXOTIC_PROTOCOLS) - } else if (aProtocol == BOSEWAVE) { - sendBoseWave(aCommand, aNumberOfRepeats); - - } else if (aProtocol == FAST) { - // We have only 8 bit command - sendFAST(aCommand, aNumberOfRepeats); - - } else if (aProtocol == LEGO_PF) { - sendLegoPowerFunctions(aAddress, aCommand, aCommand >> 4, (aNumberOfRepeats < 0)); // send 5 autorepeats, except for dedicated repeats -#endif - - } else { - return 0; // Not supported by write. E.g for BANG_OLUFSEN - } - return 1; -} - -/** - * Function using an 16 byte microsecond timing array for every purpose. - * Raw data starts with a Mark. No leading space as in received timing data! - */ -void IRsend::sendRaw(const uint16_t aBufferWithMicroseconds[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) { -// Set IR carrier frequency - enableIROut(aIRFrequencyKilohertz); - - /* - * Raw data starts with a mark. - */ - for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) { - if (i & 1) { - // Odd - space(aBufferWithMicroseconds[i]); - } else { - mark(aBufferWithMicroseconds[i]); - } - } -} - -/** - * Function using an 8 byte tick timing array to save program memory - * Raw data starts with a Mark. No leading space as in received timing data! - */ -void IRsend::sendRaw(const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) { -// Set IR carrier frequency - enableIROut(aIRFrequencyKilohertz); - - for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) { - if (i & 1) { - // Odd - space(aBufferWithTicks[i] * MICROS_PER_TICK); - } else { - mark(aBufferWithTicks[i] * MICROS_PER_TICK); - } - } - IRLedOff(); // Always end with the LED off -} - -/** - * Function using an 16 byte microsecond timing array in FLASH for every purpose. - * Raw data starts with a Mark. No leading space as in received timing data! - */ -void IRsend::sendRaw_P(const uint16_t aBufferWithMicroseconds[], uint_fast16_t aLengthOfBuffer, - uint_fast8_t aIRFrequencyKilohertz) { -#if !defined(__AVR__) - sendRaw(aBufferWithMicroseconds, aLengthOfBuffer, aIRFrequencyKilohertz); // Let the function work for non AVR platforms -#else -// Set IR carrier frequency - enableIROut(aIRFrequencyKilohertz); - /* - * Raw data starts with a mark - */ - for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) { - auto duration = pgm_read_word(&aBufferWithMicroseconds[i]); - if (i & 1) { - // Odd - space(duration); - } else { - mark(duration); - } - } -#endif -} - -/** - * New function using an 8 byte tick timing array in FLASH to save program memory - * Raw data starts with a Mark. No leading space as in received timing data! - */ -void IRsend::sendRaw_P(const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) { -#if !defined(__AVR__) - sendRaw(aBufferWithTicks, aLengthOfBuffer, aIRFrequencyKilohertz); // Let the function work for non AVR platforms -#else -// Set IR carrier frequency - enableIROut(aIRFrequencyKilohertz); - - for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) { - uint_fast16_t duration = pgm_read_byte(&aBufferWithTicks[i]) * (uint_fast16_t) MICROS_PER_TICK; - if (i & 1) { - // Odd - space(duration); - } else { - mark(duration); - } - } - IRLedOff(); // Always end with the LED off -#endif -} - -/** - * Sends PulseDistance data from array - * For LSB First the LSB of array[0] is sent first then all bits until MSB of array[0]. Next is LSB of array[1] and so on. - * The output always ends with a space - * Stop bit is always sent - */ -void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros, - uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros, - IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit, - uint16_t aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats) { - uint8_t tFlags = 0; - if (aMSBFirst) { - tFlags = PROTOCOL_IS_MSB_FIRST; - } - (void) aSendStopBit; - - sendPulseDistanceWidthFromArray(aFrequencyKHz, aHeaderMarkMicros, aHeaderSpaceMicros, aOneMarkMicros, aOneSpaceMicros, - aZeroMarkMicros, aZeroSpaceMicros, aDecodedRawDataArray, aNumberOfBits, tFlags, aRepeatPeriodMillis, aNumberOfRepeats); -} - -void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, DistanceWidthTimingInfoStruct *aDistanceWidthTimingInfo, - IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis, - int_fast8_t aNumberOfRepeats) { - sendPulseDistanceWidthFromArray(aFrequencyKHz, aDistanceWidthTimingInfo->HeaderMarkMicros, - aDistanceWidthTimingInfo->HeaderSpaceMicros, aDistanceWidthTimingInfo->OneMarkMicros, - aDistanceWidthTimingInfo->OneSpaceMicros, aDistanceWidthTimingInfo->ZeroMarkMicros, - aDistanceWidthTimingInfo->ZeroSpaceMicros, aDecodedRawDataArray, aNumberOfBits, aFlags, aRepeatPeriodMillis, - aNumberOfRepeats); -} - -void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros, - uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros, - IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis, - int_fast8_t aNumberOfRepeats) { - - // Set IR carrier frequency - enableIROut(aFrequencyKHz); - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - uint_fast8_t tNumberOf32Or64BitChunks = ((aNumberOfBits - 1) / BITS_IN_RAW_DATA_TYPE) + 1; - -#if defined(LOCAL_DEBUG) - // fist data - Serial.print(F("Data[0]=0x")); - Serial.print(aDecodedRawDataArray[0], HEX); - if (tNumberOf32Or64BitChunks > 1) { - Serial.print(F(" Data[1]=0x")); - Serial.print(aDecodedRawDataArray[1], HEX); - } - Serial.print(F(" #=")); - Serial.println(aNumberOfBits); - Serial.flush(); -#endif - - while (tNumberOfCommands > 0) { - unsigned long tStartOfFrameMillis = millis(); - - // Header - mark(aHeaderMarkMicros); - space(aHeaderSpaceMicros); - - for (uint_fast8_t i = 0; i < tNumberOf32Or64BitChunks; ++i) { - uint8_t tNumberOfBitsForOneSend; - - // Manage stop bit - uint8_t tFlags; - if (i == (tNumberOf32Or64BitChunks - 1)) { - // End of data - tNumberOfBitsForOneSend = aNumberOfBits; - tFlags = aFlags; - } else { - // intermediate data - tNumberOfBitsForOneSend = BITS_IN_RAW_DATA_TYPE; - tFlags = aFlags | SUPPRESS_STOP_BIT_FOR_THIS_DATA; // No stop bit for leading data - } - - sendPulseDistanceWidthData(aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, aZeroSpaceMicros, aDecodedRawDataArray[i], - tNumberOfBitsForOneSend, tFlags); - aNumberOfBits -= BITS_IN_RAW_DATA_TYPE; - } - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - /* - * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration. - */ - auto tFrameDurationMillis = millis() - tStartOfFrameMillis; - if (aRepeatPeriodMillis > tFrameDurationMillis) { - delay(aRepeatPeriodMillis - tFrameDurationMillis); - } - } - } -} - -/** - * Sends PulseDistance data from array using PulseDistanceWidthProtocolConstants - * For LSB First the LSB of array[0] is sent first then all bits until MSB of array[0]. Next is LSB of array[1] and so on. - * The output always ends with a space - * Stop bit is always sent - */ -void IRsend::sendPulseDistanceWidthFromArray(PulseDistanceWidthProtocolConstants *aProtocolConstants, - IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, int_fast8_t aNumberOfRepeats) { - -// Calling sendPulseDistanceWidthFromArray() costs 68 bytes program memory compared to the implementation below -// sendPulseDistanceWidthFromArray(aProtocolConstants->FrequencyKHz, aProtocolConstants->DistanceWidthTimingInfo.HeaderMarkMicros, -// aProtocolConstants->DistanceWidthTimingInfo.HeaderSpaceMicros, -// aProtocolConstants->DistanceWidthTimingInfo.OneMarkMicros, aProtocolConstants->DistanceWidthTimingInfo.OneSpaceMicros, -// aProtocolConstants->DistanceWidthTimingInfo.ZeroMarkMicros, aProtocolConstants->DistanceWidthTimingInfo.ZeroSpaceMicros, -// aDecodedRawDataArray, aNumberOfBits, aProtocolConstants->Flags, aProtocolConstants->RepeatPeriodMillis, -// aNumberOfRepeats); - // Set IR carrier frequency - enableIROut(aProtocolConstants->FrequencyKHz); - - uint_fast8_t tNumberOf32Or64BitChunks = ((aNumberOfBits - 1) / BITS_IN_RAW_DATA_TYPE) + 1; - -#if defined(LOCAL_DEBUG) - // fist data - Serial.print(F("Data[0]=0x")); - Serial.print(aDecodedRawDataArray[0], HEX); - if (tNumberOf32Or64BitChunks > 1) { - Serial.print(F(" Data[1]=0x")); - Serial.print(aDecodedRawDataArray[1], HEX); - } - Serial.print(F(" #=")); - Serial.println(aNumberOfBits); - Serial.flush(); -#endif - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - auto tStartOfFrameMillis = millis(); - auto tNumberOfBits = aNumberOfBits; // refresh value for repeats - - // Header - mark(aProtocolConstants->DistanceWidthTimingInfo.HeaderMarkMicros); - space(aProtocolConstants->DistanceWidthTimingInfo.HeaderSpaceMicros); - uint8_t tOriginalFlags = aProtocolConstants->Flags; - - for (uint_fast8_t i = 0; i < tNumberOf32Or64BitChunks; ++i) { - uint8_t tNumberOfBitsForOneSend; - - uint8_t tFlags; - if (i == (tNumberOf32Or64BitChunks - 1)) { - // End of data - tNumberOfBitsForOneSend = tNumberOfBits; - tFlags = tOriginalFlags; - } else { - // intermediate data - tNumberOfBitsForOneSend = BITS_IN_RAW_DATA_TYPE; - tFlags = tOriginalFlags | SUPPRESS_STOP_BIT_FOR_THIS_DATA; // No stop bit for leading data - } - - sendPulseDistanceWidthData(aProtocolConstants->DistanceWidthTimingInfo.OneMarkMicros, - aProtocolConstants->DistanceWidthTimingInfo.OneSpaceMicros, - aProtocolConstants->DistanceWidthTimingInfo.ZeroMarkMicros, - aProtocolConstants->DistanceWidthTimingInfo.ZeroSpaceMicros, aDecodedRawDataArray[i], tNumberOfBitsForOneSend, - tFlags); - tNumberOfBits -= BITS_IN_RAW_DATA_TYPE; - } - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - /* - * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration. - */ - auto tFrameDurationMillis = millis() - tStartOfFrameMillis; - if (aProtocolConstants->RepeatPeriodMillis > tFrameDurationMillis) { - delay(aProtocolConstants->RepeatPeriodMillis - tFrameDurationMillis); - } - } - } -} - -/** - * Sends PulseDistance frames and repeats and enables receiver again - * @param aProtocolConstants The constants to use for sending this protocol. - * @param aData uint32 or uint64 holding the bits to be sent. - * @param aNumberOfBits Number of bits from aData to be actually sent. - * @param aNumberOfRepeats If < 0 and a aProtocolConstants->SpecialSendRepeatFunction() is specified - * then it is called without leading and trailing space. - */ -void IRsend::sendPulseDistanceWidth(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, - uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats) { - -#if defined(LOCAL_DEBUG) - Serial.print(F("Data=0x")); - Serial.print(aData, HEX); - Serial.print(F(" #=")); - Serial.println(aNumberOfBits); - Serial.flush(); -#endif - - if (aNumberOfRepeats < 0) { - if (aProtocolConstants->SpecialSendRepeatFunction != NULL) { - aProtocolConstants->SpecialSendRepeatFunction(); - return; - } else { - aNumberOfRepeats = 0; // send a plain frame as repeat - } - } - - // Set IR carrier frequency - enableIROut(aProtocolConstants->FrequencyKHz); - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - unsigned long tStartOfFrameMillis = millis(); - - if (tNumberOfCommands < ((uint_fast8_t) aNumberOfRepeats + 1) && aProtocolConstants->SpecialSendRepeatFunction != NULL) { - // send special repeat - aProtocolConstants->SpecialSendRepeatFunction(); - } else { - /* - * Send Header and regular frame - */ - mark(aProtocolConstants->DistanceWidthTimingInfo.HeaderMarkMicros); - space(aProtocolConstants->DistanceWidthTimingInfo.HeaderSpaceMicros); - sendPulseDistanceWidthData(aProtocolConstants, aData, aNumberOfBits); - } - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - /* - * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration. - */ - auto tFrameDurationMillis = millis() - tStartOfFrameMillis; - if (aProtocolConstants->RepeatPeriodMillis > tFrameDurationMillis) { - delay(aProtocolConstants->RepeatPeriodMillis - tFrameDurationMillis); - } - } - } -} - -/** - * Sends PulseDistance frames and repeats. - * @param aFrequencyKHz, aHeaderMarkMicros, aHeaderSpaceMicros, aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, aZeroSpaceMicros, aFlags, aRepeatPeriodMillis Values to use for sending this protocol, also contained in the PulseDistanceWidthProtocolConstants of this protocol. - * @param aData uint32 or uint64 holding the bits to be sent. - * @param aNumberOfBits Number of bits from aData to be actually sent. - * @param aNumberOfRepeats If < 0 and a aProtocolConstants->SpecialSendRepeatFunction() is specified - * then it is called without leading and trailing space. - * @param aSpecialSendRepeatFunction If NULL, the first frame is repeated completely, otherwise this function is used for sending the repeat frame. - */ -void IRsend::sendPulseDistanceWidth(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros, - uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros, IRRawDataType aData, - uint_fast8_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit, uint16_t aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats, - void (*aSpecialSendRepeatFunction)()) { - uint8_t tFlags = 0; - if (aMSBFirst) { - tFlags = PROTOCOL_IS_MSB_FIRST; - } - (void) aSendStopBit; - sendPulseDistanceWidth(aFrequencyKHz, aHeaderMarkMicros, aHeaderSpaceMicros, aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, - aZeroSpaceMicros, aData, aNumberOfBits, tFlags, aRepeatPeriodMillis, aNumberOfRepeats, aSpecialSendRepeatFunction); - -} -void IRsend::sendPulseDistanceWidth(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros, - uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros, IRRawDataType aData, - uint_fast8_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats, - void (*aSpecialSendRepeatFunction)()) { - - if (aNumberOfRepeats < 0) { - if (aSpecialSendRepeatFunction != NULL) { - aSpecialSendRepeatFunction(); - return; - } else { - aNumberOfRepeats = 0; // send a plain frame as repeat - } - } - - // Set IR carrier frequency - enableIROut(aFrequencyKHz); - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - unsigned long tStartOfFrameMillis = millis(); - - if (tNumberOfCommands < ((uint_fast8_t) aNumberOfRepeats + 1) && aSpecialSendRepeatFunction != NULL) { - // send special repeat - aSpecialSendRepeatFunction(); - } else { - // Header and regular frame - mark(aHeaderMarkMicros); - space(aHeaderSpaceMicros); - sendPulseDistanceWidthData(aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, aZeroSpaceMicros, aData, aNumberOfBits, - aFlags); - } - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - /* - * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration. - */ - auto tFrameDurationMillis = millis() - tStartOfFrameMillis; - if (aRepeatPeriodMillis > tFrameDurationMillis) { - delay(aRepeatPeriodMillis - tFrameDurationMillis); - } - } - } -} - -/** - * Sends PulseDistance data - * The output always ends with a space - * Each additional call costs 16 bytes program memory - */ -void IRsend::sendPulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, - uint_fast8_t aNumberOfBits) { - - sendPulseDistanceWidthData(aProtocolConstants->DistanceWidthTimingInfo.OneMarkMicros, - aProtocolConstants->DistanceWidthTimingInfo.OneSpaceMicros, aProtocolConstants->DistanceWidthTimingInfo.ZeroMarkMicros, - aProtocolConstants->DistanceWidthTimingInfo.ZeroSpaceMicros, aData, aNumberOfBits, aProtocolConstants->Flags); -} - -/** - * Sends PulseDistance data - * The output always ends with a space - */ -void IRsend::sendPulseDistanceWidthData(uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, - uint16_t aZeroSpaceMicros, IRRawDataType aData, uint_fast8_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit) { - uint8_t tFlags = 0; - if (aMSBFirst) { - tFlags = PROTOCOL_IS_MSB_FIRST; - } - (void) aSendStopBit; - sendPulseDistanceWidthData(aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, aZeroSpaceMicros, aData, aNumberOfBits, tFlags); -} -void IRsend::sendPulseDistanceWidthData(uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, - uint16_t aZeroSpaceMicros, IRRawDataType aData, uint_fast8_t aNumberOfBits, uint8_t aFlags) { - -#if defined(LOCAL_DEBUG) - Serial.print(aData, HEX); - Serial.print('|'); - Serial.println(aNumberOfBits); - Serial.flush(); -#endif - - // For MSBFirst, send data from MSB to LSB until mask bit is shifted out - IRRawDataType tMask = 1ULL << (aNumberOfBits - 1); - for (uint_fast8_t i = aNumberOfBits; i > 0; i--) { - if (((aFlags & PROTOCOL_IS_MSB_FIRST) && (aData & tMask)) || (!(aFlags & PROTOCOL_IS_MSB_FIRST) && (aData & 1))) { -#if defined(LOCAL_TRACE) - Serial.print('1'); -#endif - mark(aOneMarkMicros); - space(aOneSpaceMicros); - } else { -#if defined(LOCAL_TRACE) - Serial.print('0'); -#endif - mark(aZeroMarkMicros); - space(aZeroSpaceMicros); - } - if (aFlags & PROTOCOL_IS_MSB_FIRST) { - tMask >>= 1; - } else { - aData >>= 1; - } - } - /* - * Stop bit is sent for all pulse distance protocols i.e. aOneMarkMicros == aZeroMarkMicros. - * Therefore it is not sent for Sony and Magiquest :-) - */ - if (!(aFlags & SUPPRESS_STOP_BIT_FOR_THIS_DATA) && aOneMarkMicros == aZeroMarkMicros) { - // Send stop bit here -#if defined(LOCAL_TRACE) - Serial.print('S'); -#endif - mark(aZeroMarkMicros); // Use aZeroMarkMicros for stop bits. This seems to be correct for all protocols :-) - } -#if defined(LOCAL_TRACE) - Serial.println(); -#endif -} - -/** - * Sends Biphase data MSB first - * Always send start bit, do not send the trailing space of the start bit - * 0 -> mark+space - * 1 -> space+mark - * The output always ends with a space - * can only send 31 bit data, since we put the start bit as 32th bit on front - */ -void IRsend::sendBiphaseData(uint16_t aBiphaseTimeUnit, uint32_t aData, uint_fast8_t aNumberOfBits) { - - IR_TRACE_PRINT(F("0x")); - IR_TRACE_PRINT(aData, HEX); - -#if defined(LOCAL_TRACE) - Serial.print('S'); -#endif - -// Data - Biphase code MSB first -// prepare for start with sending the start bit, which is 1 - uint32_t tMask = 1UL << aNumberOfBits; // mask is now set for the virtual start bit - uint_fast8_t tLastBitValue = 1; // Start bit is a 1 - bool tNextBitIsOne = 1; // Start bit is a 1 - for (uint_fast8_t i = aNumberOfBits + 1; i > 0; i--) { - bool tCurrentBitIsOne = tNextBitIsOne; - tMask >>= 1; - tNextBitIsOne = ((aData & tMask) != 0) || (i == 1); // true for last bit to avoid extension of mark - if (tCurrentBitIsOne) { -#if defined(LOCAL_TRACE) - Serial.print('1'); -#endif - space(aBiphaseTimeUnit); - if (tNextBitIsOne) { - mark(aBiphaseTimeUnit); - } else { - // if next bit is 0, extend the current mark in order to generate a continuous signal without short breaks - mark(2 * aBiphaseTimeUnit); - } - tLastBitValue = 1; - - } else { -#if defined(LOCAL_TRACE) - Serial.print('0'); -#endif - if (!tLastBitValue) { - mark(aBiphaseTimeUnit); - } - space(aBiphaseTimeUnit); - tLastBitValue = 0; - } - } - IR_TRACE_PRINTLN(F("")); -} - -/** - * Sends an IR mark for the specified number of microseconds. - * The mark output is modulated at the PWM frequency if USE_NO_SEND_PWM is not defined. - * The output is guaranteed to be OFF / inactive after after the call of the function. - * This function may affect the state of feedback LED. - * Period time is 26 us for 38.46 kHz, 27 us for 37.04 kHz, 25 us for 40 kHz. - * On time is 8 us for 30% duty cycle - */ -void IRsend::mark(uint16_t aMarkMicros) { - -#if defined(SEND_PWM_BY_TIMER) || defined(USE_NO_SEND_PWM) -# if !defined(NO_LED_FEEDBACK_CODE) - if (FeedbackLEDControl.LedFeedbackEnabled == LED_FEEDBACK_ENABLED_FOR_SEND) { - setFeedbackLED(true); - } -# endif -#endif - -#if defined(SEND_PWM_BY_TIMER) - /* - * Generate hardware PWM signal - */ - enableSendPWMByTimer(); // Enable timer or ledcWrite() generated PWM output - customDelayMicroseconds(aMarkMicros); - IRLedOff(); // disables hardware PWM and manages feedback LED - return; - -#elif defined(USE_NO_SEND_PWM) - /* - * Here we generate no carrier PWM, just simulate an active low receiver signal. - */ -# if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN) - pinModeFast(sendPin, OUTPUT); // active state for mimicking open drain -# else - digitalWriteFast(sendPin, LOW); // Set output to active low. -# endif - - customDelayMicroseconds(aMarkMicros); - IRLedOff(); -# if !defined(NO_LED_FEEDBACK_CODE) - if (FeedbackLEDControl.LedFeedbackEnabled == LED_FEEDBACK_ENABLED_FOR_SEND) { - setFeedbackLED(false); - } - return; -# endif - -#else // defined(SEND_PWM_BY_TIMER) - /* - * Generate PWM by bit banging - */ - unsigned long tStartMicros = micros(); - unsigned long tNextPeriodEnding = tStartMicros; - unsigned long tMicros; -# if !defined(NO_LED_FEEDBACK_CODE) - bool FeedbackLedIsActive = false; -# endif - - do { -// digitalToggleFast(_IR_TIMING_TEST_PIN); - /* - * Output the PWM pulse - */ - noInterrupts(); // do not let interrupts extend the short on period -# if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) -# if defined(OUTPUT_OPEN_DRAIN) - digitalWriteFast(sendPin, LOW); // set output with pin mode OUTPUT_OPEN_DRAIN to active low -# else - pinModeFast(sendPin, OUTPUT); // active state for mimicking open drain -# endif -# else - // 3.5 us from FeedbackLed on to pin setting. 5.7 us from call of mark() to pin setting incl. setting of feedback pin. - // 4.3 us from do{ to pin setting if sendPin is no constant - digitalWriteFast(sendPin, HIGH); -# endif - delayMicroseconds(periodOnTimeMicros); // On time is 8 us for 30% duty cycle. This is normally implemented by a blocking wait. - - /* - * Output the PWM pause - */ -# if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN) -# if defined(OUTPUT_OPEN_DRAIN) - digitalWriteFast(sendPin, HIGH); // Set output with pin mode OUTPUT_OPEN_DRAIN to inactive high. -# else - pinModeFast(sendPin, INPUT); // to mimic the open drain inactive state -# endif - -# else - digitalWriteFast(sendPin, LOW); -# endif - /* - * Enable interrupts at start of the longer off period. Required at least to keep micros correct. - * If receive interrupt is still active, it takes 3.4 us from now until receive ISR is active (for 7 us + pop's) - */ - interrupts(); - -# if !defined(NO_LED_FEEDBACK_CODE) - /* - * Delayed call of setFeedbackLED() to get better startup timing, especially required for consecutive marks - */ - if (!FeedbackLedIsActive) { - FeedbackLedIsActive = true; - if (FeedbackLEDControl.LedFeedbackEnabled == LED_FEEDBACK_ENABLED_FOR_SEND) { - setFeedbackLED(true); - } - } -# endif - /* - * PWM pause timing - * Measured delta between pause duration values are 13 us for a 16 MHz Uno (from 13 to 26), if interrupts are disabled below - * Measured delta between pause duration values are 20 us for a 16 MHz Uno (from 7.8 to 28), if interrupts are not disabled below - * Minimal pause duration is 5.2 us with NO_LED_FEEDBACK_CODE enabled - * and 8.1 us with NO_LED_FEEDBACK_CODE disabled. - */ - tNextPeriodEnding += periodTimeMicros; -#if defined(__AVR__) // micros() for STM sometimes give decreasing values if interrupts are disabled. See https://github.com/stm32duino/Arduino_Core_STM32/issues/1680 - noInterrupts(); // disable interrupts (especially the 20 us receive interrupts) only at start of the PWM pause. Otherwise it may extend the pause too much. -#endif - do { -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) - digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles -#endif - /* - * For AVR @16MHz we have only 4 us resolution. - * The duration of the micros() call itself is 3 us. - * It takes 0.9 us from signal going low here. - * The rest of the loop takes 1.2 us with NO_LED_FEEDBACK_CODE enabled - * and 3 us with NO_LED_FEEDBACK_CODE disabled. - */ -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) - digitalWriteFast(_IR_TIMING_TEST_PIN, LOW); // 2 clock cycles -#endif - /* - * Exit the forever loop if aMarkMicros has reached - */ - tMicros = micros(); - uint16_t tDeltaMicros = tMicros - tStartMicros; -#if defined(__AVR__) - // reset feedback led in the last pause before end -// tDeltaMicros += (160 / CLOCKS_PER_MICRO); // adding this once increases program size, so do it below ! -# if !defined(NO_LED_FEEDBACK_CODE) - if (tDeltaMicros >= aMarkMicros - (30 + (112 / CLOCKS_PER_MICRO))) { // 30 to be constant. Using periodTimeMicros increases program size too much. - if (FeedbackLEDControl.LedFeedbackEnabled == LED_FEEDBACK_ENABLED_FOR_SEND) { - setFeedbackLED(false); - } - } -# endif - // Just getting variables and check for end condition takes minimal 3.8 us - if (tDeltaMicros >= aMarkMicros - (112 / CLOCKS_PER_MICRO)) { // To compensate for call duration - 112 is an empirical value -#else - if (tDeltaMicros >= aMarkMicros) { -# if !defined(NO_LED_FEEDBACK_CODE) - if (FeedbackLEDControl.LedFeedbackEnabled == LED_FEEDBACK_ENABLED_FOR_SEND) { - setFeedbackLED(false); - } -# endif -#endif -#if defined(__AVR__) - interrupts(); -#endif - return; - } - } while (tMicros < tNextPeriodEnding); - } while (true); -# endif -} - -/** - * Just switch the IR sending LED off to send an IR space - * A space is "no output", so the PWM output is disabled. - * This function may affect the state of feedback LED. - */ -void IRsend::IRLedOff() { -#if defined(SEND_PWM_BY_TIMER) - disableSendPWMByTimer(); // Disable PWM output -#elif defined(USE_NO_SEND_PWM) -# if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN) - digitalWriteFast(sendPin, LOW); // prepare for all next active states. - pinModeFast(sendPin, INPUT);// inactive state for open drain -# else - digitalWriteFast(sendPin, HIGH); // Set output to inactive high. -# endif -#else -# if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) -# if defined(OUTPUT_OPEN_DRAIN) - digitalWriteFast(sendPin, HIGH); // Set output to inactive high. -# else - pinModeFast(sendPin, INPUT); // inactive state to mimic open drain -# endif -# else - digitalWriteFast(sendPin, LOW); -# endif -#endif - -#if !defined(NO_LED_FEEDBACK_CODE) - if (FeedbackLEDControl.LedFeedbackEnabled == LED_FEEDBACK_ENABLED_FOR_SEND) { - setFeedbackLED(false); - } -#endif -} - -/** - * Sends an IR space for the specified number of microseconds. - * A space is "no output", so just wait. - */ -void IRsend::space(uint16_t aSpaceMicros) { - customDelayMicroseconds(aSpaceMicros); -} - -/** - * Custom delay function that circumvents Arduino's delayMicroseconds 16 bit limit - * and is (mostly) not extended by the duration of interrupt codes like the millis() interrupt - */ -void IRsend::customDelayMicroseconds(unsigned long aMicroseconds) { -#if defined(ESP32) || defined(ESP8266) - // from https://github.com/crankyoldgit/IRremoteESP8266/blob/00b27cc7ea2e7ac1e48e91740723c805a38728e0/src/IRsend.cpp#L123 - // Invoke a delay(), where possible, to avoid triggering the WDT. - // see https://github.com/Arduino-IRremote/Arduino-IRremote/issues/1114 for the reason of checking for > 16383) - // delayMicroseconds() is only accurate to 16383 us. Ref: https://www.arduino.cc/en/Reference/delayMicroseconds - if (aMicroseconds > 16383) { - delay(aMicroseconds / 1000UL); // Delay for as many whole milliseconds as we can. - // Delay the remaining sub-millisecond. - delayMicroseconds(static_cast<uint16_t>(aMicroseconds % 1000UL)); - } else { - delayMicroseconds(aMicroseconds); - } -#else - -# if defined(__AVR__) - unsigned long start = micros() - (64 / clockCyclesPerMicrosecond()); // - (64 / clockCyclesPerMicrosecond()) for reduced resolution and additional overhead -# else - unsigned long start = micros(); -# endif -// overflow invariant comparison :-) - while (micros() - start < aMicroseconds) { - } -#endif -} - -/** - * Enables IR output. The kHz value controls the modulation frequency in kilohertz. - * IF PWM should be generated by a timer, it uses the platform specific timerConfigForSend() function, - * otherwise it computes the delays used by the mark() function. - * If IR_SEND_PIN is defined, maximum PWM frequency for an AVR @16 MHz is 170 kHz (180 kHz if NO_LED_FEEDBACK_CODE is defined) - */ -void IRsend::enableIROut(uint_fast8_t aFrequencyKHz) { -#if defined(SEND_PWM_BY_TIMER) - timerConfigForSend(aFrequencyKHz); // must set output pin mode and disable receive interrupt if required, e.g. uses the same resource - -#elif defined(USE_NO_SEND_PWM) - (void) aFrequencyKHz; - -#else - periodTimeMicros = (1000U + (aFrequencyKHz / 2)) / aFrequencyKHz; // rounded value -> 26 for 38.46 kHz, 27 for 37.04 kHz, 25 for 40 kHz. -# if defined(IR_SEND_PIN) - periodOnTimeMicros = (((periodTimeMicros * IR_SEND_DUTY_CYCLE_PERCENT) + 50) / 100U); // +50 for rounding -> 830/100 for 30% and 16 MHz -# else -// Heuristics! We require a nanosecond correction for "slow" digitalWrite() functions - periodOnTimeMicros = (((periodTimeMicros * IR_SEND_DUTY_CYCLE_PERCENT) + 50 - (PULSE_CORRECTION_NANOS / 10)) / 100U); // +50 for rounding -> 530/100 for 30% and 16 MHz -# endif -#endif // defined(SEND_PWM_BY_TIMER) - -#if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && defined(OUTPUT_OPEN_DRAIN) // the mode INPUT for mimicking open drain is set at IRLedOff() -# if defined(IR_SEND_PIN) - pinModeFast(IR_SEND_PIN, OUTPUT_OPEN_DRAIN); -# else - pinModeFast(sendPin, OUTPUT_OPEN_DRAIN); -# endif -#else - -// For Non AVR platforms pin mode for SEND_PWM_BY_TIMER must be handled by the timerConfigForSend() function -// because ESP 2.0.2 ledcWrite does not work if pin mode is set, and RP2040 requires gpio_set_function(IR_SEND_PIN, GPIO_FUNC_PWM); -# if defined(__AVR__) || !defined(SEND_PWM_BY_TIMER) -# if defined(IR_SEND_PIN) - pinModeFast(IR_SEND_PIN, OUTPUT); -# else - pinModeFast(sendPin, OUTPUT); -# endif -# endif -#endif // defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) -} - -#if defined(SEND_PWM_BY_TIMER) -// Used for Bang&Olufsen -void IRsend::enableHighFrequencyIROut(uint_fast16_t aFrequencyKHz) { - timerConfigForSend(aFrequencyKHz); // must set output pin mode and disable receive interrupt if required, e.g. uses the same resource - // For Non AVR platforms pin mode for SEND_PWM_BY_TIMER must be handled by the timerConfigForSend() function - // because ESP 2.0.2 ledcWrite does not work if pin mode is set, and RP2040 requires gpio_set_function(IR_SEND_PIN, GPIO_FUNC_PWM); -# if defined(__AVR__) -# if defined(IR_SEND_PIN) - pinModeFast(IR_SEND_PIN, OUTPUT); -# else - pinModeFast(sendPin, OUTPUT); -# endif -# endif -} -#endif - -uint16_t IRsend::getPulseCorrectionNanos() { - return PULSE_CORRECTION_NANOS; -} - -/** @}*/ -#if defined(_IR_MEASURE_TIMING) -#undef _IR_MEASURE_TIMING -#endif -#if defined(LOCAL_TRACE) -#undef LOCAL_TRACE -#endif -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_SEND_HPP diff --git a/IRremote/src/IRVersion.h b/IRremote/src/IRVersion.h deleted file mode 100644 index 06cd4d40c71e3ca6bae665eb3850a5bebe1cd775..0000000000000000000000000000000000000000 --- a/IRremote/src/IRVersion.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file IRversion.hpp - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2015-2023 Ken Shirriff http://www.righto.com, Rafi Khan, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - * - * For Ken Shiriffs original blog entry, see http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html - * Initially influenced by: - * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 - * and http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ - */ - -#ifndef _IR_VERSION_HPP -#define _IR_VERSION_HPP - -#define VERSION_IRREMOTE "4.2.0" -#define VERSION_IRREMOTE_MAJOR 4 -#define VERSION_IRREMOTE_MINOR 2 -#define VERSION_IRREMOTE_PATCH 0 - -/* - * Macro to convert 3 version parts into an integer - * To be used in preprocessor comparisons, such as #if VERSION_IRREMOTE_HEX >= VERSION_HEX_VALUE(3, 7, 0) - */ -#define VERSION_HEX_VALUE(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) -#define VERSION_IRREMOTE_HEX VERSION_HEX_VALUE(VERSION_IRREMOTE_MAJOR, VERSION_IRREMOTE_MINOR, VERSION_IRREMOTE_PATCH) - -#endif // _IR_VERSION_HPP diff --git a/IRremote/src/IRremote.h b/IRremote/src/IRremote.h deleted file mode 100644 index 90a91e4d1815d8a15e3bdacfd7f1fefdf62b62e8..0000000000000000000000000000000000000000 --- a/IRremote/src/IRremote.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @file IRremote.h - * - * @brief Stub for backward compatibility - */ - -#ifndef IRremote_h -#define IRremote_h - -#include "IRremote.hpp" - -/********************************************************************************************************************** - * The OLD and DEPRECATED decode function with parameter aResults, kept for backward compatibility to old 2.0 tutorials - * This function calls the old MSB first decoders and fills only the 3 variables: - * aResults->value - * aResults->bits - * aResults->decode_type - * It prints a message on the first call. - **********************************************************************************************************************/ -bool IRrecv::decode(decode_results *aResults) { - static bool sMessageWasSent = false; - if (!sMessageWasSent) { - Serial.println(F("**************************************************************************************************")); - Serial.println(F("Thank you for using the IRremote library!")); - Serial.println(F("It seems, that you are using a old version 2.0 code / example.")); - Serial.println(F("This version is no longer supported!")); - Serial.println(F("Please use one of the new code examples from the library,")); - Serial.println(F(" available at \"File > Examples > Examples from Custom Libraries / IRremote\".")); - Serial.println(); - Serial.println(F("Start with the SimpleReceiver or SimpleSender example.")); - Serial.println(); - Serial.println(F("The examples are documented here:")); - Serial.println(F(" https://github.com/Arduino-IRremote/Arduino-IRremote#examples-for-this-library")); - Serial.println(F("A guide how to convert your 2.0 program is here:")); - Serial.println(F(" https://github.com/Arduino-IRremote/Arduino-IRremote#converting-your-2x-program-to-the-4x-version")); - Serial.println(); - Serial.println(F("Thanks")); - Serial.println(F("**************************************************************************************************")); - Serial.println(); - Serial.println(); - sMessageWasSent = true; - } - return decode_old(aResults); -} - -#endif // IRremote_h -#pragma once - diff --git a/IRremote/src/IRremote.hpp b/IRremote/src/IRremote.hpp deleted file mode 100644 index f3e2919dae429af666e20266f484d6e198a8a4f1..0000000000000000000000000000000000000000 --- a/IRremote/src/IRremote.hpp +++ /dev/null @@ -1,318 +0,0 @@ -/** - * @file IRremote.hpp - * - * @brief Public API to the library. - * - * @code - * !!! All the macro values defined here can be overwritten with values, !!! - * !!! the user defines in its source code BEFORE the #include <IRremote.hpp> !!! - * @endcode - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2015-2023 Ken Shirriff http://www.righto.com, Rafi Khan, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - * - * For Ken Shiriffs original blog entry, see http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html - * Initially influenced by: - * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 - * and http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ - */ - -/* - * This library can be configured at compile time by the following options / macros: - * For more details see: https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library - * - * - RAW_BUFFER_LENGTH Buffer size of raw input buffer. Must be even! 100 is sufficient for *regular* protocols of up to 48 bits. - * - IR_SEND_PIN If specified (as constant), reduces program size and improves send timing for AVR. - * - SEND_PWM_BY_TIMER Disable carrier PWM generation in software and use (restricted) hardware PWM. - * - USE_NO_SEND_PWM Use no carrier PWM, just simulate an **active low** receiver signal. Overrides SEND_PWM_BY_TIMER definition. - * - USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN Use or simulate open drain output mode at send pin. Attention, active state of open drain is LOW, so connect the send LED between positive supply and send pin! - * - EXCLUDE_EXOTIC_PROTOCOLS If activated, BANG_OLUFSEN, BOSEWAVE, WHYNTER, FAST and LEGO_PF are excluded in decode() and in sending with IrSender.write(). - * - EXCLUDE_UNIVERSAL_PROTOCOLS If activated, the universal decoder for pulse distance protocols and decodeHash (special decoder for all protocols) are excluded in decode(). - * - DECODE_* Selection of individual protocols to be decoded. See below. - * - MARK_EXCESS_MICROS Value is subtracted from all marks and added to all spaces before decoding, to compensate for the signal forming of different IR receiver modules. - * - RECORD_GAP_MICROS Minimum gap between IR transmissions, to detect the end of a protocol. - * - FEEDBACK_LED_IS_ACTIVE_LOW Required on some boards (like my BluePill and my ESP8266 board), where the feedback LED is active low. - * - NO_LED_FEEDBACK_CODE This completely disables the LED feedback code for send and receive. - * - IR_INPUT_IS_ACTIVE_HIGH Enable it if you use a RF receiver, which has an active HIGH output signal. - * - IR_SEND_DUTY_CYCLE_PERCENT Duty cycle of IR send signal. - * - MICROS_PER_TICK Resolution of the raw input buffer data. Corresponds to 2 pulses of each 26.3 us at 38 kHz. - * - IR_USE_AVR_TIMER* Selection of timer to be used for generating IR receiving sample interval. - */ - -#ifndef _IR_REMOTE_HPP -#define _IR_REMOTE_HPP - -#include "IRVersion.h" - -// activate it for all cores that does not use the -flto flag, if you get false error messages regarding begin() during compilation. -//#define SUPPRESS_ERROR_MESSAGE_FOR_BEGIN - -/* - * If activated, BANG_OLUFSEN, BOSEWAVE, MAGIQUEST, WHYNTER, FAST and LEGO_PF are excluded in decoding and in sending with IrSender.write - */ -//#define EXCLUDE_EXOTIC_PROTOCOLS -/**************************************************** - * PROTOCOLS - ****************************************************/ -/* - * Supported IR protocols - * Each protocol you include costs memory and, during decode, costs time - * Copy the lines with the protocols you need in your program before the #include <IRremote.hpp> line - * See also SimpleReceiver example - */ - -#if !defined(NO_DECODER) // for sending raw only -# if (!(defined(DECODE_DENON) || defined(DECODE_JVC) || defined(DECODE_KASEIKYO) \ -|| defined(DECODE_PANASONIC) || defined(DECODE_LG) || defined(DECODE_NEC) || defined(DECODE_ONKYO) || defined(DECODE_SAMSUNG) \ -|| defined(DECODE_SONY) || defined(DECODE_RC5) || defined(DECODE_RC6) \ -|| defined(DECODE_DISTANCE_WIDTH) || defined(DECODE_HASH) || defined(DECODE_BOSEWAVE) \ -|| defined(DECODE_LEGO_PF) || defined(DECODE_MAGIQUEST) || defined(DECODE_FAST) || defined(DECODE_WHYNTER))) -/* - * If no protocol is explicitly enabled, we enable all protocols - */ -#define DECODE_DENON // Includes Sharp -#define DECODE_JVC -#define DECODE_KASEIKYO -#define DECODE_PANASONIC // alias for DECODE_KASEIKYO -#define DECODE_LG -#define DECODE_NEC // Includes Apple and Onkyo -#define DECODE_SAMSUNG -#define DECODE_SONY -#define DECODE_RC5 -#define DECODE_RC6 - -# if !defined(EXCLUDE_EXOTIC_PROTOCOLS) // saves around 2000 bytes program memory -#define DECODE_BOSEWAVE -#define DECODE_LEGO_PF -#define DECODE_MAGIQUEST // It modifies the RAW_BUFFER_LENGTH from 100 to 112 -#define DECODE_WHYNTER -#define DECODE_FAST -# endif - -# if !defined(EXCLUDE_UNIVERSAL_PROTOCOLS) -#define DECODE_DISTANCE_WIDTH // universal decoder for pulse distance width protocols - requires up to 750 bytes additional program memory -#define DECODE_HASH // special decoder for all protocols - requires up to 250 bytes additional program memory -# endif -# endif -#endif // !defined(NO_DECODER) - -//#define DECODE_BEO // Bang & Olufsen protocol always must be enabled explicitly. It prevents decoding of SONY! - -#if defined(DECODE_NEC) && !(~(~DECODE_NEC + 0) == 0 && ~(~DECODE_NEC + 1) == 1) -#warning "The macros DECODE_XXX no longer require a value. Decoding is now switched by defining / non defining the macro." -#endif - -//#define DEBUG // Activate this for lots of lovely debug output from the IRremote core. - -/**************************************************** - * RECEIVING - ****************************************************/ -/** - * MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, - * to compensate for the signal forming of different IR receiver modules - * For Vishay TSOP*, marks tend to be too long and spaces tend to be too short. - * If you set MARK_EXCESS_MICROS to approx. 50us then the TSOP4838 works best. - * At 100us it also worked, but not as well. - * Set MARK_EXCESS to 100us and the VS1838 doesn't work at all. - * - * The right value is critical for IR codes using short pulses like Denon / Sharp / Lego - * - * Observed values: - * Delta of each signal type is around 50 up to 100 and at low signals up to 200. TSOP is better, especially at low IR signal level. - * VS1838 Mark Excess -50 at low intensity to +50 us at high intensity - * TSOP31238 Mark Excess 0 to +50 - */ -#if !defined(MARK_EXCESS_MICROS) -// To change this value, you simply can add a line #define "MARK_EXCESS_MICROS <My_new_value>" in your ino file before the line "#include <IRremote.hpp>" -#define MARK_EXCESS_MICROS 20 -#endif - -/** - * Minimum gap between IR transmissions, to detect the end of a protocol. - * Must be greater than any space of a protocol e.g. the NEC header space of 4500 us. - * Must be smaller than any gap between a command and a repeat; e.g. the retransmission gap for Sony is around 15 ms for Sony20 protocol. - * Keep in mind, that this is the delay between the end of the received command and the start of decoding. - */ -#if !defined(RECORD_GAP_MICROS) -// To change this value, you simply can add a line #define "RECORD_GAP_MICROS <My_new_value>" in your ino file before the line "#include <IRremote.hpp>" -#define RECORD_GAP_MICROS 5000 // FREDRICH28AC / LG2 header space is 9700, NEC header space is 4500 -#endif -/** - * Threshold for warnings at printIRResult*() to report about changing the RECORD_GAP_MICROS value to a higher value. - */ -#if !defined(RECORD_GAP_MICROS_WARNING_THRESHOLD) -// To change this value, you simply can add a line #define "RECORD_GAP_MICROS_WARNING_THRESHOLD <My_new_value>" in your ino file before the line "#include <IRremote.hpp>" -#define RECORD_GAP_MICROS_WARNING_THRESHOLD 15000 -#endif - -/** Minimum gap between IR transmissions, in MICROS_PER_TICK */ -#define RECORD_GAP_TICKS (RECORD_GAP_MICROS / MICROS_PER_TICK) // 100 - -/* - * Activate this line if your receiver has an external output driver transistor / "inverted" output - */ -//#define IR_INPUT_IS_ACTIVE_HIGH -#if defined(IR_INPUT_IS_ACTIVE_HIGH) -// IR detector output is active high -#define INPUT_MARK 1 ///< Sensor output for a mark ("flash") -#else -// IR detector output is active low -#define INPUT_MARK 0 ///< Sensor output for a mark ("flash") -#endif -/**************************************************** - * SENDING - ****************************************************/ -/** - * Define to disable carrier PWM generation in software and use (restricted) hardware PWM. - */ -//#define SEND_PWM_BY_TIMER // restricts send pin on many platforms to fixed pin numbers -#if (defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE)) || defined(ARDUINO_ARCH_MBED) -# if !defined(SEND_PWM_BY_TIMER) -#define SEND_PWM_BY_TIMER // the best and default method for ESP32 etc. -#warning INFO: For ESP32, RP2040, mbed and particle boards SEND_PWM_BY_TIMER is enabled by default. If this is not intended, deactivate the line in IRremote.hpp over this warning message in file IRremote.hpp. -# endif -#else -# if defined(SEND_PWM_BY_TIMER) -# if defined(IR_SEND_PIN) -#undef IR_SEND_PIN // to avoid warning 3 lines later -#warning Since SEND_PWM_BY_TIMER is defined, the existing value of IR_SEND_PIN is discarded and replaced by the value determined by timer used for PWM generation -# endif -#define IR_SEND_PIN DeterminedByTimer // must be set here, since it is evaluated at IRremoteInt.h, before the include of private/IRTimer.hpp -# endif -#endif - -/** - * Define to use no carrier PWM, just simulate an active low receiver signal. - */ -//#define USE_NO_SEND_PWM -#if defined(SEND_PWM_BY_TIMER) && defined(USE_NO_SEND_PWM) -#warning "SEND_PWM_BY_TIMER and USE_NO_SEND_PWM are both defined -> undefine SEND_PWM_BY_TIMER now!" -#undef SEND_PWM_BY_TIMER // USE_NO_SEND_PWM overrides SEND_PWM_BY_TIMER -#endif - -/** - * Define to use or simulate open drain output mode at send pin. - * Attention, active state of open drain is LOW, so connect the send LED between positive supply and send pin! - */ -//#define USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN -#if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN) -#warning Pin mode OUTPUT_OPEN_DRAIN is not supported on this platform -> mimick open drain mode by switching between INPUT and OUTPUT mode. -#endif -/** - * This amount is subtracted from the on-time of the pulses generated for software PWM generation. - * It should be the time used for digitalWrite(sendPin, LOW) and the call to delayMicros() - * Measured value for Nano @16MHz is around 3000, for Bluepill @72MHz is around 700, for Zero 3600 - */ -#if !defined(PULSE_CORRECTION_NANOS) -# if defined(F_CPU) -// To change this value, you simply can add a line #define "PULSE_CORRECTION_NANOS <My_new_value>" in your ino file before the line "#include <IRremote.hpp>" -#define PULSE_CORRECTION_NANOS (48000L / (F_CPU/MICROS_IN_ONE_SECOND)) // 3000 @16MHz, 666 @72MHz -# else -#define PULSE_CORRECTION_NANOS 600 -# endif -#endif - -/** - * Duty cycle in percent for sent signals. - */ -#if ! defined(IR_SEND_DUTY_CYCLE_PERCENT) -#define IR_SEND_DUTY_CYCLE_PERCENT 30 // 30 saves power and is compatible to the old existing code -#endif - -/** - * microseconds per clock interrupt tick - */ -#if ! defined(MICROS_PER_TICK) -#define MICROS_PER_TICK 50L // must be with L to get 32 bit results if multiplied with rawbuf[] content. -#endif - -#define MILLIS_IN_ONE_SECOND 1000L -#define MICROS_IN_ONE_SECOND 1000000L -#define MICROS_IN_ONE_MILLI 1000L - -#include "IRremoteInt.h" -/* - * We always use digitalWriteFast() and digitalReadFast() functions to have a consistent mapping for pins. - * For most non AVR cpu's, it is just a mapping to digitalWrite() and digitalRead() functions. - */ -#include "digitalWriteFast.h" - -#if !defined(USE_IRREMOTE_HPP_AS_PLAIN_INCLUDE) -#include "private/IRTimer.hpp" // defines IR_SEND_PIN for AVR and SEND_PWM_BY_TIMER - -# if !defined(NO_LED_FEEDBACK_CODE) -# if !defined(LED_BUILTIN) -/* - * print a warning - */ -#warning INFO: No definition for LED_BUILTIN found -> default LED feedback is disabled. -# endif -#include "IRFeedbackLED.hpp" -# endif - -#include "LongUnion.h" // used in most decoders - -/* - * Include the sources here to enable compilation with macro values set by user program. - */ -#include "IRProtocol.hpp" // must be first, it includes definition for PrintULL (unsigned long long) -#if !defined(DISABLE_CODE_FOR_RECEIVER) -#include "IRReceive.hpp" -#endif -#include "IRSend.hpp" - -/* - * Include the sources of all decoders here to enable compilation with macro values set by user program. - */ -#include "ir_BangOlufsen.hpp" -#include "ir_BoseWave.hpp" -#include "ir_Denon.hpp" -#include "ir_JVC.hpp" -#include "ir_Kaseikyo.hpp" -#include "ir_Lego.hpp" -#include "ir_LG.hpp" -#include "ir_MagiQuest.hpp" -#include "ir_NEC.hpp" -#include "ir_RC5_RC6.hpp" -#include "ir_Samsung.hpp" -#include "ir_Sony.hpp" -#include "ir_FAST.hpp" -#include "ir_Others.hpp" -#include "ir_Pronto.hpp" // pronto is an universal decoder and encoder -# if defined(DECODE_DISTANCE_WIDTH) // universal decoder for pulse distance width protocols - requires up to 750 bytes additional program memory -#include <ir_DistanceWidthProtocol.hpp> -# endif -#endif // #if !defined(USE_IRREMOTE_HPP_AS_PLAIN_INCLUDE) - -/** - * Macros for legacy compatibility - */ -#define RAWBUF 101 // Maximum length of raw duration buffer -#define REPEAT 0xFFFFFFFF -#define USECPERTICK MICROS_PER_TICK -#define MARK_EXCESS MARK_EXCESS_MICROS - -#endif // _IR_REMOTE_HPP diff --git a/IRremote/src/IRremoteInt.h b/IRremote/src/IRremoteInt.h deleted file mode 100644 index 7ff756e339b0294c66c8b7ee21ad36954c287efe..0000000000000000000000000000000000000000 --- a/IRremote/src/IRremoteInt.h +++ /dev/null @@ -1,619 +0,0 @@ -/** - * @file IRremoteInt.h - * @brief Contains all declarations required for the interface to IRremote. - * Could not be named IRremote.h, since this has another semantic (it must include all *.hpp files) for old example code found in the wild. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2015-2023 Ken Shirriff http://www.righto.com, Rafi Khan, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_REMOTE_INT_H -#define _IR_REMOTE_INT_H - -#include <Arduino.h> - -#define MARK 1 -#define SPACE 0 - -#if defined(PARTICLE) -#define F_CPU 16000000 // definition for a board for which F_CPU is not defined -#endif -#if defined(F_CPU) // F_CPU is used to generate the receive send timings in some CPU's -#define CLOCKS_PER_MICRO (F_CPU / MICROS_IN_ONE_SECOND) -#endif - -/* - * For backwards compatibility - */ -#if defined(SYSCLOCK) // allow for processor specific code to define F_CPU -#undef F_CPU -#define F_CPU SYSCLOCK // Clock frequency to be used for timing. -#endif - -//#define DEBUG // Activate this for lots of lovely debug output from the IRremote core and all protocol decoders. -//#define TRACE // Activate this for more debug output. - -/** - * For better readability of code - */ -#define DISABLE_LED_FEEDBACK false -#define ENABLE_LED_FEEDBACK true -#define USE_DEFAULT_FEEDBACK_LED_PIN 0 - -/** - * The length of the buffer where the IR timing data is stored before decoding - * 100 is sufficient for most standard protocols, but air conditioners often send a longer protocol data stream - */ -#if !defined(RAW_BUFFER_LENGTH) -# if defined(DECODE_MAGIQUEST) -#define RAW_BUFFER_LENGTH 112 // MagiQuest requires 112 bytes. -# else -#define RAW_BUFFER_LENGTH 100 ///< Length of raw duration buffer. Must be even. 100 supports up to 48 bit codings inclusive 1 start and 1 stop bit. -//#define RAW_BUFFER_LENGTH 750 // 750 (600 if we have only 2k RAM) is the value for air condition remotes. -# endif -#endif -#if RAW_BUFFER_LENGTH % 2 == 1 -#error RAW_BUFFER_LENGTH must be even, since the array consists of space / mark pairs. -#endif - -/**************************************************** - * Declarations for the receiver Interrupt Service Routine - ****************************************************/ -// ISR State-Machine : Receiver States -#define IR_REC_STATE_IDLE 0 // Counting the gap time and waiting for the start bit to arrive -#define IR_REC_STATE_MARK 1 // A mark was received and we are counting the duration of it. -#define IR_REC_STATE_SPACE 2 // A space was received and we are counting the duration of it. If space is too long, we assume end of frame. -#define IR_REC_STATE_STOP 3 // Stopped until set to IR_REC_STATE_IDLE which can only be done by resume() - -/** - * This struct contains the data and control used for receiver static functions and the ISR (interrupt service routine) - * Only StateForISR needs to be volatile. All the other fields are not written by ISR after data available and before start/resume. - */ -struct irparams_struct { - // The fields are ordered to reduce memory over caused by struct-padding - volatile uint8_t StateForISR; ///< State Machine state - uint_fast8_t IRReceivePin; ///< Pin connected to IR data from detector -#if defined(__AVR__) - volatile uint8_t *IRReceivePinPortInputRegister; - uint8_t IRReceivePinMask; -#endif - volatile uint_fast16_t TickCounterForISR; ///< Counts 50uS ticks. The value is copied into the rawbuf array on every transition. -#if !IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK - void (*ReceiveCompleteCallbackFunction)(void); ///< The function to call if a protocol message has arrived, i.e. StateForISR changed to IR_REC_STATE_STOP -#endif - bool OverflowFlag; ///< Raw buffer OverflowFlag occurred -#if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR - uint_fast8_t rawlen; ///< counter of entries in rawbuf -#else - uint_fast16_t rawlen; ///< counter of entries in rawbuf -#endif - uint16_t rawbuf[RAW_BUFFER_LENGTH]; ///< raw data / tick counts per mark/space, first entry is the length of the gap between previous and current command -}; - -#if (__INT_WIDTH__ < 32) -typedef uint32_t IRRawDataType; -#define BITS_IN_RAW_DATA_TYPE 32 -#else -typedef uint64_t IRRawDataType; -#define BITS_IN_RAW_DATA_TYPE 64 -#endif -#include "IRProtocol.h" - -/* - * Debug directives - */ -#if defined(DEBUG) || defined(TRACE) -# define IR_DEBUG_PRINT(...) Serial.print(__VA_ARGS__) -# define IR_DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__) -#else -/** - * If DEBUG, print the arguments, otherwise do nothing. - */ -# define IR_DEBUG_PRINT(...) void() -/** - * If DEBUG, print the arguments as a line, otherwise do nothing. - */ -# define IR_DEBUG_PRINTLN(...) void() -#endif - -#if defined(TRACE) -# define IR_TRACE_PRINT(...) Serial.print(__VA_ARGS__) -# define IR_TRACE_PRINTLN(...) Serial.println(__VA_ARGS__) -#else -# define IR_TRACE_PRINT(...) void() -# define IR_TRACE_PRINTLN(...) void() -#endif - -/**************************************************** - * RECEIVING - ****************************************************/ - -/** - * Results returned from old decoders !!!deprecated!!! - */ -struct decode_results { - decode_type_t decode_type; // deprecated, moved to decodedIRData.protocol ///< UNKNOWN, NEC, SONY, RC5, ... - uint16_t address; // Used by Panasonic & Sharp [16-bits] - uint32_t value; // deprecated, moved to decodedIRData.decodedRawData ///< Decoded value / command [max 32-bits] - uint8_t bits; // deprecated, moved to decodedIRData.numberOfBits ///< Number of bits in decoded value - uint16_t magnitude; // deprecated, moved to decodedIRData.extra ///< Used by MagiQuest [16-bits] - bool isRepeat; // deprecated, moved to decodedIRData.flags ///< True if repeat of value is detected - -// next 3 values are copies of irparams values - see IRremoteint.h - uint16_t *rawbuf; // deprecated, moved to decodedIRData.rawDataPtr->rawbuf ///< Raw intervals in 50uS ticks - uint_fast8_t rawlen; // deprecated, moved to decodedIRData.rawDataPtr->rawlen ///< Number of records in rawbuf - bool overflow; // deprecated, moved to decodedIRData.flags ///< true if IR raw code too long -}; - -/** - * Main class for receiving IR signals - */ -class IRrecv { -public: - - IRrecv(); - IRrecv(uint_fast8_t aReceivePin); - IRrecv(uint_fast8_t aReceivePin, uint_fast8_t aFeedbackLEDPin); - void setReceivePin(uint_fast8_t aReceivePinNumber); - void registerReceiveCompleteCallback(void (*aReceiveCompleteCallbackFunction)(void)); - /* - * Stream like API - */ - void begin(uint_fast8_t aReceivePin, bool aEnableLEDFeedback = false, uint_fast8_t aFeedbackLEDPin = - USE_DEFAULT_FEEDBACK_LED_PIN); - void start(); - void enableIRIn(); // alias for start - void start(uint32_t aMicrosecondsToAddToGapCounter); - void startWithTicksToAdd(uint16_t aTicksToAddToGapCounter); - void restartAfterSend(); - - void addTicksToInternalTickCounter(uint16_t aTicksToAddToInternalTickCounter); - void addMicrosToInternalTickCounter(uint16_t aMicrosecondsToAddToInternalTickCounter); - - bool available(); - IRData* read(); // returns decoded data - // write is a method of class IRsend below - // size_t write(IRData *aIRSendData, int_fast8_t aNumberOfRepeats = NO_REPEATS); - void stop(); - void disableIRIn(); // alias for stop - void end(); // alias for stop - - bool isIdle(); - - /* - * The main functions - */ - bool decode(); // Check if available and try to decode - void resume(); // Enable receiving of the next value - - /* - * Useful info and print functions - */ - void printIRResultMinimal(Print *aSerial); - void printIRResultRawFormatted(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks = true); - void printIRResultAsCVariables(Print *aSerial); - uint32_t getTotalDurationOfRawData(); - - /* - * Next 4 functions are also available as non member functions - */ - bool printIRResultShort(Print *aSerial, bool aPrintRepeatGap = true, bool aCheckForRecordGapsMicros = true); - void printDistanceWidthTimingInfo(Print *aSerial, DistanceWidthTimingInfoStruct *aDistanceWidthTimingInfo); - void printIRSendUsage(Print *aSerial); -#if defined(__AVR__) - const __FlashStringHelper* getProtocolString(); -#else - const char* getProtocolString(); -#endif - static void printActiveIRProtocols(Print *aSerial); - - void compensateAndPrintIRResultAsCArray(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks = true); - void compensateAndPrintIRResultAsPronto(Print *aSerial, uint16_t frequency = 38000U); - - /* - * Store the data for further processing - */ - void compensateAndStoreIRResultInArray(uint8_t *aArrayPtr); - size_t compensateAndStorePronto(String *aString, uint16_t frequency = 38000U); - - /* - * The main decoding functions used by the individual decoders - */ - bool decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits, - uint_fast8_t aStartOffset = 3); - - bool decodePulseDistanceWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, uint16_t aOneMarkMicros, - uint16_t aZeroMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroSpaceMicros, bool aMSBfirst); - - bool decodeBiPhaseData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, uint_fast8_t aStartClockCount, - uint_fast8_t aValueOfSpaceToMarkTransition, uint16_t aBiphaseTimeUnit); - - void initBiphaselevel(uint_fast8_t aRCDecodeRawbuffOffset, uint16_t aBiphaseTimeUnit); - uint_fast8_t getBiphaselevel(); - - /* - * All standard (decode address + command) protocol decoders - */ - bool decodeBangOlufsen(); - bool decodeBoseWave(); - bool decodeDenon(); - bool decodeFAST(); - bool decodeJVC(); - bool decodeKaseikyo(); - bool decodeLegoPowerFunctions(); - bool decodeLG(); - bool decodeMagiQuest(); // not completely standard - bool decodeNEC(); - bool decodeRC5(); - bool decodeRC6(); - bool decodeSamsung(); - bool decodeSharp(); // redirected to decodeDenon() - bool decodeSony(); - bool decodeWhynter(); - - bool decodeDistanceWidth(); - - bool decodeHash(); - - // Template function :-) - bool decodeShuzu(); - - /* - * Old functions - */ - bool decodeDenonOld(decode_results *aResults); - bool decodeJVCMSB(decode_results *aResults); - bool decodeLGMSB(decode_results *aResults); - bool decodeNECMSB(decode_results *aResults); - bool decodePanasonicMSB(decode_results *aResults); - bool decodeSonyMSB(decode_results *aResults); - bool decodeSAMSUNG(decode_results *aResults); - bool decodeHashOld(decode_results *aResults); - - bool decode_old(decode_results *aResults); - - bool decode( - decode_results *aResults) - __attribute__ ((deprecated ("Please use IrReceiver.decode() without a parameter and IrReceiver.decodedIRData.<fieldname> ."))); - - // for backward compatibility. Now in IRFeedbackLED.hpp - void blink13(uint8_t aEnableLEDFeedback) - __attribute__ ((deprecated ("Please use setLEDFeedback() or enableLEDFeedback() / disableLEDFeedback()."))); - - /* - * Internal functions - */ - void initDecodedIRData(); - uint_fast8_t compare(uint16_t oldval, uint16_t newval); - bool checkHeader(PulseDistanceWidthProtocolConstants *aProtocolConstants); - void checkForRepeatSpaceTicksAndSetFlag(uint16_t aMaximumRepeatSpaceTicks); - bool checkForRecordGapsMicros(Print *aSerial); - - IRData decodedIRData; // New: decoded IR data for the application - - // Last decoded IR data for repeat detection and parity for Denon autorepeat - decode_type_t lastDecodedProtocol; - uint32_t lastDecodedAddress; - uint32_t lastDecodedCommand; - - uint8_t repeatCount; // Used e.g. for Denon decode for autorepeat decoding. -}; - -extern uint_fast8_t sBiphaseDecodeRawbuffOffset; // - -/* - * Mark & Space matching functions - */ -bool matchTicks(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros); -bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros); -bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros); - -/* - * Old function names - */ -bool MATCH(uint16_t measured, uint16_t desired); -bool MATCH_MARK(uint16_t measured_ticks, uint16_t desired_us); -bool MATCH_SPACE(uint16_t measured_ticks, uint16_t desired_us); - -int getMarkExcessMicros(); - -void printActiveIRProtocols(Print *aSerial); - -/**************************************************** - * Feedback LED related functions - ****************************************************/ -#define DO_NOT_ENABLE_LED_FEEDBACK 0x00 -#define LED_FEEDBACK_DISABLED_COMPLETELY 0x00 -#define LED_FEEDBACK_ENABLED_FOR_RECEIVE 0x01 -#define LED_FEEDBACK_ENABLED_FOR_SEND 0x02 -void setFeedbackLED(bool aSwitchLedOn); -void setLEDFeedback(uint8_t aFeedbackLEDPin, uint8_t aEnableLEDFeedback); // if aFeedbackLEDPin == 0, then take board BLINKLED_ON() and BLINKLED_OFF() functions -void setLEDFeedback(bool aEnableLEDFeedback); // Direct replacement for blink13() -void enableLEDFeedback(); -constexpr auto enableLEDFeedbackForReceive = enableLEDFeedback; // alias for enableLEDFeedback -void disableLEDFeedback(); -constexpr auto disableLEDFeedbackForReceive = disableLEDFeedback; // alias for enableLEDFeedback -void enableLEDFeedbackForSend(); -void disableLEDFeedbackForSend(); - -void setBlinkPin(uint8_t aFeedbackLEDPin) __attribute__ ((deprecated ("Please use setLEDFeedback()."))); // deprecated - -/* - * Pulse parms are ((X*50)-MARK_EXCESS_MICROS) for the Mark and ((X*50)+MARK_EXCESS_MICROS) for the Space. - * First MARK is the one after the long gap - * Pulse parameters in microseconds - */ -#if !defined(TOLERANCE_FOR_DECODERS_MARK_OR_SPACE_MATCHING) -#define TOLERANCE_FOR_DECODERS_MARK_OR_SPACE_MATCHING 25 // Relative tolerance (in percent) for matchTicks(), matchMark() and matchSpace() functions used for protocol decoding. -#endif - -/** Lower tolerance for comparison of measured data */ -//#define LTOL (1.0 - (TOLERANCE/100.)) -#define LTOL (100 - TOLERANCE_FOR_DECODERS_MARK_OR_SPACE_MATCHING) -/** Upper tolerance for comparison of measured data */ -//#define UTOL (1.0 + (TOLERANCE/100.)) -#define UTOL (100 + TOLERANCE_FOR_DECODERS_MARK_OR_SPACE_MATCHING) - -//#define TICKS_LOW(us) ((int)(((us)*LTOL/MICROS_PER_TICK))) -//#define TICKS_HIGH(us) ((int)(((us)*UTOL/MICROS_PER_TICK + 1))) -#if MICROS_PER_TICK == 50 && TOLERANCE_FOR_DECODERS_MARK_OR_SPACE_MATCHING == 25 // Defaults -#define TICKS_LOW(us) ((us)/67 ) // (us) / ((MICROS_PER_TICK:50 / LTOL:75 ) * 100) -#define TICKS_HIGH(us) (((us)/40) + 1) // (us) / ((MICROS_PER_TICK:50 / UTOL:125) * 100) + 1 -#else -#define TICKS_LOW(us) ((uint16_t ) ((long) (us) * LTOL / (MICROS_PER_TICK * 100) )) -#define TICKS_HIGH(us) ((uint16_t ) ((long) (us) * UTOL / (MICROS_PER_TICK * 100) + 1)) -#endif - -/* - * The receiver instance - */ -extern IRrecv IrReceiver; - -/* - * The receiver interrupt handler for timer interrupt - */ -void IRReceiveTimerInterruptHandler(); - -/**************************************************** - * SENDING - ****************************************************/ - -/** - * Just for better readability of code - */ -#define NO_REPEATS 0 -#define SEND_REPEAT_COMMAND true ///< used for e.g. NEC, where a repeat is different from just repeating the data. - -/** - * Main class for sending IR signals - */ -class IRsend { -public: - IRsend(); - - /* - * IR_SEND_PIN is defined - */ -#if defined(IR_SEND_PIN) - void begin(); - void begin(bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin = USE_DEFAULT_FEEDBACK_LED_PIN); - // The next function is a dummy to avoid acceptance of pre 4.0 calls to begin(IR_SEND_PIN, DISABLE_LED_FEEDBACK); - void begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback) -# if !defined (DOXYGEN) - __attribute__ ((deprecated ("You must use begin(ENABLE_LED_FEEDBACK) or begin(DISABLE_LED_FEEDBACK) since version 4.0."))); -# endif -#else - IRsend(uint_fast8_t aSendPin); - void begin(uint_fast8_t aSendPin); - void setSendPin(uint_fast8_t aSendPin); // required if we use IRsend() as constructor - // Since 4.0 guarded and without default parameter - void begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin); // aFeedbackLEDPin can be USE_DEFAULT_FEEDBACK_LED_PIN -#endif - - size_t write(IRData *aIRSendData, int_fast8_t aNumberOfRepeats = NO_REPEATS); - size_t write(decode_type_t aProtocol, uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats = NO_REPEATS); - - void enableIROut(uint_fast8_t aFrequencyKHz); -#if defined(SEND_PWM_BY_TIMER) - void enableHighFrequencyIROut(uint_fast16_t aFrequencyKHz); // Used for Bang&Olufsen -#endif - - void sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros, - uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros, - IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis, - int_fast8_t aNumberOfRepeats); - void sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros, - uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros, - IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit, - uint16_t aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats) - __attribute__ ((deprecated ("Since version 4.1.0 parameter aSendStopBit is not longer required."))); - void sendPulseDistanceWidthFromArray(PulseDistanceWidthProtocolConstants *aProtocolConstants, - IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, int_fast8_t aNumberOfRepeats); - void sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, DistanceWidthTimingInfoStruct *aDistanceWidthTimingInfo, - IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis, - int_fast8_t aNumberOfRepeats); - - void sendPulseDistanceWidth(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, - uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats); - void sendPulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, - uint_fast8_t aNumberOfBits); - void sendPulseDistanceWidth(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros, - uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros, - IRRawDataType aData, uint_fast8_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis, - int_fast8_t aNumberOfRepeats, void (*aSpecialSendRepeatFunction)() = NULL); - void sendPulseDistanceWidth(uint_fast8_t aFrequencyKHz, uint16_t aHeaderMarkMicros, uint16_t aHeaderSpaceMicros, - uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros, - IRRawDataType aData, uint_fast8_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit, uint16_t aRepeatPeriodMillis, - int_fast8_t aNumberOfRepeats, void (*aSpecialSendRepeatFunction)() = NULL) - __attribute__ ((deprecated ("Since version 4.1.0 parameter aSendStopBit is not longer required."))); - void sendPulseDistanceWidthData(uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, - uint16_t aZeroSpaceMicros, IRRawDataType aData, uint_fast8_t aNumberOfBits, uint8_t aFlags); - void sendPulseDistanceWidthData(uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, - uint16_t aZeroSpaceMicros, IRRawDataType aData, uint_fast8_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit) - __attribute__ ((deprecated ("Since version 4.1.0 last parameter aSendStopBit is not longer required."))); - void sendBiphaseData(uint16_t aBiphaseTimeUnit, uint32_t aData, uint_fast8_t aNumberOfBits); - - void mark(uint16_t aMarkMicros); - static void space(uint16_t aSpaceMicros); - void IRLedOff(); - -// 8 Bit array - void sendRaw(const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz); - void sendRaw_P(const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz); - -// 16 Bit array - void sendRaw(const uint16_t aBufferWithMicroseconds[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz); - void sendRaw_P(const uint16_t aBufferWithMicroseconds[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz); - - /* - * New send functions - */ - void sendBangOlufsen(uint16_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats = NO_REPEATS, - int8_t aNumberOfHeaderBits = 8); - void sendBangOlufsenDataLink(uint32_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats = NO_REPEATS, - int8_t aNumberOfHeaderBits = 8); - void sendBangOlufsenRaw(uint32_t aRawData, int_fast8_t aBits, bool aBackToBack = false); - void sendBangOlufsenRawDataLink(uint64_t aRawData, int_fast8_t aBits, bool aBackToBack = false, - bool aUseDatalinkTiming = false); - void sendBoseWave(uint8_t aCommand, int_fast8_t aNumberOfRepeats = NO_REPEATS); - void sendDenon(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aSendSharp = false); - void sendDenonRaw(uint16_t aRawData, int_fast8_t aNumberOfRepeats = NO_REPEATS) -#if !defined (DOXYGEN) - __attribute__ ((deprecated ("Please use sendDenon(aAddress, aCommand, aNumberOfRepeats)."))); -#endif - void sendFAST(uint8_t aCommand, int_fast8_t aNumberOfRepeats); - void sendJVC(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats); - - void sendLG2Repeat(); - uint32_t computeLGRawDataAndChecksum(uint8_t aAddress, uint16_t aCommand); - void sendLG(uint8_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats); - void sendLG2(uint8_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats); - void sendLGRaw(uint32_t aRawData, int_fast8_t aNumberOfRepeats = NO_REPEATS); - - void sendNECRepeat(); - uint32_t computeNECRawDataAndChecksum(uint16_t aAddress, uint16_t aCommand); - void sendNEC(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats); - void sendNEC2(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats); - void sendNECRaw(uint32_t aRawData, int_fast8_t aNumberOfRepeats = NO_REPEATS); - // NEC variants - void sendOnkyo(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats); - void sendApple(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats); - - void sendKaseikyo(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats, uint16_t aVendorCode); // LSB first - void sendPanasonic(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats); // LSB first - void sendKaseikyo_Denon(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats); // LSB first - void sendKaseikyo_Mitsubishi(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats); // LSB first - void sendKaseikyo_Sharp(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats); // LSB first - void sendKaseikyo_JVC(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats); // LSB first - - void sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle = true); - void sendRC6(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle = true); - void sendSamsungLGRepeat(); - void sendSamsung(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats); - void sendSamsung48(uint16_t aAddress, uint32_t aCommand, int_fast8_t aNumberOfRepeats); - void sendSamsungLG(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats); - void sendSharp(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats); // redirected to sendDenon - void sendSony(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint8_t numberOfBits = 12); // SIRCS_12_PROTOCOL - - void sendLegoPowerFunctions(uint8_t aChannel, uint8_t tCommand, uint8_t aMode, bool aDoSend5Times = true); - void sendLegoPowerFunctions(uint16_t aRawData, bool aDoSend5Times = true); - void sendLegoPowerFunctions(uint16_t aRawData, uint8_t aChannel, bool aDoSend5Times = true); - - void sendMagiQuest(uint32_t aWandId, uint16_t aMagnitude); - - void sendPronto(const __FlashStringHelper *str, int_fast8_t aNumberOfRepeats = NO_REPEATS); - void sendPronto(const char *prontoHexString, int_fast8_t aNumberOfRepeats = NO_REPEATS); - void sendPronto(const uint16_t *data, uint16_t length, int_fast8_t aNumberOfRepeats = NO_REPEATS); - -#if defined(__AVR__) - void sendPronto_PF(uint_farptr_t str, int_fast8_t aNumberOfRepeats = NO_REPEATS); - void sendPronto_P(const char *str, int_fast8_t aNumberOfRepeats); -#endif - -// Template protocol :-) - void sendShuzu(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats); - - /* - * OLD send functions - */ - void sendDenon(unsigned long data, - int nbits) - __attribute__ ((deprecated ("The function sendDenon(data, nbits) is deprecated and may not work as expected! Use sendDenonRaw(data, NumberOfRepeats) or better sendDenon(Address, Command, NumberOfRepeats)."))); - void sendDish(uint16_t aData); - void sendJVC(unsigned long data, int nbits, - bool repeat) - __attribute__ ((deprecated ("This old function sends MSB first! Please use sendJVC(aAddress, aCommand, aNumberOfRepeats)."))) { - sendJVCMSB(data, nbits, repeat); - } - void sendJVCMSB(unsigned long data, int nbits, bool repeat = false); - - void sendLG(unsigned long data, - int nbits) - __attribute__ ((deprecated ("The function sendLG(data, nbits) is deprecated and may not work as expected! Use sendLGRaw(data, NumberOfRepeats) or better sendLG(Address, Command, NumberOfRepeats)."))); - - void sendNEC(uint32_t aRawData, - uint8_t nbits) - __attribute__ ((deprecated ("This old function sends MSB first! Please use sendNECMSB() or sendNEC(aAddress, aCommand, aNumberOfRepeats)."))) { - sendNECMSB(aRawData, nbits); - } - void sendNECMSB(uint32_t data, uint8_t nbits, bool repeat = false); - void sendRC5(uint32_t data, uint8_t nbits); - void sendRC5ext(uint8_t addr, uint8_t cmd, bool toggle); - void sendRC6Raw(uint32_t data, uint8_t nbits); - void sendRC6(uint32_t data, uint8_t nbits) __attribute__ ((deprecated ("Please use sendRC6Raw()."))); - void sendRC6Raw(uint64_t data, uint8_t nbits); - void sendRC6(uint64_t data, uint8_t nbits) __attribute__ ((deprecated ("Please use sendRC6Raw()."))); - ; - void sendSharpRaw(unsigned long data, int nbits); - void sendSharp(uint16_t address, uint16_t command); - void sendSAMSUNG(unsigned long data, int nbits); - __attribute__ ((deprecated ("This old function sends MSB first! Please use sendSamsung()."))); - void sendSony(unsigned long data, - int nbits) - __attribute__ ((deprecated ("This old function sends MSB first! Please use sendSony(aAddress, aCommand, aNumberOfRepeats)."))); - ; - void sendWhynter(uint32_t aData, uint8_t aNumberOfBitsToSend); - -#if !defined(IR_SEND_PIN) - uint8_t sendPin; -#endif - uint16_t periodTimeMicros; - uint16_t periodOnTimeMicros; // compensated with PULSE_CORRECTION_NANOS for duration of digitalWrite. Around 8 microseconds for 38 kHz. - uint16_t getPulseCorrectionNanos(); - - static void customDelayMicroseconds(unsigned long aMicroseconds); -}; - -/* - * The sender instance - */ -extern IRsend IrSender; - -void sendNECSpecialRepeat(); -void sendLG2SpecialRepeat(); -void sendSamsungLGSpecialRepeat(); - -#endif // _IR_REMOTE_INT_H diff --git a/IRremote/src/LongUnion.h b/IRremote/src/LongUnion.h deleted file mode 100644 index 1e09695ee9f1fbac03a0b56eeca09113e6918665..0000000000000000000000000000000000000000 --- a/IRremote/src/LongUnion.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * LongUnion.h - * - * Copyright (C) 2020-2022 Armin Joachimsmeyer - * Email: armin.joachimsmeyer@gmail.com - * - * This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils. - * - * Arduino-Utils is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -#if !defined(_WORD_UNION_H) || !defined(_LONG_UNION_H) || !defined(_LONG_LONG_UNION_H) - -#include <stdint.h> - -#ifndef _WORD_UNION_H -#define _WORD_UNION_H -/** - * Union to specify parts / manifestations of a 16 bit Word without casts and shifts. - * It also supports the compiler generating small code. - * Usage: WordUnion tWord; - * tWord.UByte.HighByte = 0x12; - */ -union WordUnion { - struct { - uint8_t LowByte; - uint8_t HighByte; - } UByte; - struct { - int8_t LowByte; - int8_t HighByte; - } Byte; - uint8_t UBytes[2]; // UBytes[0] is LowByte - int8_t Bytes[2]; - uint16_t UWord; - int16_t Word; - uint8_t *BytePointer; -}; -#endif // _WORD_UNION_H - -#ifndef _LONG_UNION_H -#define _LONG_UNION_H -/** - * Union to specify parts / manifestations of a 32 bit Long without casts and shifts. - * It also supports the compiler generating small code. - */ -union LongUnion { - struct { - uint8_t LowByte; - uint8_t MidLowByte; - uint8_t MidHighByte; - uint8_t HighByte; - } UByte; - struct { - int8_t LowByte; - int8_t MidLowByte; - int8_t MidHighByte; - int8_t HighByte; - } Byte; - /* Does not work for STM32 - struct { - uint8_t LowByte; - uint16_t MidWord; - uint8_t HighByte; - } UByteWord; - */ - struct { - uint16_t LowWord; - uint16_t HighWord; - } UWord; - struct { - int16_t LowWord; - int16_t HighWord; - } Word; - struct { - WordUnion LowWord; - WordUnion HighWord; - } WordUnion; - uint8_t UBytes[4]; // seems to have the same code size as using struct UByte - int8_t Bytes[4]; // Bytes[0] is LowByte - uint16_t UWords[2]; - int16_t Words[2]; - uint32_t ULong; - int32_t Long; -}; -#endif // _LONG_UNION_H - -#ifndef _LONG_LONG_UNION_H -#define _LONG_LONG_UNION_H -/** - * Union to specify parts / manifestations of a 64 bit LongLong without casts and shifts. - * It also supports the compiler generating small code. - */ -union LongLongUnion { - struct { - uint16_t LowWord; - uint16_t MidLowWord; - uint16_t MidHighWord; - uint16_t HighWord; - } UWord; - struct { - int16_t LowWord; - int16_t MidLowWord; - int16_t MidHighWord; - int16_t HighWord; - } Word; - struct { - WordUnion LowWord; - WordUnion MidLowWord; - WordUnion MidHighWord; - WordUnion HighWord; - } WordUnion; - struct { - uint32_t LowLong; - uint32_t HighLong; - } ULong; - struct { - int32_t LowLong; - int32_t HighLong; - } Long; - struct { - LongUnion LowLong; - LongUnion HighLong; - } LongUnion; - uint8_t UBytes[8]; // seems to have the same code size as using struct UByte - int8_t Bytes[8]; - uint16_t UWords[4]; - int16_t Words[4]; - uint64_t ULongLong; - int64_t LongLong; -}; -#endif // _LONG_LONG_UNION_H - -#endif // !defined(_WORD_UNION_H) || !defined(_LONG_UNION_H) || !defined(_LONG_LONG_UNION_H) diff --git a/IRremote/src/TinyIR.h b/IRremote/src/TinyIR.h deleted file mode 100644 index cc17bc3571bbffc8e2544e030d82968f8d13d279..0000000000000000000000000000000000000000 --- a/IRremote/src/TinyIR.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * TinyIR.h - * - * - * Copyright (C) 2021-2023 Armin Joachimsmeyer - * armin.joachimsmeyer@gmail.com - * - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - * TinyIRReceiver is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. - * - */ - -#ifndef _TINY_IR_H -#define _TINY_IR_H - -#include <Arduino.h> - -#include "LongUnion.h" - -/** \addtogroup TinyReceiver Minimal receiver for NEC and FAST protocol - * @{ - */ - -#define VERSION_TINYIR "1.2.0" -#define VERSION_TINYIR_MAJOR 1 -#define VERSION_TINYIR_MINOR 2 -#define VERSION_TINYIR_PATCH 0 -// The change log is at the bottom of the file - -/** - * Timing for NEC protocol - * - * see: https://www.sbprojects.net/knowledge/ir/nec.php - * LSB first, 1 start bit + 16 bit address + 8 bit data + 8 bit inverted data + 1 stop bit. - */ -#if !defined(NEC_ADDRESS_BITS) -#define NEC_ADDRESS_BITS 16 // 16 bit address or 8 bit address and 8 bit inverted address -#define NEC_COMMAND_BITS 16 // Command and inverted command -#define NEC_BITS (NEC_ADDRESS_BITS + NEC_COMMAND_BITS) - -#define NEC_UNIT 560 - -#define NEC_HEADER_MARK (16 * NEC_UNIT) // 9000 -#define NEC_HEADER_SPACE (8 * NEC_UNIT) // 4500 - -#define NEC_BIT_MARK NEC_UNIT -#define NEC_ONE_SPACE (3 * NEC_UNIT) // 1690 -#define NEC_ZERO_SPACE NEC_UNIT - -#define NEC_REPEAT_HEADER_SPACE (4 * NEC_UNIT) // 2250 - -#define NEC_REPEAT_PERIOD 110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down. -#define NEC_MINIMAL_DURATION 49900 // NEC_HEADER_MARK + NEC_HEADER_SPACE + 32 * 2 * NEC_UNIT + NEC_UNIT // 2.5 because we assume more zeros than ones -#define NEC_MAXIMUM_REPEAT_DISTANCE (NEC_REPEAT_PERIOD - NEC_MINIMAL_DURATION + 10000) // 70 ms -#endif - -/** - * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header. - * FAST protocol characteristics: - * - Bit timing is like NEC or JVC - * - The header is shorter, 3156 vs. 12500 - * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command, - * leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms. - * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance. - */ -/* -Protocol=FAST Address=0x0 Command=0x76 Raw-Data=0x8976 16 bits LSB first - +2100,-1050 - + 550,- 500 + 550,-1550 + 550,-1550 + 550,- 500 - + 550,-1550 + 550,-1550 + 550,-1550 + 550,- 500 - + 550,-1550 + 550,- 500 + 550,- 500 + 550,-1550 - + 550,- 500 + 550,- 500 + 550,- 500 + 550,-1550 - + 550 -Sum: 28900 -*/ -#define FAST_KHZ 38 -#define FAST_ADDRESS_BITS 0 // No address -#define FAST_COMMAND_BITS 16 // Command and inverted command (parity) -#define FAST_BITS (FAST_ADDRESS_BITS + FAST_COMMAND_BITS) - -#define FAST_UNIT 526 // 20 periods of 38 kHz (526.315789) - -#define FAST_BIT_MARK FAST_UNIT -#define FAST_ONE_SPACE (3 * FAST_UNIT) // 1578 -> bit period = 2104 -#define FAST_ZERO_SPACE FAST_UNIT // 526 -> bit period = 1052 - -#define FAST_HEADER_MARK (4 * FAST_UNIT) // 2104 -#define FAST_HEADER_SPACE (2 * FAST_UNIT) // 1052 - -#define FAST_REPEAT_PERIOD 50000 // Commands are repeated every 50 ms (measured from start to start) for as long as the key on the remote control is held down. -#define FAST_REPEAT_DISTANCE (FAST_REPEAT_PERIOD - (55 * FAST_UNIT)) // 19 ms -#define FAST_MAXIMUM_REPEAT_DISTANCE (FAST_REPEAT_DISTANCE + 10000) // 29 ms - -/* - * Definitions to switch between FAST and NEC/ONKYO timing with the same code. - */ -#if defined(USE_FAST_PROTOCOL) -#define ENABLE_NEC2_REPEATS // Disables detection of special short frame NEC repeats. Saves 40 bytes program memory. - -#define TINY_RECEIVER_ADDRESS_BITS FAST_ADDRESS_BITS -#define TINY_RECEIVER_COMMAND_BITS FAST_COMMAND_BITS -#if !defined(TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY) -#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY true // 8 bit and 8 bit parity -//#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY false // 16 bit command without parity - not tested -#endif - -#define TINY_RECEIVER_BITS FAST_BITS -#define TINY_RECEIVER_UNIT FAST_UNIT - -#define TINY_RECEIVER_HEADER_MARK FAST_HEADER_MARK -#define TINY_RECEIVER_HEADER_SPACE FAST_HEADER_SPACE - -#define TINY_RECEIVER_BIT_MARK FAST_BIT_MARK -#define TINY_RECEIVER_ONE_SPACE FAST_ONE_SPACE -#define TINY_RECEIVER_ZERO_SPACE FAST_ZERO_SPACE - -#define TINY_RECEIVER_MAXIMUM_REPEAT_DISTANCE FAST_MAXIMUM_REPEAT_DISTANCE // for repeat detection - -#else - -#define TINY_RECEIVER_ADDRESS_BITS NEC_ADDRESS_BITS // the address bits + parity -# if defined(USE_ONKYO_PROTOCOL) -#define TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY false // 16 bit address without parity -# else -#define TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY true // 8 bit and 8 bit parity -# endif - -#define TINY_RECEIVER_COMMAND_BITS NEC_COMMAND_BITS // the command bits + parity -# if defined(USE_ONKYO_PROTOCOL) -#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY false // 16 bit command without parity -# else -#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY true // 8 bit and 8 bit parity -# endif - -#define TINY_RECEIVER_BITS NEC_BITS -#define TINY_RECEIVER_UNIT NEC_UNIT - -#define TINY_RECEIVER_HEADER_MARK NEC_HEADER_MARK -#define TINY_RECEIVER_HEADER_SPACE NEC_HEADER_SPACE - -#define TINY_RECEIVER_BIT_MARK NEC_BIT_MARK -#define TINY_RECEIVER_ONE_SPACE NEC_ONE_SPACE -#define TINY_RECEIVER_ZERO_SPACE NEC_ZERO_SPACE - -#define TINY_RECEIVER_MAXIMUM_REPEAT_DISTANCE NEC_MAXIMUM_REPEAT_DISTANCE -#endif - -/* - * This function is called, if a complete command was received and must be implemented in the file (user code) which includes this library. - * The parameter size is dependent of the code variant used in order to save program memory. - * We have 6 cases: 0, 8 bit or 16 bit address, each with 8 or 16 bit command - */ -#if (TINY_RECEIVER_ADDRESS_BITS > 0) -# if TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY -// 8 bit address here -# if TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY -extern void handleReceivedTinyIRData(uint8_t aAddress, uint8_t aCommand, uint8_t aFlags); // Standard NEC callback -# else -extern void handleReceivedTinyIRData(uint8_t aAddress, uint16_t aCommand, uint8_t aFlags); // If SUPPORT_ONKYO_16_BIT_COMMAND is defined -# endif - -# else // TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY -// 16 bit address here -# if TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY -extern void handleReceivedTinyIRData(uint16_t aAddress, uint8_t aCommand, uint8_t aFlags); -# else -extern void handleReceivedTinyIRData(uint16_t aAddress, uint16_t aCommand, uint8_t aFlags); -# endif -# endif - -#else -// FAST protocol - No address here -# if TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY -extern void handleReceivedTinyIRData(uint8_t aCommand, uint8_t aFlags); // Standard FAST callback -# else -extern void handleReceivedTinyIRData(uint16_t aCommand, uint8_t aFlags); // If "TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY false" is defined. 16 bit without parity. -# endif -#endif - -#if !defined(MICROS_IN_ONE_SECOND) -#define MICROS_IN_ONE_SECOND 1000000L -#endif - -#if !defined(MICROS_IN_ONE_MILLI) -#define MICROS_IN_ONE_MILLI 1000L -#endif - -/* - * Macros for comparing timing values - */ -#define lowerValue25Percent(aDuration) (aDuration - (aDuration / 4)) -#define upperValue25Percent(aDuration) (aDuration + (aDuration / 4)) -#define lowerValue50Percent(aDuration) (aDuration / 2) // (aDuration - (aDuration / 2)) -#define upperValue50Percent(aDuration) (aDuration + (aDuration / 2)) - -/* - * The states for the state machine - */ -#define IR_RECEIVER_STATE_WAITING_FOR_START_MARK 0 -#define IR_RECEIVER_STATE_WAITING_FOR_START_SPACE 1 -#define IR_RECEIVER_STATE_WAITING_FOR_FIRST_DATA_MARK 2 -#define IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE 3 -#define IR_RECEIVER_STATE_WAITING_FOR_DATA_MARK 4 -#define IR_RECEIVER_STATE_WAITING_FOR_STOP_MARK 5 -/** - * Control and data variables of the state machine for TinyReceiver - */ -struct TinyIRReceiverStruct { - /* - * State machine - */ - uint32_t LastChangeMicros; ///< Microseconds of last Pin Change Interrupt. - uint8_t IRReceiverState; ///< The state of the state machine. - uint8_t IRRawDataBitCounter; ///< How many bits are currently contained in raw data. - /* - * Data - */ -#if (TINY_RECEIVER_BITS > 16) - uint32_t IRRawDataMask; ///< The corresponding bit mask for IRRawDataBitCounter. - LongUnion IRRawData; ///< The current raw data. LongUnion helps with decoding of address and command. -#else - uint16_t IRRawDataMask; ///< The corresponding bit mask for IRRawDataBitCounter. - WordUnion IRRawData; ///< The current raw data. WordUnion helps with decoding of command. -#endif - uint8_t Flags; ///< One of IRDATA_FLAGS_EMPTY, IRDATA_FLAGS_IS_REPEAT, and IRDATA_FLAGS_PARITY_FAILED -}; - -/* - * Definitions for member TinyIRReceiverCallbackDataStruct.Flags - * From IRremoteInt.h - */ -#define IRDATA_FLAGS_EMPTY 0x00 -#define IRDATA_FLAGS_IS_REPEAT 0x01 -#define IRDATA_FLAGS_IS_AUTO_REPEAT 0x02 // not used here, overwritten with _IRDATA_FLAGS_IS_SHORT_REPEAT -#define IRDATA_FLAGS_PARITY_FAILED 0x04 ///< the current (autorepeat) frame violated parity check - -/** - * Can be used by the callback to transfer received data to main loop for further processing. - * E.g. with volatile struct TinyIRReceiverCallbackDataStruct sCallbackData; - */ -struct TinyIRReceiverCallbackDataStruct { -#if (TINY_RECEIVER_ADDRESS_BITS > 0) -# if (TINY_RECEIVER_ADDRESS_BITS == 16) && !TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY - uint16_t Address; -# else - uint8_t Address; -# endif -#endif - -# if (TINY_RECEIVER_COMMAND_BITS == 16) && !TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY - uint16_t Command; -#else - uint8_t Command; -#endif - uint8_t Flags; // Bit coded flags. Can contain one of the bits: IRDATA_FLAGS_IS_REPEAT and IRDATA_FLAGS_PARITY_FAILED - bool justWritten; ///< Is set true if new data is available. Used by the main loop, to avoid multiple evaluations of the same IR frame. -}; - -bool initPCIInterruptForTinyReceiver(); -bool enablePCIInterruptForTinyReceiver(); -void disablePCIInterruptForTinyReceiver(); -bool isTinyReceiverIdle(); -#if defined(USE_FAST_PROTOCOL) -void printTinyReceiverResultMinimal(Print *aSerial, uint16_t aCommand, uint8_t aFlags); -#else -void printTinyReceiverResultMinimal(Print *aSerial, uint8_t aAddress, uint8_t aCommand, uint8_t aFlags); -#endif - -void sendFAST(uint8_t aSendPin, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0); -void sendFast8BitAndParity(uint8_t aSendPin, uint8_t aCommand, uint_fast8_t aNumberOfRepeats = 0); -void sendONKYO(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0); // Send NEC with 16 bit command, even if aCommand < 0x100 -void sendNECMinimal(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0) - __attribute__ ((deprecated ("Renamed to sendNEC()."))); -void sendNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0); - -/* - * Version 1.2.0 - 01/2023 - * - Added ONKYO protocol, NEC with 16 bit address and command, instead of 8 bit + 8 bit parity address and command. - * - Renamed functions and macros. - * - * Version 1.1.0 - 01/2023 - * - FAST protocol added. - */ -/** @}*/ - -#endif // _TINY_IR_H diff --git a/IRremote/src/TinyIRReceiver.hpp b/IRremote/src/TinyIRReceiver.hpp deleted file mode 100644 index 42905bb4479932896b3d0c889ce47173836d71ac..0000000000000000000000000000000000000000 --- a/IRremote/src/TinyIRReceiver.hpp +++ /dev/null @@ -1,687 +0,0 @@ -/* - * TinyIRReceiver.hpp - * - * Receives IR protocol data of NEC protocol using pin change interrupts. - * NEC is the protocol of most cheap remote controls for Arduino. - * - * Parity check is done for address and data. - * On a completely received IR command, the user function handleReceivedIRData(uint8_t aAddress, uint8_t aCommand, uint8_t aFlags) - * is called in interrupt context but with interrupts being enabled to enable use of delay() etc. - * !!!!!!!!!!!!!!!!!!!!!! - * Functions called in interrupt context should be running as short as possible, - * so if you require longer action, save the data (address + command) and handle them in the main loop. - * !!!!!!!!!!!!!!!!!!!!! - * aFlags can contain one of IRDATA_FLAGS_EMPTY, IRDATA_FLAGS_IS_REPEAT and IRDATA_FLAGS_PARITY_FAILED bits - * - * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header. - * FAST Protocol characteristics: - * - Bit timing is like NEC or JVC - * - The header is shorter, 3156 vs. 12500 - * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command, - * leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms. - * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance. - * - * - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -/* - * This library can be configured at compile time by the following options / macros: - * For more details see: https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library (scroll down) - * - * - IR_RECEIVE_PIN The pin number for TinyIRReceiver IR input. - * - IR_FEEDBACK_LED_PIN The pin number for TinyIRReceiver feedback LED. - * - NO_LED_FEEDBACK_CODE Disables the feedback LED function. Saves 14 bytes program memory. - * - DISABLE_PARITY_CHECKS Disable parity checks. Saves 48 bytes of program memory. - * - USE_ONKYO_PROTOCOL Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. - * - USE_FAST_PROTOCOL Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC. - * - ENABLE_NEC2_REPEATS Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. - */ - -#ifndef _TINY_IR_RECEIVER_HPP -#define _TINY_IR_RECEIVER_HPP - -#include <Arduino.h> - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -//#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory. -//#define USE_ONKYO_PROTOCOL // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. -//#define USE_FAST_PROTOCOL // Use FAST protocol instead of NEC / ONKYO. -//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. - -#include "TinyIR.h" // If not defined, it defines IR_RECEIVE_PIN, IR_FEEDBACK_LED_PIN and TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT - -#include "digitalWriteFast.h" -/** \addtogroup TinyReceiver Minimal receiver for NEC and FAST protocol - * @{ - */ - -#if defined(DEBUG) -#define LOCAL_DEBUG_ATTACH_INTERRUPT -#else -//#define LOCAL_DEBUG_ATTACH_INTERRUPT // to see if attachInterrupt() or static interrupt (by register tweaking) is used -#endif -#if defined(TRACE) -#define LOCAL_TRACE_STATE_MACHINE -#else -//#define LOCAL_TRACE_STATE_MACHINE // to see the state of the ISR (Interrupt Service Routine) state machine -#endif - -//#define _IR_MEASURE_TIMING // Activate this if you want to enable internal hardware timing measurement. -//#define _IR_TIMING_TEST_PIN 7 -TinyIRReceiverStruct TinyIRReceiverControl; - -/* - * Set input pin and output pin definitions etc. - */ -#if defined(IR_INPUT_PIN) -#warning "IR_INPUT_PIN is deprecated, use IR_RECEIVE_PIN" -#define IR_RECEIVE_PIN IR_INPUT_PIN -#endif -#if !defined(IR_RECEIVE_PIN) -#if defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) -#warning "IR_RECEIVE_PIN is not defined, so it is set to 10" -#define IR_RECEIVE_PIN 10 -#elif defined(__AVR_ATtiny816__) -#warning "IR_RECEIVE_PIN is not defined, so it is set to 14" -#define IR_RECEIVE_PIN 14 -#else -#warning "IR_RECEIVE_PIN is not defined, so it is set to 2" -#define IR_RECEIVE_PIN 2 -#endif -#endif - -#if !defined(IR_FEEDBACK_LED_PIN) && defined(LED_BUILTIN) -#define IR_FEEDBACK_LED_PIN LED_BUILTIN -#endif - -#if !( \ - (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)) /* ATtinyX5 */ \ -|| defined(__AVR_ATtiny88__) /* MH-ET LIVE Tiny88 */ \ -|| defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) \ -|| defined(__AVR_ATmega8__) || defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__) \ -|| defined(__AVR_ATmega168__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168PB__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) \ - /* ATmegas with ports 0,1,2 above and ATtiny167 only 2 pins below */ \ -|| ( (defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)) && ( (defined(ARDUINO_AVR_DIGISPARKPRO) && ((IR_RECEIVE_PIN == 3) || (IR_RECEIVE_PIN == 9))) /*ATtinyX7(digisparkpro) and pin 3 or 9 */\ - || (! defined(ARDUINO_AVR_DIGISPARKPRO) && ((IR_RECEIVE_PIN == 3) || (IR_RECEIVE_PIN == 14)))) ) /*ATtinyX7(ATTinyCore) and pin 3 or 14 */ \ -) -#define TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT // Cannot use any static ISR vector here. In other cases we have code provided for generating interrupt on pin change. -#endif - -/** - * Declaration of the callback function provided by the user application. - * It is called every time a complete IR command or repeat was received. - */ -extern void handleReceivedIRData(uint16_t aAddress, uint8_t aCommand, bool isRepetition); - -#if defined(LOCAL_DEBUG) -uint32_t sMicrosOfGap; // The length of the gap before the start bit -#endif -/** - * The ISR (Interrupt Service Routine) of TinyIRRreceiver. - * It handles the NEC protocol decoding and calls the user callback function on complete. - * 5 us + 3 us for push + pop for a 16MHz ATmega - */ -#if defined(ESP8266) || defined(ESP32) -IRAM_ATTR -#endif -void IRPinChangeInterruptHandler(void) { -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) - digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles -#endif - /* - * Save IR input level - * Negative logic, true / HIGH means inactive / IR space, LOW / false means IR mark. - */ - uint_fast8_t tIRLevel = digitalReadFast(IR_RECEIVE_PIN); - -#if !defined(NO_LED_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN) - digitalWriteFast(IR_FEEDBACK_LED_PIN, !tIRLevel); -#endif - - /* - * 1. compute microseconds after last change - */ - // Repeats can be sent after a pause, which is longer than 64000 microseconds, so we need a 32 bit value for check of repeats - uint32_t tCurrentMicros = micros(); - uint32_t tMicrosOfMarkOrSpace32 = tCurrentMicros - TinyIRReceiverControl.LastChangeMicros; - uint16_t tMicrosOfMarkOrSpace = tMicrosOfMarkOrSpace32; - - TinyIRReceiverControl.LastChangeMicros = tCurrentMicros; - - uint8_t tState = TinyIRReceiverControl.IRReceiverState; - -#if defined(LOCAL_TRACE_STATE_MACHINE) - Serial.print(tState); - Serial.print(F(" D=")); - Serial.print(tMicrosOfMarkOrSpace); -// Serial.print(F(" I=")); -// Serial.print(tIRLevel); - Serial.print('|'); -#endif - - if (tIRLevel == LOW) { - /* - * We have a mark here - */ - if (tMicrosOfMarkOrSpace > 2 * TINY_RECEIVER_HEADER_MARK) { - // timeout -> must reset state machine - tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK; - } - if (tState == IR_RECEIVER_STATE_WAITING_FOR_START_MARK) { - // We are at the beginning of the header mark, check timing at the next transition - tState = IR_RECEIVER_STATE_WAITING_FOR_START_SPACE; - TinyIRReceiverControl.Flags = IRDATA_FLAGS_EMPTY; // If we do it here, it saves 4 bytes -#if defined(LOCAL_TRACE) - sMicrosOfGap = tMicrosOfMarkOrSpace32; -#endif -#if defined(ENABLE_NEC2_REPEATS) - // Check for repeat, where full frame is sent again after TINY_RECEIVER_REPEAT_PERIOD ms - // Not required for NEC, where repeats are detected by a special header space duration - // Must use 32 bit arithmetic here! - if (tMicrosOfMarkOrSpace32 < TINY_RECEIVER_MAXIMUM_REPEAT_DISTANCE) { - TinyIRReceiverControl.Flags = IRDATA_FLAGS_IS_REPEAT; - } -#endif - } - - else if (tState == IR_RECEIVER_STATE_WAITING_FOR_FIRST_DATA_MARK) { - if (tMicrosOfMarkOrSpace >= lowerValue25Percent(TINY_RECEIVER_HEADER_SPACE) - && tMicrosOfMarkOrSpace <= upperValue25Percent(TINY_RECEIVER_HEADER_SPACE)) { - /* - * We have a valid data header space here -> initialize data - */ - TinyIRReceiverControl.IRRawDataBitCounter = 0; -#if (TINY_RECEIVER_BITS > 16) - TinyIRReceiverControl.IRRawData.ULong = 0; -#else - TinyIRReceiverControl.IRRawData.UWord = 0; -#endif - TinyIRReceiverControl.IRRawDataMask = 1; - tState = IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE; -#if !defined(ENABLE_NEC2_REPEATS) - // Check for NEC repeat header - } else if (tMicrosOfMarkOrSpace >= lowerValue25Percent(NEC_REPEAT_HEADER_SPACE) - && tMicrosOfMarkOrSpace <= upperValue25Percent(NEC_REPEAT_HEADER_SPACE) - && TinyIRReceiverControl.IRRawDataBitCounter >= TINY_RECEIVER_BITS) { - /* - * We have a repeat header here and no broken receive before -> set repeat flag - */ - TinyIRReceiverControl.Flags = IRDATA_FLAGS_IS_REPEAT; - tState = IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE; -#endif - } else { - // This parts are optimized by the compiler into jumps to one code :-) - // Wrong length -> reset state - tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK; - } - } - - else if (tState == IR_RECEIVER_STATE_WAITING_FOR_DATA_MARK) { - // Check data space length - if (tMicrosOfMarkOrSpace >= lowerValue50Percent(TINY_RECEIVER_ZERO_SPACE) - && tMicrosOfMarkOrSpace <= upperValue50Percent(TINY_RECEIVER_ONE_SPACE)) { - // We have a valid bit here - tState = IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE; - if (tMicrosOfMarkOrSpace >= 2 * TINY_RECEIVER_UNIT) { - // we received a 1 -#if (TINY_RECEIVER_BITS > 16) - TinyIRReceiverControl.IRRawData.ULong |= TinyIRReceiverControl.IRRawDataMask; -#else - TinyIRReceiverControl.IRRawData.UWord |= TinyIRReceiverControl.IRRawDataMask; -#endif - } else { - // we received a 0 - empty code for documentation - } - // prepare for next bit - TinyIRReceiverControl.IRRawDataMask = TinyIRReceiverControl.IRRawDataMask << 1; - TinyIRReceiverControl.IRRawDataBitCounter++; - } else { - // Wrong length -> reset state - tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK; - } - } else { - // error wrong state for the received level, e.g. if we missed one change interrupt -> reset state - tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK; - } - } - - else { - /* - * We have a space here - */ - if (tState == IR_RECEIVER_STATE_WAITING_FOR_START_SPACE) { - /* - * Check length of header mark here - */ - if (tMicrosOfMarkOrSpace >= lowerValue25Percent(TINY_RECEIVER_HEADER_MARK) - && tMicrosOfMarkOrSpace <= upperValue25Percent(TINY_RECEIVER_HEADER_MARK)) { - tState = IR_RECEIVER_STATE_WAITING_FOR_FIRST_DATA_MARK; - } else { - // Wrong length of header mark -> reset state - tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK; - } - } - - else if (tState == IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE) { - // Check data mark length - if (tMicrosOfMarkOrSpace >= lowerValue50Percent(TINY_RECEIVER_BIT_MARK) - && tMicrosOfMarkOrSpace <= upperValue50Percent(TINY_RECEIVER_BIT_MARK)) { - /* - * We have a valid mark here, check for transmission complete, i.e. the mark of the stop bit - */ - if (TinyIRReceiverControl.IRRawDataBitCounter >= TINY_RECEIVER_BITS -#if !defined(ENABLE_NEC2_REPEATS) - || (TinyIRReceiverControl.Flags & IRDATA_FLAGS_IS_REPEAT) // Do not check for full length received, if we have a short repeat frame -#endif - ) { - /* - * Code complete -> optionally check parity - */ - // Reset state for new start - tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK; - -#if !defined(DISABLE_PARITY_CHECKS) && (TINY_RECEIVER_ADDRESS_BITS == 16) && TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY - /* - * Check address parity - * Address is sent first and contained in the lower word - */ - if (TinyIRReceiverControl.IRRawData.UBytes[0] != (uint8_t) (~TinyIRReceiverControl.IRRawData.UBytes[1])) { -#if defined(ENABLE_NEC2_REPEATS) - TinyIRReceiverControl.Flags |= IRDATA_FLAGS_PARITY_FAILED; // here we can have the repeat flag already set -#else - TinyIRReceiverControl.Flags = IRDATA_FLAGS_PARITY_FAILED; // here we do not check anything, if we have a repeat -#endif - } -#endif -#if !defined(DISABLE_PARITY_CHECKS) && (TINY_RECEIVER_COMMAND_BITS == 16) && TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY - /* - * Check command parity - */ -#if (TINY_RECEIVER_ADDRESS_BITS > 0) - if (TinyIRReceiverControl.IRRawData.UBytes[2] != (uint8_t) (~TinyIRReceiverControl.IRRawData.UBytes[3])) { -#if defined(ENABLE_NEC2_REPEATS) - TinyIRReceiverControl.Flags |= IRDATA_FLAGS_PARITY_FAILED; -#else - TinyIRReceiverControl.Flags = IRDATA_FLAGS_PARITY_FAILED; -#endif -# if defined(LOCAL_DEBUG) - Serial.print(F("Parity check for command failed. Command=")); - Serial.print(TinyIRReceiverControl.IRRawData.UBytes[2], HEX); - Serial.print(F(" parity=")); - Serial.println(TinyIRReceiverControl.IRRawData.UBytes[3], HEX); -# endif -#else - // No address, so command and parity are in the lowest bytes - if (TinyIRReceiverControl.IRRawData.UBytes[0] != (uint8_t) (~TinyIRReceiverControl.IRRawData.UBytes[1])) { - TinyIRReceiverControl.Flags |= IRDATA_FLAGS_PARITY_FAILED; -# if defined(LOCAL_DEBUG) - Serial.print(F("Parity check for command failed. Command=")); - Serial.print(TinyIRReceiverControl.IRRawData.UBytes[0], HEX); - Serial.print(F(" parity=")); - Serial.println(TinyIRReceiverControl.IRRawData.UBytes[1], HEX); -# endif -#endif - } -#endif - /* - * Call user provided callback here - * The parameter size is dependent of the code variant used in order to save program memory. - * We have 6 cases: 0, 8 bit or 16 bit address, each with 8 or 16 bit command - */ -#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) // no Serial etc. in callback for ESP -> no interrupt required, WDT is running! - interrupts(); // enable interrupts, so delay() etc. works in callback -#endif - handleReceivedTinyIRData( -#if (TINY_RECEIVER_ADDRESS_BITS > 0) -# if TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY - // Here we have 8 bit address - TinyIRReceiverControl.IRRawData.UBytes[0], -# else - // Here we have 16 bit address - TinyIRReceiverControl.IRRawData.UWord.LowWord, -# endif -# if TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY - // Here we have 8 bit command - TinyIRReceiverControl.IRRawData.UBytes[2], -# else - // Here we have 16 bit command - TinyIRReceiverControl.IRRawData.UWord.HighWord, -# endif -#else - - // Here we have NO address -# if TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY - // Here we have 8 bit command - TinyIRReceiverControl.IRRawData.UBytes[0], -# else - // Here we have 16 bit command - TinyIRReceiverControl.IRRawData.UWord, -# endif -#endif - TinyIRReceiverControl.Flags); - - } else { - // not finished yet - tState = IR_RECEIVER_STATE_WAITING_FOR_DATA_MARK; - } - } else { - // Wrong length -> reset state - tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK; - } - } else { - // error wrong state for the received level, e.g. if we missed one change interrupt -> reset state - tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK; - } - } - - TinyIRReceiverControl.IRReceiverState = tState; -#ifdef _IR_MEASURE_TIMING - digitalWriteFast(_IR_TIMING_TEST_PIN, LOW); // 2 clock cycles -#endif -} - -bool isTinyReceiverIdle() { - return (TinyIRReceiverControl.IRReceiverState == IR_RECEIVER_STATE_WAITING_FOR_START_MARK); -} - -/** - * Sets IR_RECEIVE_PIN mode to INPUT, and if IR_FEEDBACK_LED_PIN is defined, sets feedback LED output mode. - * Then call enablePCIInterruptForTinyReceiver() - */ -bool initPCIInterruptForTinyReceiver() { - pinModeFast(IR_RECEIVE_PIN, INPUT); - -#if !defined(NO_LED_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN) - pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT); -#endif - return enablePCIInterruptForTinyReceiver(); -} - -#if defined(USE_FAST_PROTOCOL) -void printTinyReceiverResultMinimal(Print *aSerial, uint16_t aCommand, uint8_t aFlags) -#else -void printTinyReceiverResultMinimal(Print *aSerial, uint8_t aAddress, uint8_t aCommand, uint8_t aFlags) -#endif - { -// Print only very short output, since we are in an interrupt context and do not want to miss the next interrupts of the repeats coming soon - // Print only very short output, since we are in an interrupt context and do not want to miss the next interrupts of the repeats coming soon -#if defined(USE_FAST_PROTOCOL) - aSerial->print(F("C=0x")); -#else - aSerial->print(F("A=0x")); - aSerial->print(aAddress, HEX); - aSerial->print(F(" C=0x")); -#endif - aSerial->print(aCommand, HEX); - if (aFlags == IRDATA_FLAGS_IS_REPEAT) { - aSerial->print(F(" R")); - } -#if !defined(DISABLE_PARITY_CHECKS) - if (aFlags == IRDATA_FLAGS_PARITY_FAILED) { - aSerial->print(F(" P")); - } -#endif - aSerial->println(); -} - -#if defined (LOCAL_DEBUG_ATTACH_INTERRUPT) && !defined(STR) -// Helper macro for getting a macro definition as string -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) -#endif - -/************************************************** - * Pin to interrupt mapping for different platforms - **************************************************/ -#if defined(__AVR_ATtiny816__) || defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) -#define USE_ATTACH_INTERRUPT_DIRECT - -#elif !defined(__AVR__) || defined(TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT) -// Default for all NON AVR platforms -#define USE_ATTACH_INTERRUPT - -#else -# if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) -#define USE_PCIE - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -# if defined(ARDUINO_AVR_DIGISPARKPRO) -# if (IR_RECEIVE_PIN == 3) -#define USE_INT0 -# elif (IR_RECEIVE_PIN == 9) -#define USE_INT1 -# else -# error "IR_RECEIVE_PIN must be 9 or 3." -# endif // if (IR_RECEIVE_PIN == 9) -# else // defined(ARDUINO_AVR_DIGISPARKPRO) -# if (IR_RECEIVE_PIN == 14) -#define USE_INT0 -# elif (IR_RECEIVE_PIN == 3) -#define USE_INT1 -# else -# error "IR_RECEIVE_PIN must be 14 or 3." -# endif // if (IR_RECEIVE_PIN == 14) -# endif - -# elif (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)) -# if (IR_RECEIVE_PIN == 21) -#define USE_INT0 -# elif (IR_RECEIVE_PIN == 20) -#define USE_INT1 -# else -#warning "No pin mapping for IR_RECEIVE_PIN to interrupt found -> attachInterrupt() is used now." -#define USE_ATTACH_INTERRUPT -# endif - -# else // defined(__AVR_ATtiny25__) -/* - * ATmegas + ATtiny88 here - */ -# if (IR_RECEIVE_PIN == 2) -#define USE_INT0 -# elif (IR_RECEIVE_PIN == 3) -#define USE_INT1 - -# elif IR_RECEIVE_PIN == 4 || IR_RECEIVE_PIN == 5 || IR_RECEIVE_PIN == 6 || IR_RECEIVE_PIN == 7 - //ATmega328 (Uno, Nano ) etc. Enable pin change interrupt 20 to 23 for port PD4 to PD7 (Arduino pin 4 to 7) -#define USE_PCINT2 -# elif IR_RECEIVE_PIN == 8 || IR_RECEIVE_PIN == 9 || IR_RECEIVE_PIN == 10 || IR_RECEIVE_PIN == 11 || IR_RECEIVE_PIN == 12 || IR_RECEIVE_PIN == 13 - //ATmega328 (Uno, Nano ) etc. Enable pin change interrupt 0 to 5 for port PB0 to PB5 (Arduino pin 8 to 13) -#define USE_PCINT0 -# elif IR_RECEIVE_PIN == A0 || IR_RECEIVE_PIN == A1 || IR_RECEIVE_PIN == A2 || IR_RECEIVE_PIN == A3 || IR_RECEIVE_PIN == A4 || IR_RECEIVE_PIN == A5 - //ATmega328 (Uno, Nano ) etc. Enable pin change interrupt 8 to 13 for port PC0 to PC5 (Arduino pin A0 to A5) -#define USE_PCINT1 - -# else -#warning "No pin mapping for IR_RECEIVE_PIN to interrupt found -> attachInterrupt() is used now." -#define USE_ATTACH_INTERRUPT -# endif // if (IR_RECEIVE_PIN == 2) -# endif // defined(__AVR_ATtiny25__) -#endif // ! defined(__AVR__) || defined(TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT) - -/** - * Initializes hardware interrupt generation according to IR_RECEIVE_PIN or use attachInterrupt() function. - * @return true if interrupt was successfully enabled - */ -bool enablePCIInterruptForTinyReceiver() { -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) - pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT); -#endif - -#if defined(USE_ATTACH_INTERRUPT) || defined(USE_ATTACH_INTERRUPT_DIRECT) -# if defined(USE_ATTACH_INTERRUPT) -#if defined(NOT_AN_INTERRUPT) - if(digitalPinToInterrupt(IR_RECEIVE_PIN) == NOT_AN_INTERRUPT){ - return false; - } -#endif - // costs 112 bytes program memory + 4 bytes RAM - attachInterrupt(digitalPinToInterrupt(IR_RECEIVE_PIN), IRPinChangeInterruptHandler, CHANGE); -# else - // 2.2 us more than version configured with macros and not compatible - attachInterrupt(IR_RECEIVE_PIN, IRPinChangeInterruptHandler, CHANGE); // no extra pin mapping here -# endif - -# if defined(LOCAL_DEBUG_ATTACH_INTERRUPT) - Serial.println(F("Use attachInterrupt for pin=" STR(IR_RECEIVE_PIN))); -# endif - -#else -# if defined(LOCAL_DEBUG_ATTACH_INTERRUPT) - Serial.println(F("Use static interrupt for pin=" STR(IR_RECEIVE_PIN))); -# endif -# if defined(USE_INT0) - // interrupt on any logical change - EICRA |= _BV(ISC00); - // clear interrupt bit - EIFR |= 1 << INTF0; - // enable interrupt on next change - EIMSK |= 1 << INT0; - -# elif defined(USE_INT1) - EICRA |= _BV(ISC10); -// clear interrupt bit - EIFR |= 1 << INTF1; -// enable interrupt on next change - EIMSK |= 1 << INT1; - -# elif defined(USE_PCIE) // For ATtiny85 etc. - // use PinChangeInterrupt no INT0 for pin PB2 - PCMSK = _BV(IR_RECEIVE_PIN); - // clear interrupt bit - GIFR |= 1 << PCIF; - // enable interrupt on next change - GIMSK |= 1 << PCIE; - -# elif defined(USE_PCINT0) - PCICR |= _BV(PCIE0); - PCMSK0 = digitalPinToBitMask(IR_RECEIVE_PIN); -# elif defined(USE_PCINT1) - PCICR |= _BV(PCIE1); - PCMSK1 = digitalPinToBitMask(IR_RECEIVE_PIN); -# elif defined(USE_PCINT2) - PCICR |= _BV(PCIE2); - PCMSK2 = digitalPinToBitMask(IR_RECEIVE_PIN); -# else - return false; -# endif -#endif // defined(USE_ATTACH_INTERRUPT) - return true; -} - -void disablePCIInterruptForTinyReceiver() { -#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN) - pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT); -#endif - -#if defined(USE_ATTACH_INTERRUPT) || defined(USE_ATTACH_INTERRUPT_DIRECT) -# if defined(USE_ATTACH_INTERRUPT) - detachInterrupt(digitalPinToInterrupt(IR_RECEIVE_PIN)); -# else - detachInterrupt(IR_RECEIVE_PIN); -# endif - -#else -# if defined(USE_INT0) - // clear interrupt bit - EIFR |= 1 << INTF0; - // disable interrupt on next change - EIMSK &= ~(1 << INT0); - -# elif defined(USE_INT1) - // clear interrupt bit - EIFR |= 1 << INTF1; - // disable interrupt on next change - EIMSK &= ~(1 << INT1); - -# elif defined(USE_PCIE) // For ATtiny85 etc. - // clear interrupt bit - GIFR |= 1 << PCIF; - // disable interrupt on next change - GIMSK &= ~(1 << PCIE); - -# elif defined(USE_PCINT0) - PCICR &= ~(_BV(PCIE0)); -# elif defined(USE_PCINT1) - PCICR &= ~(_BV(PCIE1)); -# elif defined(USE_PCINT2) - PCICR &= ~(_BV(PCIE2)); - -# endif -#endif // defined(USE_ATTACH_INTERRUPT) -} - -/* - * Specify the right INT0, INT1 or PCINT0 interrupt vector according to different pins and cores. - * The default value of TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT is set in TinyIRReceiver.h - */ -#if !(defined(USE_ATTACH_INTERRUPT) || defined(USE_ATTACH_INTERRUPT_DIRECT)) -# if defined(USE_INT0) -ISR(INT0_vect) - -# elif defined(USE_INT1) -ISR(INT1_vect) - -# elif defined(USE_PCIE) // For ATtiny85 etc. -// on ATtinyX5 we do not have a INT1_vect but we can use the PCINT0_vect -ISR(PCINT0_vect) - -# elif defined(USE_PCINT0) -ISR(PCINT0_vect) -# elif defined(USE_PCINT1) -ISR(PCINT1_vect) -# elif defined(USE_PCINT2) -ISR(PCINT2_vect) -# else -void dummyFunctionToAvoidCompilerErrors() -# endif -{ - IRPinChangeInterruptHandler(); -} -#endif // !(defined(USE_ATTACH_INTERRUPT) || defined(USE_ATTACH_INTERRUPT_DIRECT)) - -/** @}*/ - -#if defined(LOCAL_DEBUG_ATTACH_INTERRUPT) -#undef LOCAL_DEBUG_ATTACH_INTERRUPT -#endif -#if defined(LOCAL_TRACE_STATE_MACHINE) -#undef LOCAL_TRACE_STATE_MACHINE -#endif - -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _TINY_IR_RECEIVER_HPP diff --git a/IRremote/src/TinyIRSender.hpp b/IRremote/src/TinyIRSender.hpp deleted file mode 100644 index 0672383bb173c936775e2c94721d94902b8e70c9..0000000000000000000000000000000000000000 --- a/IRremote/src/TinyIRSender.hpp +++ /dev/null @@ -1,290 +0,0 @@ -/* - * TinyIRSender.hpp - * - * Sends IR protocol data of NEC and FAST protocol using bit banging. - * NEC is the protocol of most cheap remote controls for Arduino. - * - * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header. - * FAST Protocol characteristics: - * - Bit timing is like NEC or JVC - * - The header is shorter, 3156 vs. 12500 - * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command, - * leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms. - * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance. - * - * - * This file is part of IRMP https://github.com/IRMP-org/IRMP. - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -#ifndef _TINY_IR_SENDER_HPP -#define _TINY_IR_SENDER_HPP - -#include <Arduino.h> - -//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif -#include "TinyIR.h" // Defines protocol timings - -#include "digitalWriteFast.h" -/** \addtogroup TinySender Minimal sender for NEC and FAST protocol - * @{ - */ - -/* - * Generate 38 kHz IR signal by bit banging - */ -void sendMark(uint8_t aSendPin, unsigned int aMarkMicros) { - unsigned long tStartMicros = micros(); - unsigned long tNextPeriodEnding = tStartMicros; - unsigned long tMicros; - do { - /* - * Generate pulse - */ - noInterrupts(); // do not let interrupts extend the short on period - digitalWriteFast(aSendPin, HIGH); - delayMicroseconds(8); // 8 us for a 30 % duty cycle for 38 kHz - digitalWriteFast(aSendPin, LOW); - interrupts(); // Enable interrupts - to keep micros correct- for the longer off period 3.4 us until receive ISR is active (for 7 us + pop's) - - /* - * PWM pause timing and end check - * Minimal pause duration is 4.3 us - */ - tNextPeriodEnding += 26; // for 38 kHz - do { - tMicros = micros(); // we have only 4 us resolution for AVR @16MHz - /* - * Exit the forever loop if aMarkMicros has reached - */ - unsigned int tDeltaMicros = tMicros - tStartMicros; -#if defined(__AVR__) - // Just getting variables and check for end condition takes minimal 3.8 us - if (tDeltaMicros >= aMarkMicros - (112 / (F_CPU / MICROS_IN_ONE_SECOND))) { // To compensate for call duration - 112 is an empirical value -#else - if (tDeltaMicros >= aMarkMicros) { - #endif - return; - } - } while (tMicros < tNextPeriodEnding); - } while (true); -} - -/* - * Send NEC with 16 bit command, even if aCommand < 0x100 - * @param aAddress - The 16 bit address to send. - * @param aCommand - The 16 bit command to send. - * @param aNumberOfRepeats - Number of repeats send at a period of 110 ms. - */ -void sendONKYO(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats) { - pinModeFast(aSendPin, OUTPUT); - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - unsigned long tStartOfFrameMillis = millis(); - - sendMark(aSendPin, NEC_HEADER_MARK); -#if !defined(ENABLE_NEC2_REPEATS) - if (tNumberOfCommands < aNumberOfRepeats + 1) { - // send the NEC special repeat - delayMicroseconds(NEC_REPEAT_HEADER_SPACE); // - 2250 - } else -#endif - { - // send header - delayMicroseconds(NEC_HEADER_SPACE); - LongUnion tData; - tData.UWord.LowWord = aAddress; - tData.UWord.HighWord = aCommand; - // Send data - for (uint_fast8_t i = 0; i < NEC_BITS; ++i) { - sendMark(aSendPin, NEC_BIT_MARK); // constant mark length - if (tData.ULong & 1) { - delayMicroseconds(NEC_ONE_SPACE); - } else { - delayMicroseconds(NEC_ZERO_SPACE); - } - tData.ULong >>= 1; // shift command for next bit - } - } // send stop bit - sendMark(aSendPin, NEC_BIT_MARK); - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - /* - * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration. - */ - auto tFrameDurationMillis = millis() - tStartOfFrameMillis; - if (NEC_REPEAT_PERIOD / 1000 > tFrameDurationMillis) { - delay(NEC_REPEAT_PERIOD / 1000 - tFrameDurationMillis); - } - } - } -} - -/* - * Send NEC with 8 or 16 bit address or data depending on the values of aAddress and aCommand. - * @param aAddress - If aAddress < 0x100 send 8 bit address and 8 bit inverted address, else send 16 bit address. - * @param aCommand - If aCommand < 0x100 send 8 bit command and 8 bit inverted command, else send 16 bit command. - * @param aNumberOfRepeats - Number of repeats send at a period of 110 ms. - */ -void sendNECMinimal(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats) { - sendNEC(aSendPin, aAddress, aCommand, aNumberOfRepeats); // sendNECMinimal() is deprecated -} -void sendNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats) { - pinModeFast(aSendPin, OUTPUT); - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - unsigned long tStartOfFrameMillis = millis(); - - sendMark(aSendPin, NEC_HEADER_MARK); -#if !defined(ENABLE_NEC2_REPEATS) - if (tNumberOfCommands < aNumberOfRepeats + 1) { - // send the NEC special repeat - delayMicroseconds(NEC_REPEAT_HEADER_SPACE); // - 2250 - } else -#endif - { - // send header - delayMicroseconds(NEC_HEADER_SPACE); - LongUnion tData; - /* - * The compiler is intelligent and removes the code for "(aAddress > 0xFF)" if we are called with an uint8_t address :-). - * Using an uint16_t address requires additional 28 bytes program memory. - */ - if (aAddress > 0xFF) { - tData.UWord.LowWord = aAddress; - } else { - tData.UByte.LowByte = aAddress; // LSB first - tData.UByte.MidLowByte = ~aAddress; - } - if (aCommand > 0xFF) { - tData.UWord.HighWord = aCommand; - } else { - tData.UByte.MidHighByte = aCommand; - tData.UByte.HighByte = ~aCommand; // LSB first - } - // Send data - for (uint_fast8_t i = 0; i < NEC_BITS; ++i) { - sendMark(aSendPin, NEC_BIT_MARK); // constant mark length - - if (tData.ULong & 1) { - delayMicroseconds(NEC_ONE_SPACE); - } else { - delayMicroseconds(NEC_ZERO_SPACE); - } - tData.ULong >>= 1; // shift command for next bit - } - } // send stop bit - sendMark(aSendPin, NEC_BIT_MARK); - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - /* - * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration. - */ - auto tFrameDurationMillis = millis() - tStartOfFrameMillis; - if (NEC_REPEAT_PERIOD / 1000 > tFrameDurationMillis) { - delay(NEC_REPEAT_PERIOD / 1000 - tFrameDurationMillis); - } - } - } -} - -/* - * LSB first, send header, command, inverted command and stop bit - */ -void sendFast8BitAndParity(uint8_t aSendPin, uint8_t aCommand, uint_fast8_t aNumberOfRepeats) { - sendFAST(aSendPin, aCommand, aNumberOfRepeats); -} - -/* - * LSB first, send header, 16 bit command or 8 bit command, inverted command and stop bit - */ -void sendFAST(uint8_t aSendPin, uint16_t aCommand, uint_fast8_t aNumberOfRepeats) { - pinModeFast(aSendPin, OUTPUT); - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - unsigned long tStartOfFrameMillis = millis(); - - // send header - sendMark(aSendPin, FAST_HEADER_MARK); - delayMicroseconds(FAST_HEADER_SPACE); - uint16_t tData; - /* - * The compiler is intelligent and removes the code for "(aCommand > 0xFF)" if we are called with an uint8_t command :-). - * Using an uint16_t command requires additional 56 bytes program memory. - */ - if (aCommand > 0xFF) { - tData = aCommand; - } else { - tData = aCommand | (((uint8_t) (~aCommand)) << 8); // LSB first - } - // Send data - for (uint_fast8_t i = 0; i < FAST_BITS; ++i) { - sendMark(aSendPin, FAST_BIT_MARK); // constant mark length - - if (tData & 1) { - delayMicroseconds(FAST_ONE_SPACE); - } else { - delayMicroseconds(FAST_ZERO_SPACE); - } - tData >>= 1; // shift command for next bit - } - // send stop bit - sendMark(aSendPin, FAST_BIT_MARK); - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - /* - * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration. - */ - auto tFrameDurationMillis = millis() - tStartOfFrameMillis; - if (FAST_REPEAT_PERIOD / 1000 > tFrameDurationMillis) { - delay(FAST_REPEAT_PERIOD / 1000 - tFrameDurationMillis); - } - } - } -} - -/** @}*/ - -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _TINY_IR_SENDER_HPP diff --git a/IRremote/src/ac_LG.h b/IRremote/src/ac_LG.h deleted file mode 100644 index 4f56de7b765d642bdff4d959afcfb4d49b2609ec..0000000000000000000000000000000000000000 --- a/IRremote/src/ac_LG.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * ac_LG.h - * - * Contains definitions for receiving and sending LG air conditioner IR Protocol - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2021 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -// see also: https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h -#ifndef _AC_LG_H -#define _AC_LG_H - -#include <Arduino.h> - -/** \addtogroup Airconditoners Air conditioner special code - * @{ - */ - -#define LG_ADDRESS 0x88 - -/* - * The basic IR command codes - * Parts of the codes (especially the lower nibbles) may be modified to contain - * additional information like temperature, fan speed and minutes. - */ -#define LG_SWITCH_ON_MASK 0x0800 // This bit is masked if we switch Power on -#define LG_MODE_COOLING 0x0800 // Temperature and fan speed in lower nibbles -#define LG_MODE_DEHUMIDIFIYING 0x0990 // sets also temperature to 24 and fan speed to 0 -#define LG_MODE_FAN 0x0A30 // sets also temperature to 18 -#define LG_MODE_AUTO 0x0B00 // The remote initially sets also temperature to 22 and fan speed to 4 -#define LG_MODE_HEATING 0x0C00 // Temperature and fan speed in lower nibbles -#define LG_ENERGY_SAVING_ON 0x1004 -#define LG_ENERGY_SAVING_OFF 0x1005 -#define LG_JET_ON 0x1008 -#define LG_WALL_SWING_ON 0x1314 -#define LG_WALL_SWING_OFF 0x1315 -#define LG_SWING_ON 0x1316 // not verified, for AKB73757604 -#define LG_SWING_OFF 0x1317 // not verified, for AKB73757604 -#define LG_TIMER_ON 0x8000 // relative minutes in lower nibbles -#define LG_TIMER_OFF 0x9000 // relative minutes in lower nibbles -#define LG_SLEEP 0xA000 // relative minutes in lower nibbles -#define LG_CLEAR_ALL 0xB000 // Timers and sleep -#define LG_POWER_DOWN 0xC005 -#define LG_LIGHT 0xC00A -#define LG_AUTO_CLEAN_ON 0xC00B -#define LG_AUTO_CLEAN_OFF 0xC00C - -/* - * Commands as printed in menu and uses as first parameter for sendCommandAndParameter - */ -#define LG_COMMAND_OFF '0' -#define LG_COMMAND_ON '1' -#define LG_COMMAND_SWING 's' -#define LG_COMMAND_AUTO_CLEAN 'a' -#define LG_COMMAND_JET 'j' -#define LG_COMMAND_ENERGY 'e' -#define LG_COMMAND_LIGHT 'l' -#define LG_COMMAND_FAN_SPEED 'f' -#define LG_COMMAND_TEMPERATURE 't' -#define LG_COMMAND_TEMPERATURE_PLUS '+' -#define LG_COMMAND_TEMPERATURE_MINUS '-' -#define LG_COMMAND_MODE 'm' -#define LG_COMMAND_SLEEP 'S' -#define LG_COMMAND_TIMER_ON 'T' -#define LG_COMMAND_TIMER_OFF 'O' -#define LG_COMMAND_CLEAR_ALL 'C' - -/* - * The modes are encoded as character values for easy printing :-) - */ -#define AC_MODE_COOLING 'c' -#define AC_MODE_DEHUMIDIFIYING 'd' -#define AC_MODE_FAN 'f' -#define AC_MODE_AUTO 'a' -#define AC_MODE_HEATING 'h' - -// see https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h -union LGProtocol { - uint32_t raw; ///< The state of the IR remote in IR code form. - struct { - uint32_t Checksum :4; - uint32_t Fan :3; - uint32_t FanExt :1; - uint32_t Temp :4; - uint32_t Mode :4; // highest bit 1 => Set temperature and ventilation by mode - uint32_t Function :3; - uint32_t SwitchOnMask :1; /* Content is 0 when switching from off to on */ - uint32_t Signature :8; /* Content is 0x88, LG_ADDRESS */ - }; -}; - -class Aircondition_LG { -public: - bool sendCommandAndParameter(char aCommand, int aParameter); - void setType(bool aIsWallType); - void printMenu(Print *aSerial); - void sendIRCommand(uint16_t aCommand); - void sendTemperatureFanSpeedAndMode(); - /* - * Internal state of the air condition - */ -#define LG_IS_WALL_TYPE true -#define LG_IS_TOWER_TYPE false - bool ACIsWallType; // false : TOWER, true : WALL - bool PowerIsOn; - - // These value are encoded and sent by AC_LG_SendCommandAndParameter() - uint8_t FanIntensity = 1; // 0 -> low, 4 high, 5 -> cycle - uint8_t Temperature = 22; // temperature : 18 ~ 30 - uint8_t Mode = AC_MODE_COOLING; - bool useLG2Protocol = false; -}; - -/** @}*/ -#endif // _AC_LG_H diff --git a/IRremote/src/ac_LG.hpp b/IRremote/src/ac_LG.hpp deleted file mode 100644 index d5037c2d7155f5b2ccb9b3ea0da6482253930af9..0000000000000000000000000000000000000000 --- a/IRremote/src/ac_LG.hpp +++ /dev/null @@ -1,322 +0,0 @@ -/* - * ac_LG.hpp - * - * Contains functions for sending LG air conditioner IR Protocol - * There is no state plausibility check, e.g. you can send fan speed in Mode D and change temperature in mode F - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2021-2022 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _AC_LG_HPP -#define _AC_LG_HPP -#include <Arduino.h> - -#if defined(INFO) && !defined(LOCAL_INFO) -#define LOCAL_INFO -#else -//#define LOCAL_INFO // This enables info output only for this file -#endif -//#define DEBUG // for more output from the LG-AC driver. -#include "IRremoteInt.h" -#include "ac_LG.h" // useful constants -#include "LongUnion.h" - -/** \addtogroup Airconditoners Air conditioner special code - * @{ - */ -/* - * LG remote measurements: Type AKB73315611, Ver1.1 from 2011.03.01 - * Internal crystal: 4 MHz - * Header: 8.9 ms mark 4.15 ms space - * Data: 500 / 540 and 500 / 1580; - * Clock is nor synchronized with gate so you have 19 and sometimes 19 and a spike pulses for mark - * Duty: 9 us on 17 us off => around 33 % duty - * NO REPEAT: If value like temperature has changed during long press, the last value is send at button release - * If you do a double press -tested with the fan button-, the next value can be sent after 118 ms - */ -#define SIZE_OF_FAN_SPEED_MAPPING_TABLE 4 -const int AC_FAN_TOWER[SIZE_OF_FAN_SPEED_MAPPING_TABLE] = { 0, 4, 6, 6 }; // last dummy entry to avoid out of bounds access -const int AC_FAN_WALL[SIZE_OF_FAN_SPEED_MAPPING_TABLE] = { 0, 2, 4, 5 }; // 0 -> low, 4 high, 5 -> cycle - -void Aircondition_LG::setType(bool aIsWallType) { - ACIsWallType = aIsWallType; -#if defined(LOCAL_INFO) - Serial.print(F("Set wall type to ")); - Serial.println(aIsWallType); -#endif -} - -void Aircondition_LG::printMenu(Print *aSerial) { - aSerial->println(); - aSerial->println(); - aSerial->println(F("Type command and optional parameter without a separator")); - aSerial->println(F("0 Off")); - aSerial->println(F("1 On")); - aSerial->println(F("s Swing <0 or 1>")); - aSerial->println(F("a Auto clean <0 or 1>")); - aSerial->println(F("j Jet on")); - aSerial->println(F("e Energy saving <0 or 1>")); - aSerial->println(F("l Lights toggle")); - aSerial->println(F("f Fan speed <0 to 2 or 3 for cycle>")); - aSerial->println(F("t Temperature <18 to 30> degree")); - aSerial->println(F("+ Temperature + 1")); - aSerial->println(F("- Temperature - 1")); - aSerial->println(F("m <c(ool) or a(uto) or d(ehumidifying) or h(eating) or f(an) mode>")); - aSerial->println(F("S Sleep after <0 to 420> minutes")); - aSerial->println(F("T Timer on after <0 to 1439> minutes")); - aSerial->println(F("O Timer off after <0 to 1439> minutes")); - aSerial->println(F("C Clear all timer and sleep")); - aSerial->println(F("e.g. \"s1\" or \"t23\" or \"mc\" or \"O60\" or \"+\"")); - aSerial->println(F("No plausibility check is made!")); - aSerial->println(); -} - -/* - * Send repeat - * Repeat commands should be sent in a 110 ms raster. - * @param aCommand one of LG_COMMAND_OFF, LG_COMMAND_ON etc. - */ -bool Aircondition_LG::sendCommandAndParameter(char aCommand, int aParameter) { - // Commands without parameter - switch (aCommand) { - case LG_COMMAND_OFF: // off - sendIRCommand(LG_POWER_DOWN); - PowerIsOn = false; - return true; - - case LG_COMMAND_ON: // on - PowerIsOn = false; // set to false in order to suppress on bit - sendTemperatureFanSpeedAndMode(); - return true; - - case LG_COMMAND_JET: - IR_DEBUG_PRINTLN(F("Send jet on")); - sendIRCommand(LG_JET_ON); - return true; - - case LG_COMMAND_LIGHT: - sendIRCommand(LG_LIGHT); - return true; - - case LG_COMMAND_CLEAR_ALL: - sendIRCommand(LG_CLEAR_ALL); - return true; - - case LG_COMMAND_TEMPERATURE_PLUS: - if (18 <= Temperature && Temperature <= 29) { - Temperature++; - sendTemperatureFanSpeedAndMode(); - } else { - return false; - } - return true; - - case LG_COMMAND_TEMPERATURE_MINUS: - if (19 <= Temperature && Temperature <= 30) { - Temperature--; - sendTemperatureFanSpeedAndMode(); - } else { - return false; - } - return true; - - } - - PowerIsOn = true; - - /* - * Now the commands which require a parameter - */ - if (aParameter < 0) { - IR_DEBUG_PRINT(F("Error: Parameter is less than 0")); - return false; - } - switch (aCommand) { - - case LG_COMMAND_MODE: - Mode = aParameter + '0'; - sendTemperatureFanSpeedAndMode(); - break; - - case LG_COMMAND_SWING: - IR_DEBUG_PRINT(F("Send air swing=")); - IR_DEBUG_PRINTLN(aParameter); - if (ACIsWallType) { - if (aParameter) { - sendIRCommand(LG_WALL_SWING_ON); - } else { - sendIRCommand(LG_WALL_SWING_OFF); - } - } else { - if (aParameter) { - sendIRCommand(LG_SWING_ON); - } else { - sendIRCommand(LG_SWING_OFF); - } - } - break; - - case LG_COMMAND_AUTO_CLEAN: - IR_DEBUG_PRINT(F("Send auto clean=")); - IR_DEBUG_PRINTLN(aParameter); - if (aParameter) { - sendIRCommand(LG_AUTO_CLEAN_ON); - } else { - sendIRCommand(LG_AUTO_CLEAN_OFF); - } - break; - - case LG_COMMAND_ENERGY: - IR_DEBUG_PRINT(F("Send energy saving on=")); - IR_DEBUG_PRINTLN(aParameter); - if (aParameter) { - sendIRCommand(LG_ENERGY_SAVING_ON); - } else { - sendIRCommand(LG_ENERGY_SAVING_OFF); - } - break; - - case LG_COMMAND_FAN_SPEED: - if (aParameter < SIZE_OF_FAN_SPEED_MAPPING_TABLE) { - FanIntensity = aParameter; - sendTemperatureFanSpeedAndMode(); - } else { - return false; - } - break; - - case LG_COMMAND_TEMPERATURE: - if (18 <= aParameter && aParameter <= 30) { - Temperature = aParameter; - sendTemperatureFanSpeedAndMode(); - } else { - return false; - } - break; - - case LG_COMMAND_SLEEP: - // 420 = maximum I have recorded - if (aParameter <= 420) { - sendIRCommand(LG_SLEEP + aParameter); - } else { - return false; - } - break; - - case LG_COMMAND_TIMER_ON: - // 1440 = minutes of a day - if (aParameter <= 1439) { - sendIRCommand(LG_TIMER_ON + aParameter); - } else { - return false; - } - break; - - case LG_COMMAND_TIMER_OFF: - if (aParameter <= 1439) { - sendIRCommand(LG_TIMER_OFF + aParameter); - } else { - return false; - } - break; - - default: - return false; - } - return true; -} - -void Aircondition_LG::sendIRCommand(uint16_t aCommand) { - -#if defined(LOCAL_INFO) - Serial.print(F("Send code=0x")); - Serial.print(aCommand, HEX); - Serial.print(F(" | 0b")); - Serial.println(aCommand, BIN); -#endif - - IrSender.sendLG2((uint8_t) LG_ADDRESS, aCommand, 0); -} - -/* - * Takes values from static variables - */ -void Aircondition_LG::sendTemperatureFanSpeedAndMode() { - - uint8_t tTemperature = Temperature; -#if defined(LOCAL_INFO) - Serial.print(F("Send temperature=")); - Serial.print(tTemperature); - Serial.print(F(" fan intensity=")); - Serial.print(FanIntensity); - Serial.print(F(" mode=")); - Serial.println((char )Mode); -#endif - - WordUnion tIRCommand; - tIRCommand.UWord = 0; - - // Temperature is coded in the upper nibble of the LowByte - tIRCommand.UByte.LowByte = ((tTemperature - 15) << 4); // 16 -> 0x00, 18 -> 0x30, 30 -> 0xF0 - - // Fan intensity is coded in the lower nibble of the LowByte - if (ACIsWallType) { - tIRCommand.UByte.LowByte |= AC_FAN_WALL[FanIntensity]; - } else { - tIRCommand.UByte.LowByte |= AC_FAN_TOWER[FanIntensity]; - } - - switch (Mode) { - case AC_MODE_COOLING: - tIRCommand.UByte.HighByte = LG_MODE_COOLING >> 8; - break; - case AC_MODE_HEATING: - tIRCommand.UByte.HighByte = LG_MODE_HEATING >> 8; - break; - case AC_MODE_AUTO: - tIRCommand.UByte.HighByte = LG_MODE_AUTO >> 8; - break; - case AC_MODE_FAN: - tTemperature = 18; - tIRCommand.UByte.HighByte = LG_MODE_FAN >> 8; - break; - case AC_MODE_DEHUMIDIFIYING: - tIRCommand.UWord = LG_MODE_DEHUMIDIFIYING; - break; - default: - break; - } - if (!PowerIsOn) { - // switch on requires masked bit - tIRCommand.UByte.HighByte &= ~(LG_SWITCH_ON_MASK >> 8); - } - PowerIsOn = true; - - sendIRCommand(tIRCommand.UWord); -} - -/** @}*/ -#endif // _AC_LG_HPP diff --git a/IRremote/src/digitalWriteFast.h b/IRremote/src/digitalWriteFast.h deleted file mode 100644 index 1bb8eb507baea642514ca9f5aff09c6952be53ac..0000000000000000000000000000000000000000 --- a/IRremote/src/digitalWriteFast.h +++ /dev/null @@ -1,419 +0,0 @@ -/* - * digitalWriteFast.h - * - * Optimized digital functions for AVR microcontrollers - * by Watterott electronic (www.watterott.com) - * based on https://code.google.com/p/digitalwritefast - * - * License: BSD 3-Clause License (https://opensource.org/licenses/BSD-3-Clause) - */ - -#ifndef __digitalWriteFast_h_ -#define __digitalWriteFast_h_ 1 - -//#define SANGUINO_PINOUT // define for Sanguino pinout - -// general macros/defines -#if !defined(BIT_READ) -# define BIT_READ(value, bit) ((value) & (1UL << (bit))) -#endif -#if !defined(BIT_SET) -# define BIT_SET(value, bit) ((value) |= (1UL << (bit))) -#endif -#if !defined(BIT_CLEAR) -# define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit))) -#endif -#if !defined(BIT_WRITE) -# define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit)) -#endif - -#include <Arduino.h> // declarations for the fallback to digitalWrite(), digitalRead() etc. - -// --- Arduino Mega and ATmega128x/256x based boards --- -#if (defined(ARDUINO_AVR_MEGA) || \ - defined(ARDUINO_AVR_MEGA1280) || \ - defined(ARDUINO_AVR_MEGA2560) || \ - defined(__AVR_ATmega1280__) || \ - defined(__AVR_ATmega1281__) || \ - defined(__AVR_ATmega2560__) || \ - defined(__AVR_ATmega2561__)) - -#define __digitalPinToPortReg(P) \ -(((P) >= 22 && (P) <= 29) ? &PORTA : \ -((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \ -(((P) >= 30 && (P) <= 37) ? &PORTC : \ -((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \ -((((P) <= 3) || (P) == 5) ? &PORTE : \ -(((P) >= 54 && (P) <= 61) ? &PORTF : \ -((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \ -((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \ -(((P) == 14 || (P) == 15) ? &PORTJ : \ -(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) - -#define __digitalPinToDDRReg(P) \ -(((P) >= 22 && (P) <= 29) ? &DDRA : \ -((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \ -(((P) >= 30 && (P) <= 37) ? &DDRC : \ -((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \ -((((P) <= 3) || (P) == 5) ? &DDRE : \ -(((P) >= 54 && (P) <= 61) ? &DDRF : \ -((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \ -((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \ -(((P) == 14 || (P) == 15) ? &DDRJ : \ -(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL)))))))))) - -#define __digitalPinToPINReg(P) \ -(((P) >= 22 && (P) <= 29) ? &PINA : \ -((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \ -(((P) >= 30 && (P) <= 37) ? &PINC : \ -((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \ -((((P) <= 3) || (P) == 5) ? &PINE : \ -(((P) >= 54 && (P) <= 61) ? &PINF : \ -((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \ -((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \ -(((P) == 14 || (P) == 15) ? &PINJ : \ -(((P) >= 62 && (P) <= 69) ? &PINK : &PINL)))))))))) - -#define __digitalPinToBit(P) \ -(((P) >= 7 && (P) <= 9) ? (P) - 3 : \ -(((P) >= 10 && (P) <= 13) ? (P) - 6 : \ -(((P) >= 22 && (P) <= 29) ? (P) - 22 : \ -(((P) >= 30 && (P) <= 37) ? 37 - (P) : \ -(((P) >= 39 && (P) <= 41) ? 41 - (P) : \ -(((P) >= 42 && (P) <= 49) ? 49 - (P) : \ -(((P) >= 50 && (P) <= 53) ? 53 - (P) : \ -(((P) >= 54 && (P) <= 61) ? (P) - 54 : \ -(((P) >= 62 && (P) <= 69) ? (P) - 62 : \ -(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \ -(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \ -(((P) == 19) ? 2 : \ -(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \ -(((P) == 2) ? 4 : \ -(((P) == 3 || (P) == 4) ? 5 : 7))))))))))))))) - - -// --- Arduino MightyCore standard pinout --- -#elif (defined(__AVR_ATmega1284P__) || \ - defined(__AVR_ATmega1284__) || \ - defined(__AVR_ATmega644P__) || \ - defined(__AVR_ATmega644A__) || \ - defined(__AVR_ATmega644__) || \ - defined(__AVR_ATmega324PB__) || \ - defined(__AVR_ATmega324PA__) || \ - defined(__AVR_ATmega324P__) || \ - defined(__AVR_ATmega324A__) || \ - defined(__AVR_ATmega164P__) || \ - defined(__AVR_ATmega164A__) || \ - defined(__AVR_ATmega32__) || \ - defined(__AVR_ATmega16__) || \ - defined(__AVR_ATmega8535__)) && \ - !defined(BOBUINO_PINOUT) - -#if defined(__AVR_ATmega324PB__) -#define __digitalPinToPortReg(P) \ -(((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : (((P) >= 24 && (P) <= 31) ? &PORTA : &PORTE)))) -#define __digitalPinToDDRReg(P) \ -(((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : (((P) >= 24 && (P) <= 31) ? &DDRA : &DDRE)))) -#define __digitalPinToPINReg(P) \ -(((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : (((P) >= 24 && (P) <= 31) ? &PINA : &PINE)))) -# if defined(SANGUINO_PINOUT) -#define __digitalPinToBit(P) \ -(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (((P) >= 16 && (P) <= 23) ? (7 - ((P) - 24)) : (P) - 32)))) -# else //MightyCore Pinout -#define __digitalPinToBit(P) \ -(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (((P) >= 16 && (P) <= 23) ? (P) - 24 : (P) - 32)))) -# endif -#elif defined(PORTA) -#define __digitalPinToPortReg(P) \ -(((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA))) -#define __digitalPinToDDRReg(P) \ -(((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : &DDRA))) -#define __digitalPinToPINReg(P) \ -(((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : &PINA))) -# if defined(SANGUINO_PINOUT) -#define __digitalPinToBit(P) \ -(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (7 - ((P) - 24))))) -# else //MightyCore Pinout -#define __digitalPinToBit(P) \ -(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24))) -# endif -#else -#define __digitalPinToPortReg(P) \ -(((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : &PORTC)) -#define __digitalPinToDDRReg(P) \ -(((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : &DDRC)) -#define __digitalPinToPINReg(P) \ -(((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : &PINC)) -# if defined(SANGUINO_PINOUT) -#define __digitalPinToBit(P) \ -(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (7 - ((P) - 24))))) -# else //MightyCore Pinout -#define __digitalPinToBit(P) \ -(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24))) -# endif -#endif - - -// --- Arduino Leonardo and ATmega16U4/32U4 based boards --- -#elif (defined(ARDUINO_AVR_LEONARDO) || \ - defined(__AVR_ATmega16U4__) || \ - defined(__AVR_ATmega32U4__)) -# if defined(TEENSYDUINO) - -#define __digitalPinToPortReg(P) \ -((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &PORTB : (((P) == 9 || (P) == 10) ? &PORTC : (((P) >= 16 && (P) <= 21)) ? &PORTF : &PORTD)) -#define __digitalPinToDDRReg(P) \ -((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &DDRB : (((P) == 9 || (P) == 10) ? &DDRC : (((P) >= 16 && (P) <= 21)) ? &DDRF : &DDRD)) -#define __digitalPinToPINReg(P) \ -((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &PINB : (((P) == 9 || (P) == 10) ? &PINC : (((P) >= 16 && (P) <= 21)) ? &PINF : &PIND)) -#define __digitalPinToBit(P) \ -(((P) <= 3) ? (P) : \ -(((P) == 4 || (P) == 12) ? 7 : \ -(((P) <= 8) ? (P) - 5 : \ -(((P) <= 10) ? (P) - 3 : \ -(((P) == 11) ? 6 : \ -(((P) <= 15) ? (P) - 9 : \ -(((P) <= 19) ? 23 - (P) : \ -(((P) <= 21) ? 21 - (P) : (P) - 18)))))))) -# else - -#define __digitalPinToPortReg(P) \ -((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PORTD : (((P) == 5 || (P) == 13) ? &PORTC : (((P) >= 18 && (P) <= 23)) ? &PORTF : (((P) == 7) ? &PORTE : &PORTB))) -#define __digitalPinToDDRReg(P) \ -((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &DDRD : (((P) == 5 || (P) == 13) ? &DDRC : (((P) >= 18 && (P) <= 23)) ? &DDRF : (((P) == 7) ? &DDRE : &DDRB))) -#define __digitalPinToPINReg(P) \ -((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PIND : (((P) == 5 || (P) == 13) ? &PINC : (((P) >= 18 && (P) <= 23)) ? &PINF : (((P) == 7) ? &PINE : &PINB))) -#define __digitalPinToBit(P) \ -(((P) >= 8 && (P) <= 11) ? (P) - 4 : \ -(((P) >= 18 && (P) <= 21) ? 25 - (P) : \ -(((P) == 0) ? 2 : (((P) == 1) ? 3 : (((P) == 2) ? 1 : (((P) == 3) ? 0 : (((P) == 4) ? 4 : (((P) == 6) ? 7 : (((P) == 13) ? 7 : \ -(((P) == 14) ? 3 : (((P) == 15) ? 1 : (((P) == 16) ? 2 : (((P) == 17) ? 0 : (((P) == 22) ? 1 : (((P) == 23) ? 0 : \ -(((P) == 24) ? 4 : (((P) == 25) ? 7 : (((P) == 26) ? 4 : (((P) == 27) ? 5 : 6 ))))))))))))))))))) -# endif - -// --- Arduino Uno and ATmega168/328 based boards --- -#elif (defined(ARDUINO_AVR_UNO) || \ - defined(ARDUINO_AVR_DUEMILANOVE) || \ - defined(__AVR_ATmega8__) || \ - defined(__AVR_ATmega48__) || \ - defined(__AVR_ATmega48P__) || \ - defined(__AVR_ATmega48PB__) || \ - defined(__AVR_ATmega88P__) || \ - defined(__AVR_ATmega88PB__) || \ - defined(__AVR_ATmega168__) || \ - defined(__AVR_ATmega168PA__) || \ - defined(__AVR_ATmega168PB__) || \ - defined(__AVR_ATmega328__) || \ - defined(__AVR_ATmega328P__) || \ - defined(__AVR_ATmega328PB__)) - -#if defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88PB__) || defined(__AVR_ATmega168PB__) || defined(__AVR_ATmega328PB__) -#define __digitalPinToPortReg(P) \ -(((P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE))) -#define __digitalPinToDDRReg(P) \ -(((P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE))) -#define __digitalPinToPINReg(P) \ -(((P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE))) -#define __digitalPinToBit(P) \ -(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (((P) >= 14 && (P) <= 19) ? (P) - 14 : (((P) >= 20 && (P) <= 21) ? (P) - 18 : (P) - 22)))) -#else -#define __digitalPinToPortReg(P) \ -(((P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC)) -#define __digitalPinToDDRReg(P) \ -(((P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC)) -#define __digitalPinToPINReg(P) \ -(((P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC)) -#define __digitalPinToBit(P) \ -(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14)) -#endif - -// --- Arduino Uno WiFi Rev 2, Nano Every --- -#elif defined(__AVR_ATmega4809__) - -#define __digitalPinToPortReg(P) \ -(((P) == 2 || (P) == 7 ) ? &VPORTA.OUT : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.OUT : ((P) == 4) ? &VPORTC.OUT : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.OUT : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.OUT : &VPORTF.OUT) -#define __digitalPinToDDRReg(P) \ -(((P) == 2 || (P) == 7 ) ? &VPORTA.DIR : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.DIR : ((P) == 4) ? &VPORTC.DIR : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.DIR : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.DIR : &VPORTF.DIR) -#define __digitalPinToPINReg(P) \ -(((P) == 2 || (P) == 7 ) ? &VPORTA.IN : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.IN : ((P) == 4) ? &VPORTC.IN : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.IN : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.IN : &VPORTF.IN) -#define __digitalPinToBit(P) \ -(((P) == 2 || (P) == 9 || (P) == 11 || (P) == 17) ? 0 : ((P) == 7 || (P) == 10 || (P) == 12 || (P) == 16) ? 1 : ((P) == 5 || (P) == 13 || (P) == 15 || (P) == 18) ? 2 : ((P) == 9 || (P) == 14 || (P) == 19) ? 3 : ((P) == 6 || (P) == 20) ? 4 : ((P) == 3 || (P) == 21) ? 5 : 6 ) - - -// TinyCore -// https://raw.githubusercontent.com/xukangmin/TinyCore/master/avr/package/package_tinycore_index.json -// https://docs.tinycore.dev/en/latest/ -#elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) -#define __digitalPinToPortReg(P) ((P) <= 5 ? &VPORTB.OUT : ((P) <= 9 ? &VPORTC.OUT : ((P) <= 16 ? &VPORTA.OUT : ((P) <= 18 ? &VPORTB.OUT : &VPORTC.OUT)))) -#define __digitalPinToDDRReg(P) ((P) <= 5 ? &VPORTB.DIR : ((P) <= 9 ? &VPORTC.DIR : ((P) <= 16 ? &VPORTA.DIR : ((P) <= 18 ? &VPORTB.DIR : &VPORTC.DIR)))) -#define __digitalPinToPINReg(P) ((P) <= 5 ? &VPORTB.IN : ((P) <= 9 ? &VPORTC.IN : ((P) <= 16 ? &VPORTA.IN : ((P) <= 18 ? &VPORTB.IN : &VPORTC.IN)))) -#define __digitalPinToBit(P) ( (P) <= 3 ? (3 - P) : ((P) <= 5 ? (P) : ((P) <= 9 ? (P - 6) : ((P) <= 16 ? ((P) - 9) : ((P) <= 18 ? ((P) - 11) : ((P) - 15))))) ) - -#elif defined(__AVR_ATtiny1614__) -#define __digitalPinToPortReg(P) ((P) <= 3 ? &VPORTA.OUT : ((P) <= 7 ? &VPORTB.OUT : &VPORTA.OUT)) -#define __digitalPinToDDRReg(P) ((P) <= 3 ? &VPORTA.DIR : ((P) <= 7 ? &VPORTB.DIR : &VPORTA.DIR)) -#define __digitalPinToPINReg(P) ((P) <= 3 ? &VPORTA.IN : ((P) <= 7 ? &VPORTB.IN : &VPORTA.IN)) -#define __digitalPinToBit(P) ( (P) <= 3 ? (P + 4) : ((P) <= 7 ? (7 - P) : ((P) <= 10 ? (P - 7) : (P) - 11)) ) - -#elif defined(__AVR_ATtiny816__) -// https://github.com/Arduino-IRremote/Arduino-IRremote/discussions/1029 -#define __digitalPinToPortReg(P) ((P) <= 3 ? &VPORTA.OUT : ((P) <= 9 ? &VPORTB.OUT : ((P) <= 13 ? &VPORTC.OUT : ((P) <= 17 ? &VPORTA.OUT : &VPORTC.OUT)))) -#define __digitalPinToDDRReg(P) ((P) <= 3 ? &VPORTA.DIR : ((P) <= 9 ? &VPORTB.DIR : ((P) <= 13 ? &VPORTC.DIR : ((P) <= 17 ? &VPORTA.DIR : &VPORTC.DIR)))) -#define __digitalPinToPINReg(P) ((P) <= 3 ? &VPORTA.IN : ((P) <= 9 ? &VPORTB.IN : ((P) <= 13 ? &VPORTC.IN : ((P) <= 17 ? &VPORTA.IN : &VPORTC.IN)))) -#define __digitalPinToBit(P) ( (P) <= 3 ? (P + 4) : ((P) <= 9 ? (9 - P) : ((P) <= 13 ? (P - 10) : ((P) <= 16 ? (P - 13) : ((P) - 17)))) ) - -// --- ATtinyX5 --- -#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) -// we have only PORTB -#define __digitalPinToPortReg(P) (&PORTB) -#define __digitalPinToDDRReg(P) (&DDRB) -#define __digitalPinToPINReg(P) (&PINB) -#define __digitalPinToBit(P) (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14)) - - -// --- ATtiny88 --- -#elif defined(__AVR_ATtiny88__) -# if defined(ARDUINO_AVR_DIGISPARKPRO) -#define __digitalPinToPortReg(P) ((P) <= 7 ? &PORTD : ((P) <= 14 ? &PORTB : ((P) <= 18 ? &PORTA : &PORTC))) -#define __digitalPinToDDRReg(P) ((P) <= 7 ? &DDRD : ((P) <= 14 ? &DDRB : ((P) <= 18 ? &DDRA : &DDRC))) -#define __digitalPinToPINReg(P) ((P) <= 7 ? &PIND : ((P) <= 14 ? &PINB : ((P) <= 18 ? &PINA : &PINC))) -#define __digitalPinToBit(P) ( (P) <= 7 ? (P) : ((P) <= 13 ? ((P) - 8) : ((P) == 14 ? 7 : ((P) <= 16 ? ((P) - 14) : ((P) <= 18 ? ((P) - 17) : ((P) == 25 ? 7 : ((P) - 19)))))) ) -# else -#define __digitalPinToPortReg(P) ((P) <= 7 ? &PORTD : ((P) <= 15 ? &PORTB : ((P) <= 22 ? &PORTC : ((P) <= 26 ? &PORTA : &PORTC)))) -#define __digitalPinToDDRReg(P) ((P) <= 7 ? &DDRD : ((P) <= 15 ? &DDRB : ((P) <= 22 ? &DDRC : ((P) <= 26 ? &DDRA : &DDRC)))) -#define __digitalPinToPINReg(P) ((P) <= 7 ? &PIND : ((P) <= 15 ? &PINB : ((P) <= 22 ? &PINC : ((P) <= 26 ? &PINA : &PINC)))) -#define __digitalPinToBit(P) ((P) <= 15 ? ((P) & 0x7) : ((P) == 16 ? (7) : ((P) <= 22 ? ((P) - 17) : ((P) == 27 ? (6) : ((P) - 23))))) -# endif - - -// --- ATtinyX4 + ATtinyX7 --- -#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) \ - || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -# if defined(ARDUINO_AVR_DIGISPARKPRO) || PIN_PA7 == 5 -// Strange enumeration of pins on Digispark board and core library -#define __digitalPinToPortReg(P) (((P) <= 4) ? &PORTB : &PORTA) -#define __digitalPinToDDRReg(P) (((P) <= 4) ? &DDRB : &DDRA) -#define __digitalPinToPINReg(P) (((P) <= 4) ? &PINB : &PINA) -#define __digitalPinToBit(P) (((P) <= 2) ? (P) : (((P) == 3) ? 6 : (((P) == 4) ? 3 : (((P) == 5) ? 7 : (P) - 6 )))) -# else -// ATtinyX4: PORTA for 0 to 7, PORTB for 8 to 11 -// ATtinyX7: PORTA for 0 to 7, PORTB for 8 to 15 -#define __digitalPinToPortReg(P) (((P) <= 7) ? &PORTA : &PORTB) -#define __digitalPinToDDRReg(P) (((P) <= 7) ? &DDRA : &DDRB) -#define __digitalPinToPINReg(P) (((P) <= 7) ? &PINA : &PINB) -# endif -# if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__) -// https://github.com/SpenceKonde/ATTinyCore/blob/v2.0.0-devThis-is-the-head-submit-PRs-against-this/avr/variants/tinyx41_cw/pins_arduino.h#L334 -// Clockwise layout -#define __digitalPinToBit(P) (((P) <= 7) ? (P) : ((P) == 11 ? (3) : 10 - (P))) -# else -#define __digitalPinToBit(P) (((P) <= 7) ? (P) : (P) - 8 ) -# endif - -#endif - - -void NonConstantsUsedForPinModeFast( void ) __attribute__ (( error("Parameter for pinModeFast() function is not constant") )); -void NonConstantsUsedForDigitalWriteFast( void ) __attribute__ (( error("Parameter for digitalWriteFast() function is not constant") )); -void NonConstantsUsedForDigitalToggleFast( void ) __attribute__ (( error("Parameter for digitalToggleFast() function is not constant") )); -int NonConstantsUsedForDigitalReadFast( void ) __attribute__ (( error("Parameter for digitalReadFast() function is not constant") )); - -#if !defined(digitalWriteFast) -# if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPortReg) -# if defined(THROW_ERROR_IF_NOT_FAST) -#define digitalWriteFast(P, V) \ -if (__builtin_constant_p(P)) { \ - BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \ -} else { \ - NonConstantsUsedForDigitalWriteFast(); \ -} -# else -#define digitalWriteFast(P, V) \ -if (__builtin_constant_p(P)) { \ - BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \ -} else { \ - digitalWrite((P), (V)); \ -} -# endif // defined(THROW_ERROR_IF_NOT_FAST) -# else -#define digitalWriteFast digitalWrite -# endif -#endif - -#if !defined(pinModeFast) -# if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPortReg) -# if defined(THROW_ERROR_IF_NOT_FAST) -#define pinModeFast(P, V) \ -if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ - if (V == INPUT_PULLUP) {\ - BIT_CLEAR(*__digitalPinToDDRReg(P), __digitalPinToBit(P)); \ - BIT_SET(*__digitalPinToPortReg(P), __digitalPinToBit(P)); \ - } else { \ - BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \ - } \ -} else { \ - NonConstantsUsedForPinModeFast(); \ -} -# else -#define pinModeFast(P, V) \ -if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ - if (V == INPUT_PULLUP) {\ - BIT_CLEAR(*__digitalPinToDDRReg(P), __digitalPinToBit(P)); \ - BIT_SET(*__digitalPinToPortReg(P), __digitalPinToBit(P)); \ - } else { \ - BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \ - } \ -} else { \ - pinMode((P), (V)); \ -} -# endif // defined(THROW_ERROR_IF_NOT_FAST) -# else -#define pinModeFast pinMode -# endif -#endif // !defined(pinModeFast) - -#if !defined(digitalReadFast) -# if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPINReg) -# if defined(THROW_ERROR_IF_NOT_FAST) -#define digitalReadFast(P) ( (int) __digitalReadFast((P)) ) -// since we have return values, it is easier to implement it by ?: -#define __digitalReadFast(P ) \ - (__builtin_constant_p(P) ) ? \ - (( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ? HIGH:LOW ) : \ - NonConstantsUsedForDigitalReadFast() -# else -#define digitalReadFast(P) ( (int) __digitalReadFast((P)) ) -// since we have return values, it is easier to implement it by ?: -#define __digitalReadFast(P ) \ - (__builtin_constant_p(P) ) ? \ - (( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ? HIGH:LOW ) : \ - digitalRead((P)) -# endif // defined(THROW_ERROR_IF_NOT_FAST) -# else -#define digitalReadFast digitalRead -# endif -#endif // !defined(digitalReadFast) - -#if !defined(digitalToggleFast) -# if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPINReg) -# if defined(THROW_ERROR_IF_NOT_FAST) -#define digitalToggleFast(P) \ -if (__builtin_constant_p(P)) { \ - BIT_SET(*__digitalPinToPINReg(P), __digitalPinToBit(P)); \ -} else { \ - NonConstantsUsedForDigitalToggleFast(); \ -} -# else -#define digitalToggleFast(P) \ -if (__builtin_constant_p(P)) { \ - BIT_SET(*__digitalPinToPINReg(P), __digitalPinToBit(P)); \ -} else { \ - digitalWrite(P, ! digitalRead(P)); \ -} -# endif // defined(THROW_ERROR_IF_NOT_FAST) -# else -#define digitalToggleFast(P) digitalWrite(P, ! digitalRead(P)) -# endif -#endif // !defined(digitalToggleFast) - -#endif //__digitalWriteFast_h_ diff --git a/IRremote/src/ir_BangOlufsen.hpp b/IRremote/src/ir_BangOlufsen.hpp deleted file mode 100644 index 3ccaad45168a8139b6bb684d751107167bd07070..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_BangOlufsen.hpp +++ /dev/null @@ -1,492 +0,0 @@ -/* - * ir_BangOlufsen.hpp - * - * Contains functions for receiving and sending Bang & Olufsen IR and Datalink '86 protocols - * To receive B&O and ENABLE_BEO_WITHOUT_FRAME_GAP is NOT defined, you must set RECORD_GAP_MICROS to - * at least 16000 to accommodate the unusually long 3. start space. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022-2023 Daniel Wallner and Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_BANG_OLUFSEN_HPP -#define _IR_BANG_OLUFSEN_HPP - -//============================================================================== -// -// -// Bang & Olufsen -// -// -//============================================================================== -// https://www.mikrocontroller.net/attachment/33137/datalink.pdf -// https://www.mikrocontroller.net/articles/IRMP_-_english#B&O - -// This protocol is unusual in two ways: - -// 1. The carrier frequency is 455 kHz - -// You can build your own receiver as Bang & Olufsen did (check old schematics) or use a TSOP7000 -// Vishay stopped producing TSOP7000 since 2009 so you will probably only find counterfeits: -// https://www.vishay.com/files/whatsnew/doc/ff_FastFacts_CounterfeitTSOP7000_Dec72018.pdf -// It is also likely that you will need an oscilloscope to debug a counterfeit TSOP7000 -// The specimen used to test this code was very noisy and had a very low output current -// A somewhat working fix was to put a 4n7 capacitor across the output and ground followed by a pnp emitter follower -// Other examples may require a different treatment -// This particular receiver also did receive lower frequencies but rather poorly and with a lower delay than usual -// If you need to parallel a receiver with another one you may need to delay the signal to get in phase with the other receiver - -// 2. A stream of messages can be sent back to back with a new message immediately following the previous stop space - -// It might be that this only happens over IR and not on the datalink protocol -// You can choose to support this or not: - -// Alt 1: Mode with gaps between frames -// Set RECORD_GAP_MICROS to at least 16000 to accommodate the unusually long 3. start space -// Can only receive single messages and back to back repeats will result in overflow - -// Alt 2: Break at start mode -// Define ENABLE_BEO_WITHOUT_FRAME_GAP and set RECORD_GAP_MICROS to 13000 to treat the 3. start space as a gap between messages -// The start of a transmission will result in a dummy decode with 0 bits data followed by the actual messages -// If the receiver is not resumed within a ms or so, partial messages will be decoded -// Debug printing in the wrong place is very likely to break reception -// Make sure to check the number of bits to filter dummy and incomplete messages - -// !!! We assume that the real implementations never set the official first header bit to anything other than 0 !!! -// !!! We therefore use 4 start bits instead of the specified 3 and in turn ignore the first header bit of the specification !!! - -// IR messages are 16 bits long and datalink messages have different lengths -// This implementation supports up to 40 bits total length split into 8 bit data/command and a header/address of variable length -// Header data with more than 16 bits is stored in decodedIRData.extra - -// B&O is a pulse distance protocol, but it has 3 bit values 0, 1 and (equal/repeat) as well as a special start and trailing bit. -// MSB first, 4 start bits + 8 to 16? bit address + 8 bit command + 1 special trailing bit + 1 stop bit. -// Address can be longer than 8 bit. - -/* - * Options for this decoder - */ -//#define ENABLE_BEO_WITHOUT_FRAME_GAP // Requires additional 30 bytes program memory. -//#define SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE // This also supports headers up to 32 bit. Requires additional 150 bytes program memory. -#if defined(DECODE_BEO) -# if defined(ENABLE_BEO_WITHOUT_FRAME_GAP) -# if RECORD_GAP_MICROS > 13000 -#warning If defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to 1300 by "#define RECORD_GAP_MICROS 13000" -# endif -# else -# if RECORD_GAP_MICROS < 16000 -#error If not defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to a value >= 1600 by "#define RECORD_GAP_MICROS 16000" -# endif -# endif -#endif - -#define BEO_DATA_BITS 8 // Command or character - -#define BEO_UNIT 3125 // All timings are in microseconds - -#define BEO_IR_MARK 200 // The length of a mark in the IR protocol -#define BEO_DATALINK_MARK (BEO_UNIT / 2) // The length of a mark in the Datalink protocol - -#define BEO_PULSE_LENGTH_ZERO BEO_UNIT // The length of a one to zero transition -#define BEO_PULSE_LENGTH_EQUAL (2 * BEO_UNIT) // 6250 The length of an equal bit -#define BEO_PULSE_LENGTH_ONE (3 * BEO_UNIT) // 9375 The length of a zero to one transition -#define BEO_PULSE_LENGTH_TRAILING_BIT (4 * BEO_UNIT) // 12500 The length of the stop bit -#define BEO_PULSE_LENGTH_START_BIT (5 * BEO_UNIT) // 15625 The length of the start bit -// It is not allowed to send two ones or zeros, you must send a one or zero and a equal instead. - -//#define BEO_LOCAL_DEBUG -//#define BEO_LOCAL_TRACE - -#ifdef BEO_LOCAL_DEBUG -# define BEO_DEBUG_PRINT(...) Serial.print(__VA_ARGS__) -# define BEO_DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__) -#else -# define BEO_DEBUG_PRINT(...) void() -# define BEO_DEBUG_PRINTLN(...) void() -#endif - -#ifdef BEO_LOCAL_TRACE -# undef BEO_TRACE_PRINT -# undef BEO_TRACE_PRINTLN -# define BEO_TRACE_PRINT(...) Serial.print(__VA_ARGS__) -# define BEO_TRACE_PRINTLN(...) Serial.println(__VA_ARGS__) -#else -# define BEO_TRACE_PRINT(...) void() -# define BEO_TRACE_PRINTLN(...) void() -#endif - -/************************************ - * Start of send and decode functions - ************************************/ - -/* - * TODO aNumberOfRepeats are handled not correctly if ENABLE_BEO_WITHOUT_FRAME_GAP is defined - */ -void IRsend::sendBangOlufsen(uint16_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats, int8_t aNumberOfHeaderBits) { - for (int_fast8_t i = 0; i < aNumberOfRepeats + 1; ++i) { - sendBangOlufsenRaw((uint32_t(aHeader) << 8) | aData, aNumberOfHeaderBits + 8, i != 0); - } -} - -void IRsend::sendBangOlufsenDataLink(uint32_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats, int8_t aNumberOfHeaderBits) { - for (int_fast8_t i = 0; i < aNumberOfRepeats + 1; ++i) { - sendBangOlufsenRawDataLink((uint64_t(aHeader) << 8) | aData, aNumberOfHeaderBits + 8, i != 0, true); - } -} - -/* - * @param aBackToBack If true send data back to back, which cannot be decoded if ENABLE_BEO_WITHOUT_FRAME_GAP is NOT defined - */ -void IRsend::sendBangOlufsenRaw(uint32_t aRawData, int_fast8_t aBits, bool aBackToBack) { -#if defined(USE_NO_SEND_PWM) || defined(SEND_PWM_BY_TIMER) || BEO_KHZ == 38 // BEO_KHZ == 38 is for unit test which runs the B&O protocol with 38 kHz - - /* - * 455 kHz PWM is currently only supported with SEND_PWM_BY_TIMER defined, otherwise maximum is 180 kHz - */ -# if !defined(USE_NO_SEND_PWM) -# if defined(SEND_PWM_BY_TIMER) - enableHighFrequencyIROut (BEO_KHZ); -# elif (BEO_KHZ == 38) - enableIROut (BEO_KHZ); // currently only for unit test -# endif -# endif - -// AGC / Start - 3 bits + first constant 0 header bit described in the official documentation - if (!aBackToBack) { - mark(BEO_IR_MARK); - } - space(BEO_PULSE_LENGTH_ZERO - BEO_IR_MARK); - mark(BEO_IR_MARK); - space(BEO_PULSE_LENGTH_ZERO - BEO_IR_MARK); - mark(BEO_IR_MARK); - space(BEO_PULSE_LENGTH_START_BIT - BEO_IR_MARK); - -// First bit of header is assumed to be a constant 0 to have a fixed state to begin with the equal decisions. -// So this first 0 is treated as the last bit of AGC - mark(BEO_IR_MARK); - space(BEO_PULSE_LENGTH_ZERO - BEO_IR_MARK); - bool tLastBitValueWasOne = false; - -// Header / Data - uint32_t mask = 1UL << (aBits - 1); - for (; mask; mask >>= 1) { - if (tLastBitValueWasOne && !(aRawData & mask)) { - mark(BEO_IR_MARK); - space(BEO_PULSE_LENGTH_ZERO - BEO_IR_MARK); - tLastBitValueWasOne = false; - } else if (!tLastBitValueWasOne && (aRawData & mask)) { - mark(BEO_IR_MARK); - space(BEO_PULSE_LENGTH_ONE - BEO_IR_MARK); - tLastBitValueWasOne = true; - } else { - mark(BEO_IR_MARK); - space(BEO_PULSE_LENGTH_EQUAL - BEO_IR_MARK); - } - } - -// Stop - mark(BEO_IR_MARK); - space(BEO_PULSE_LENGTH_TRAILING_BIT - BEO_IR_MARK); - mark(BEO_IR_MARK); - -#else - (void) aRawData; - (void) aBits; - (void) aBackToBack; -#endif -} - -/* - * Version with 64 bit aRawData, which can send both timings, but costs more program memory - * @param aBackToBack If true send data back to back, which cannot be decoded if ENABLE_BEO_WITHOUT_FRAME_GAP is NOT defined - * @param aUseDatalinkTiming if false it does the same as sendBangOlufsenRaw() - */ -void IRsend::sendBangOlufsenRawDataLink(uint64_t aRawData, int_fast8_t aBits, bool aBackToBack, bool aUseDatalinkTiming) { -#if defined(USE_NO_SEND_PWM) || BEO_KHZ == 38 // BEO_KHZ == 38 is for unit test which runs the B&O protocol with 38 kHz instead 0f 455 kHz - uint16_t tSendBEOMarkLength = aUseDatalinkTiming ? BEO_DATALINK_MARK : BEO_IR_MARK; - - /* - * 455 kHz PWM is currently not supported, maximum is 180 kHz - */ -#if !defined(USE_NO_SEND_PWM) - enableIROut (BEO_KHZ); -#endif - -// AGC / Start - 3 bits + first constant 0 header bit described in the official documentation - if (!aBackToBack) { - mark(tSendBEOMarkLength); - } - space(BEO_PULSE_LENGTH_ZERO - tSendBEOMarkLength); - mark(tSendBEOMarkLength); - space(BEO_PULSE_LENGTH_ZERO - tSendBEOMarkLength); - mark(tSendBEOMarkLength); - space(BEO_PULSE_LENGTH_START_BIT - tSendBEOMarkLength); - -// First bit of header is assumed to be a constant 0 to have a fixed state to begin with the equal decisions. -// So this first 0 is treated as the last bit of AGC - mark(tSendBEOMarkLength); - space(BEO_PULSE_LENGTH_ZERO - tSendBEOMarkLength); - bool tLastBitValueWasOne = false; - -// Header / Data - uint32_t mask = 1UL << (aBits - 1); - for (; mask; mask >>= 1) { - if (tLastBitValueWasOne && !(aRawData & mask)) { - mark(tSendBEOMarkLength); - space(BEO_PULSE_LENGTH_ZERO - tSendBEOMarkLength); - tLastBitValueWasOne = false; - } else if (!tLastBitValueWasOne && (aRawData & mask)) { - mark(tSendBEOMarkLength); - space(BEO_PULSE_LENGTH_ONE - tSendBEOMarkLength); - tLastBitValueWasOne = true; - } else { - mark(tSendBEOMarkLength); - space(BEO_PULSE_LENGTH_EQUAL - tSendBEOMarkLength); - } - } - -// Stop - mark(tSendBEOMarkLength); - space(BEO_PULSE_LENGTH_TRAILING_BIT - tSendBEOMarkLength); - mark(tSendBEOMarkLength); - -#else - (void) aRawData; - (void) aBits; - (void) aUseDatalinkTiming; - (void) aBackToBack; -#endif -} - -#define BEO_MATCH_DELTA (BEO_UNIT / 2 - MICROS_PER_TICK) -static bool matchBeoLength(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) { - const uint16_t tMeasuredMicros = aMeasuredTicks * MICROS_PER_TICK; - return aMatchValueMicros - BEO_MATCH_DELTA < tMeasuredMicros && tMeasuredMicros < aMatchValueMicros + BEO_MATCH_DELTA; -} - -bool IRrecv::decodeBangOlufsen() { -#if defined(ENABLE_BEO_WITHOUT_FRAME_GAP) - if (decodedIRData.rawDataPtr->rawlen != 6 && decodedIRData.rawDataPtr->rawlen < 36) { // 16 bits minimum -#else - if (decodedIRData.rawDataPtr->rawlen < 44) { // 16 bits minimum -#endif - return false; - } - -#if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE) - uint16_t protocolMarkLength = 0; // contains BEO_IR_MARK or BEO_DATALINK_MARK depending of 4. mark received - uint64_t tDecodedRawData = 0; -#else - uint32_t tDecodedRawData = 0; -#endif - uint8_t tLastDecodedBitValue = 0; // the last start bit is assumed to be zero - uint8_t tPulseNumber = 0; - uint8_t tBitNumber = 0; - - BEO_TRACE_PRINT(F("Pre gap: ")); - BEO_TRACE_PRINT(decodedIRData.rawDataPtr->rawbuf[0] * 50); - BEO_TRACE_PRINT(F(" raw len: ")); - BEO_TRACE_PRINTLN(decodedIRData.rawDataPtr->rawlen); - -#if defined(ENABLE_BEO_WITHOUT_FRAME_GAP) - /* - * Check if we have the AGC part of the first frame in a row - */ - if (decodedIRData.rawDataPtr->rawlen == 6) { - if ((matchMark(decodedIRData.rawDataPtr->rawbuf[3], BEO_IR_MARK) - || matchMark(decodedIRData.rawDataPtr->rawbuf[3], BEO_DATALINK_MARK)) - && (matchSpace(decodedIRData.rawDataPtr->rawbuf[4], BEO_PULSE_LENGTH_ZERO - BEO_IR_MARK) - || matchSpace(decodedIRData.rawDataPtr->rawbuf[4], BEO_PULSE_LENGTH_ZERO - BEO_DATALINK_MARK))) { - BEO_TRACE_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_TRACE_PRINTLN(F("B&O: AGC only part detected")); - } else { - return false; // no B&O protocol - } - } else { - /* - * Check if leading gap is trailing bit of first frame - */ - if (!matchSpace(decodedIRData.rawDataPtr->rawbuf[0], BEO_PULSE_LENGTH_START_BIT)) { - BEO_TRACE_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_TRACE_PRINTLN(F(": Leading gap is wrong")); // Leading gap is trailing bit of first frame - return false; // no B&O protocol - } - - if (matchMark(decodedIRData.rawDataPtr->rawbuf[1], BEO_IR_MARK)) { -#if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE) - protocolMarkLength = BEO_IR_MARK; - } else if (matchMark(decodedIRData.rawDataPtr->rawbuf[1], BEO_DATALINK_MARK)) { - protocolMarkLength = BEO_DATALINK_MARK; -#endif - } else { - BEO_TRACE_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_TRACE_PRINTLN(F(": mark length is wrong")); - return false; - } - - // skip first zero header bit - for (uint8_t tRawBufferMarkIndex = 3; tRawBufferMarkIndex < decodedIRData.rawDataPtr->rawlen; tRawBufferMarkIndex += 2) { -#else - for (uint8_t tRawBufferMarkIndex = 1; tRawBufferMarkIndex < decodedIRData.rawDataPtr->rawlen; tRawBufferMarkIndex += 2) { -#endif - - uint16_t markLength = decodedIRData.rawDataPtr->rawbuf[tRawBufferMarkIndex]; - uint16_t spaceLength = decodedIRData.rawDataPtr->rawbuf[tRawBufferMarkIndex + 1]; - - BEO_TRACE_PRINT(tPulseNumber); - BEO_TRACE_PRINT(' '); - BEO_TRACE_PRINT(markLength * MICROS_PER_TICK); - BEO_TRACE_PRINT(' '); - BEO_TRACE_PRINT(spaceLength * MICROS_PER_TICK); - BEO_TRACE_PRINT(F(" (")); - BEO_TRACE_PRINT((markLength + spaceLength) * MICROS_PER_TICK); - BEO_TRACE_PRINTLN(F(") ")); - -#if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP) - /* - * Handle the first 4 start bits - * Check if the 3. bit is the long start bit. If we see the long start bit earlier, synchronize bit counter. - */ - if (tPulseNumber < 4) { - if (tPulseNumber < 2) { - // bit 0 and 1 - if (matchSpace(spaceLength, BEO_PULSE_LENGTH_START_BIT - BEO_IR_MARK)) { - BEO_TRACE_PRINTLN(F(": detected long start bit -> synchronize state now")); - tPulseNumber = 2; - } - } else { - if (tPulseNumber == 3) { - if (matchMark(markLength, BEO_IR_MARK)) { -#if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE) - protocolMarkLength = BEO_IR_MARK; - } else if (matchMark(markLength, BEO_DATALINK_MARK)) { - protocolMarkLength = BEO_DATALINK_MARK; -#endif - } else { - BEO_DEBUG_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_DEBUG_PRINTLN(F(": 4. (start) mark length is wrong")); - return false; - } - } - // bit 2 and 3 - if (!matchBeoLength(markLength + spaceLength, - (tPulseNumber == 2) ? BEO_PULSE_LENGTH_START_BIT : BEO_PULSE_LENGTH_ZERO)) { - BEO_DEBUG_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_DEBUG_PRINTLN(F(": Start length is wrong")); - return false; - } - } - } else { -#endif - - /* - * Decode header / data - * First check for length of mark - */ -#if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE) - if (!matchMark(markLength, protocolMarkLength)) { -#else - if (!matchMark(markLength, BEO_IR_MARK)) { -#endif - BEO_DEBUG_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_DEBUG_PRINTLN(F(": Mark length is wrong")); - return false; - } - - /* - * Check for stop after receiving at least 8 bits for data and 4 bits for header - */ - if (tBitNumber > BEO_DATA_BITS + 4) { - if (matchBeoLength(markLength + spaceLength, BEO_PULSE_LENGTH_TRAILING_BIT)) { - BEO_DEBUG_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_DEBUG_PRINTLN(F(": Trailing bit detected")); - break; - } -#if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP) - if (tRawBufferMarkIndex >= decodedIRData.rawDataPtr->rawlen - 3) { // (rawlen - 3) is index of trailing bit mark - BEO_DEBUG_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_DEBUG_PRINTLN(F(": End of buffer, but no trailing bit detected")); - return false; - } -#endif - } - - /* - * Decode bit - */ - if (tLastDecodedBitValue == 0 && matchBeoLength(markLength + spaceLength, BEO_PULSE_LENGTH_ONE)) { - tLastDecodedBitValue = 1; - } else if (tLastDecodedBitValue == 1 && matchBeoLength(markLength + spaceLength, BEO_PULSE_LENGTH_ZERO)) { - tLastDecodedBitValue = 0; - } else if (!matchBeoLength(markLength + spaceLength, BEO_PULSE_LENGTH_EQUAL)) { - BEO_DEBUG_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_DEBUG_PRINT(F(": Index=")); - BEO_DEBUG_PRINT(tRawBufferMarkIndex); - BEO_DEBUG_PRINT(F(" Length ")); - BEO_DEBUG_PRINT((markLength + spaceLength) * MICROS_PER_TICK); - BEO_DEBUG_PRINTLN(F(" is wrong")); - return false; - } - tDecodedRawData <<= 1; - tDecodedRawData |= tLastDecodedBitValue; - ++tBitNumber; - BEO_TRACE_PRINT(F("Bits ")); - BEO_TRACE_PRINT(tBitNumber); - BEO_TRACE_PRINT(F(" ")); - BEO_TRACE_PRINT(uint32_t(tDecodedRawData >> BEO_DATA_BITS), HEX); - BEO_TRACE_PRINT(F(" ")); - BEO_TRACE_PRINTLN(uint8_t(tDecodedRawData & ((1 << BEO_DATA_BITS) - 1)), HEX); - // End of bit decode -#if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP) - } - -#else - /* - * Check for last bit after decoding it - */ - if (tRawBufferMarkIndex >= decodedIRData.rawDataPtr->rawlen - 3) { // (rawlen - 3) is index of last bit mark - BEO_TRACE_PRINT(::getProtocolString(BANG_OLUFSEN)); - BEO_TRACE_PRINTLN(F(": Last bit reached")); - break; - } -#endif - - ++tPulseNumber; - } -#if defined(ENABLE_BEO_WITHOUT_FRAME_GAP) - } -#endif - - decodedIRData.protocol = BANG_OLUFSEN; - decodedIRData.address = tDecodedRawData >> BEO_DATA_BITS; // lower header tBitNumber - decodedIRData.command = tDecodedRawData & ((1 << BEO_DATA_BITS) - 1); // lower 8 tBitNumber - decodedIRData.extra = tDecodedRawData >> (BEO_DATA_BITS + 16); // upper header tBitNumber - decodedIRData.numberOfBits = tBitNumber; - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; - decodedIRData.decodedRawData = tDecodedRawData; - - return true; -} -#endif // _IR_BANG_OLUFSEN_HPP diff --git a/IRremote/src/ir_BoseWave.hpp b/IRremote/src/ir_BoseWave.hpp deleted file mode 100644 index bac9dcce9a1e2ce614fbdbce2476d078fa6e20aa..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_BoseWave.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * ir_BoseWave.cpp - * - * Contains functions for receiving and sending Bose IR Protocol - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - */ -#ifndef _IR_BOSEWAVE_HPP -#define _IR_BOSEWAVE_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// BBBB OOO SSSS EEEEE -// B B O O S E -// BB B O O SSS EEEE -// B B O O S E -// BBBB OOO SSSS EEEEE -//============================================================================== -// see http://lirc.sourceforge.net/remotes/bose/WAVERADIO -// see: https://www.mikrocontroller.net/articles/IRMP_-_english#BOSE -// -// Support for Bose Wave Radio CD initially provided by https://github.com/uvotguy. -// -// As seen on my trusty oscilloscope, there is no repeat code. Instead, when I -// press and hold a button on my remote, it sends a command, makes a 51.2ms space, -// and resends the command, etc, etc. -// LSB first, 1 start bit + 8 bit data + 8 bit inverted data + 1 stop bit. -#define BOSEWAVE_BITS 16 // Command and inverted command - -#define BOSEWAVE_HEADER_MARK 1014 // 1014 are 39 clock periods (I counted 3 times!) -#define BOSEWAVE_HEADER_SPACE 1468 // 1468(measured), 1456 are 56 clock periods -#define BOSEWAVE_BIT_MARK 520 // 520 are 20 clock periods -#define BOSEWAVE_ZERO_SPACE 468 // 468 are 18 clock periods -#define BOSEWAVE_ONE_SPACE 1468 // 1468(measured), 1456 are 56 clock periods - -#define BOSEWAVE_REPEAT_PERIOD 75000 -#define BOSEWAVE_REPEAT_DISTANCE 50000 -#define BOSEWAVE_MAXIMUM_REPEAT_DISTANCE 62000 - -struct PulseDistanceWidthProtocolConstants BoseWaveProtocolConstants = { BOSEWAVE, BOSEWAVE_KHZ, BOSEWAVE_HEADER_MARK, -BOSEWAVE_HEADER_SPACE, BOSEWAVE_BIT_MARK, BOSEWAVE_ONE_SPACE, BOSEWAVE_BIT_MARK, BOSEWAVE_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST - , (BOSEWAVE_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ - -void IRsend::sendBoseWave(uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - - // send 8 command bits and then 8 inverted command bits LSB first - uint16_t tData = ((~aCommand) << 8) | aCommand; - sendPulseDistanceWidth(&BoseWaveProtocolConstants, tData, BOSEWAVE_BITS, aNumberOfRepeats); -} - -bool IRrecv::decodeBoseWave() { - - if (!checkHeader(&BoseWaveProtocolConstants)) { - return false; - } - - // Check we have enough data +4 for initial gap, start bit mark and space + stop bit mark - if (decodedIRData.rawDataPtr->rawlen != (2 * BOSEWAVE_BITS) + 4) { - IR_DEBUG_PRINT(F("Bose: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 36")); - return false; - } - - if (!decodePulseDistanceWidthData(&BoseWaveProtocolConstants, BOSEWAVE_BITS)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Bose: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - - // Stop bit - if (!matchMark(decodedIRData.rawDataPtr->rawbuf[3 + (2 * BOSEWAVE_BITS)], BOSEWAVE_BIT_MARK)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Bose: ")); - Serial.println(F("Stop bit mark length is wrong")); -#endif - return false; - } - - // Success -// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value - uint16_t tDecodedValue = decodedIRData.decodedRawData; - uint8_t tCommandNotInverted = tDecodedValue & 0xFF; // comes first and is in the lower bits (LSB first :-)) - uint8_t tCommandInverted = tDecodedValue >> 8; - // parity check for command. Use this variant to avoid compiler warning "comparison of promoted ~unsigned with unsigned [-Wsign-compare]" - if ((tCommandNotInverted ^ tCommandInverted) != 0xFF) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Bose: ")); - Serial.println(F("Command and inverted command check failed")); -#endif - return false; - } - decodedIRData.command = tCommandNotInverted; - decodedIRData.numberOfBits = BOSEWAVE_BITS; - decodedIRData.protocol = BOSEWAVE; - - // check for repeat - checkForRepeatSpaceTicksAndSetFlag(BOSEWAVE_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK); - - return true; -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_BOSEWAVE_HPP diff --git a/IRremote/src/ir_Denon.hpp b/IRremote/src/ir_Denon.hpp deleted file mode 100644 index bfb48a6dfd65b5d8382169905c5313b2c2011a95..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_Denon.hpp +++ /dev/null @@ -1,313 +0,0 @@ -/* - * ir_Denon.cpp - * - * Contains functions for receiving and sending Denon/Sharp IR Protocol - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_DENON_HPP -#define _IR_DENON_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// DDDD EEEEE N N OOO N N -// D D E NN N O O NN N -// D D EEE N N N O O N N N -// D D E N NN O O N NN -// DDDD EEEEE N N OOO N N -//============================================================================== -// SSSS H H AAA RRRR PPPP -// S H H A A R R P P -// SSS HHHHH AAAAA RRRR PPPP -// S H H A A R R P -// SSSS H H A A R R P -//============================================================================== -/* - Protocol=Denon Address=0x11 Command=0x76 Raw-Data=0xED1 15 bits LSB first - + 200,-1800 + 300,- 750 + 300,- 800 + 200,- 800 - + 250,-1800 + 250,- 800 + 250,-1800 + 300,-1750 - + 300,- 750 + 300,-1800 + 250,-1800 + 250,-1850 - + 250,- 750 + 300,- 800 + 250,- 800 + 250 - Sum: 23050 - - Denon/Sharp variant - Protocol=Denon Address=0x11 Command=0x76 Raw-Data=0x4ED1 15 bits LSB first - + 200,-1800 + 300,- 750 + 250,- 800 + 250,- 750 - + 300,-1800 + 250,- 800 + 250,-1800 + 300,-1750 - + 300,- 750 + 300,-1800 + 250,-1800 + 250,-1800 - + 300,- 750 + 300,- 750 + 300,-1800 + 250 - Sum: 23050 - */ -/* - * https://www.mikrocontroller.net/articles/IRMP_-_english#DENON - * Denon published all their IR codes: - * http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls - * Example: - * 0000 006D 0000 0020 000A 001E 000A 0046 000A 001E 000A 001E 000A 001E // 5 address bits - * 000A 001E 000A 001E 000A 0046 000A 0046 000A 0046 000A 001E 000A 0046 000A 0046 // 8 command bits - * 000A 001E 000A 001E 000A 0679 // 2 frame bits 0,0 + stop bit + space for AutoRepeat - * 000A 001E 000A 0046 000A 001E 000A 001E 000A 001E // 5 address bits - * 000A 0046 000A 0046 000A 001E 000A 001E 000A 001E 000A 0046 000A 001E 000A 001E // 8 inverted command bits - * 000A 0046 000A 0046 000A 0679 // 2 frame bits 1,1 + stop bit + space for Repeat - * From analyzing the codes for Tuner preset 1 to 8 in tab Main Zone ID#1 it is obvious, that the protocol is LSB first at least for command. - * All Denon codes with 32 as 3. value use the Kaseyikyo Denon variant. - */ -// LSB first, no start bit, 5 address + 8 command + 2 frame (0,0) + 1 stop bit - each frame 2 times -// Every frame is auto repeated with a space period of 45 ms and the command and frame inverted to (1,1) or (0,1) for SHARP. -// -#define DENON_ADDRESS_BITS 5 -#define DENON_COMMAND_BITS 8 -#define DENON_FRAME_BITS 2 // 00/10 for 1. frame Denon/Sharp, inverted for autorepeat frame - -#define DENON_BITS (DENON_ADDRESS_BITS + DENON_COMMAND_BITS + DENON_FRAME_BITS) // 15 - The number of bits in the command -#define DENON_UNIT 260 - -#define DENON_BIT_MARK DENON_UNIT // The length of a Bit:Mark -#define DENON_ONE_SPACE (7 * DENON_UNIT) // 1820 // The length of a Bit:Space for 1's -#define DENON_ZERO_SPACE (3 * DENON_UNIT) // 780 // The length of a Bit:Space for 0's - -#define DENON_AUTO_REPEAT_DISTANCE 45000 // Every frame is auto repeated with a space period of 45 ms and the command and frame inverted. -#define DENON_REPEAT_PERIOD 110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down. - -// for old decoder -#define DENON_HEADER_MARK DENON_UNIT // The length of the Header:Mark -#define DENON_HEADER_SPACE (3 * DENON_UNIT) // 780 // The length of the Header:Space - -struct PulseDistanceWidthProtocolConstants DenonProtocolConstants = { DENON, DENON_KHZ, DENON_HEADER_MARK, DENON_HEADER_SPACE, -DENON_BIT_MARK, DENON_ONE_SPACE, DENON_BIT_MARK, DENON_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, - (DENON_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ - -void IRsend::sendSharp(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - sendDenon(aAddress, aCommand, aNumberOfRepeats, true); -} - -void IRsend::sendDenon(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aSendSharp) { - // Set IR carrier frequency - enableIROut (DENON_KHZ); // 38 kHz - - // Add frame marker for sharp - uint16_t tCommand = aCommand; - if (aSendSharp) { - tCommand |= 0x0200; // the 2 upper bits are 00 for Denon and 10 for Sharp - } - uint16_t tData = aAddress | ((uint16_t) tCommand << DENON_ADDRESS_BITS); - uint16_t tInvertedData = (tData ^ 0x7FE0); // Command and frame (upper 10 bits) are inverted - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - - // Data - sendPulseDistanceWidthData(&DenonProtocolConstants, tData, DENON_BITS); - - // Inverted autorepeat frame - delay(DENON_AUTO_REPEAT_DISTANCE / MICROS_IN_ONE_MILLI); - sendPulseDistanceWidthData(&DenonProtocolConstants, tInvertedData, DENON_BITS); - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - // send repeated command with a fixed space gap - delay( DENON_AUTO_REPEAT_DISTANCE / MICROS_IN_ONE_MILLI); - } - } -} - -bool IRrecv::decodeSharp() { - return decodeDenon(); -} - -bool IRrecv::decodeDenon() { - - // we have no start bit, so check for the exact amount of data bits - // Check we have the right amount of data (32). The + 2 is for initial gap + stop bit mark - if (decodedIRData.rawDataPtr->rawlen != (2 * DENON_BITS) + 2) { - IR_DEBUG_PRINT(F("Denon: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 32")); - return false; - } - - // Try to decode as Denon protocol - if (!decodePulseDistanceWidthData(&DenonProtocolConstants, DENON_BITS, 1)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Denon: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - - // Check for stop mark - if (!matchMark(decodedIRData.rawDataPtr->rawbuf[(2 * DENON_BITS) + 1], DENON_HEADER_MARK)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Denon: ")); - Serial.println(F("Stop bit mark length is wrong")); -#endif - return false; - } - - // Success - decodedIRData.address = decodedIRData.decodedRawData & 0x1F; - decodedIRData.command = decodedIRData.decodedRawData >> DENON_ADDRESS_BITS; - uint8_t tFrameBits = (decodedIRData.command >> 8) & 0x03; - decodedIRData.command &= 0xFF; - - // Check for (auto) repeat - if (decodedIRData.rawDataPtr->rawbuf[0] < ((DENON_AUTO_REPEAT_DISTANCE + (DENON_AUTO_REPEAT_DISTANCE / 4)) / MICROS_PER_TICK)) { - repeatCount++; - if (repeatCount > 1) { // skip first auto repeat - decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT; - } - - if (tFrameBits & 0x01) { - /* - * Here we are in the auto repeated frame with the inverted command - */ -#if defined(LOCAL_DEBUG) - Serial.print(F("Denon: ")); - Serial.println(F("Autorepeat received=")); -#endif - decodedIRData.flags |= IRDATA_FLAGS_IS_AUTO_REPEAT; - // Check parity of consecutive received commands. There is no parity in one data set. - if ((uint8_t) lastDecodedCommand != (uint8_t)(~decodedIRData.command)) { - decodedIRData.flags |= IRDATA_FLAGS_PARITY_FAILED; -#if defined(LOCAL_DEBUG) - Serial.print(F("Denon: ")); - Serial.print(F("Parity check for repeat failed. Last command=")); - Serial.print(lastDecodedCommand, HEX); - Serial.print(F(" current=")); - Serial.println(~decodedIRData.command, HEX); -#endif - } - // always take non inverted command - decodedIRData.command = lastDecodedCommand; - } - - // repeated command here - if (tFrameBits == 1 || tFrameBits == 2) { - decodedIRData.protocol = SHARP; - } else { - decodedIRData.protocol = DENON; - } - } else { - repeatCount = 0; - // first command here - if (tFrameBits == 2) { - decodedIRData.protocol = SHARP; - } else { - decodedIRData.protocol = DENON; - } - } - - decodedIRData.numberOfBits = DENON_BITS; - - return true; -} - -/********************************************************************************* - * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials - *********************************************************************************/ -/* - * Only for backwards compatibility - */ -void IRsend::sendDenonRaw(uint16_t aRawData, int_fast8_t aNumberOfRepeats) { - sendDenon(aRawData >> (DENON_COMMAND_BITS + DENON_FRAME_BITS), (aRawData >> DENON_FRAME_BITS) & 0xFF, aNumberOfRepeats); -} - -/* - * Old function with parameter data - */ -void IRsend::sendDenon(unsigned long data, int nbits) { - // Set IR carrier frequency - enableIROut (DENON_KHZ); -#if !(defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)) -// Serial.println( -// "The function sendDenon(data, nbits) is deprecated and may not work as expected! Use sendDenonRaw(data, NumberOfRepeats) or better sendDenon(Address, Command, NumberOfRepeats)."); -#endif - - // Header - mark(DENON_HEADER_MARK); - space(DENON_HEADER_SPACE); - - // Data - sendPulseDistanceWidthData(DENON_BIT_MARK, DENON_ONE_SPACE, DENON_BIT_MARK, DENON_ZERO_SPACE, data, nbits, - PROTOCOL_IS_MSB_FIRST); -} - -/* - * Old function without parameter aNumberOfRepeats - */ -void IRsend::sendSharp(uint16_t aAddress, uint16_t aCommand) { - sendDenon(aAddress, aCommand, true, 0); -} - -bool IRrecv::decodeDenonOld(decode_results *aResults) { - - // Check we have the right amount of data - if (decodedIRData.rawDataPtr->rawlen != 1 + 2 + (2 * DENON_BITS) + 1) { - return false; - } - - // Check initial Mark+Space match - if (!matchMark(aResults->rawbuf[1], DENON_HEADER_MARK)) { - return false; - } - - if (!matchSpace(aResults->rawbuf[2], DENON_HEADER_SPACE)) { - return false; - } - - // Try to decode as Denon protocol - if (!decodePulseDistanceWidthData(DENON_BITS, 3, DENON_BIT_MARK, 0, DENON_ONE_SPACE, DENON_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST)) { - return false; - } - - // Success - aResults->value = decodedIRData.decodedRawData; - aResults->bits = DENON_BITS; - aResults->decode_type = DENON; - decodedIRData.protocol = DENON; - return true; -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_DENON_HPP diff --git a/IRremote/src/ir_DistanceWidthProtocol.hpp b/IRremote/src/ir_DistanceWidthProtocol.hpp deleted file mode 100644 index 0908f1544dee764eb14553b2f8b29e77dc19aa54..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_DistanceWidthProtocol.hpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - * ir_DistanceWidthProtocol.hpp - * - * Contains only the decoder functions for universal pulse width or pulse distance protocols! - * The send functions are used by almost all protocols and therefore in IRSend.hh. - * - * This decoder tries to decode a pulse distance or pulse distance width with constant period (or pulse width - not enabled yet) protocol. - * 1. Analyze all space and mark length - * 2. Decide which protocol we have - * 3. Try to decode with the mark and space data found in step 1 - * 4. Assume one start bit / header and one stop bit, since pulse distance data must have a stop bit! - * No data and address decoding, only raw data as result. - * - * Pulse distance data can be sent with the generic function as in SendDemo example line 155: - * https://github.com/Arduino-IRremote/Arduino-IRremote/blob/d51b540cb2ddf1424888d2d9e6b62fe1ef46859d/examples/SendDemo/SendDemo.ino#L155 - * void sendPulseDistanceWidthData(unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros, - * unsigned int aZeroSpaceMicros, uint32_t aData, uint8_t aNumberOfBits, bool aMSBfirst, bool aSendStopBit = false) - * The header must be sent manually with: - * IrSender.mark(MarkMicros) - * IrSender.space(SpaceMicros); - * - * Or send it by filling a DecodedRawDataArray and with the sendPulseDistanceWidthFromArray() function as in SendDemo example line 175: - * https://github.com/Arduino-IRremote/Arduino-IRremote/blob/d51b540cb2ddf1424888d2d9e6b62fe1ef46859d/examples/SendDemo/SendDemo.ino#L175 - * sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, unsigned int aHeaderMarkMicros, - * unsigned int aHeaderSpaceMicros, unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros, - * unsigned int aZeroSpaceMicros, uint32_t *aDecodedRawDataArray, unsigned int aNumberOfBits, bool aMSBFirst, - * bool aSendStopBit, unsigned int aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats) - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_DISTANCE_WIDTH_HPP -#define _IR_DISTANCE_WIDTH_HPP - -#if !defined(DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS) -#define DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS 100000 // 100 ms, bit it is just a guess -#endif - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -// accept durations up to 50 * 50 (MICROS_PER_TICK) 2500 microseconds -#define DURATION_ARRAY_SIZE 50 - -// Switch the decoding according to your needs -//#define USE_MSB_DECODING_FOR_DISTANCE_DECODER // If active, it resembles LG, otherwise LSB first as most other protocols e.g. NEC and Kaseikyo/Panasonic - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//===================================================================================== -// DDD III SSS TTTTTT AA N N CCC EEEE W W III DDD TTTTTT H H -// D D I S TT A A NN N C E W W I D D TT H H -// D D I SSS TT AAAA N N N C EEE W W W I D D TT HHHH -// D D I S TT A A N NN C E W W W I D D TT H H -// DDD III SSSS TT A A N N CCC EEEE W W III DDD TT H H -//===================================================================================== -// see: https://www.mikrocontroller.net/articles/IRMP_-_english#Codings -#if defined(LOCAL_DEBUG) -void printDurations(uint8_t aArray[], uint8_t aMaxIndex) { - for (uint_fast8_t i = 0; i <= aMaxIndex; i++) { - //Print index at the beginning of a new line - if (i % 10 == 0) { - if (i == 0) { - Serial.print(' '); // indentation for the first index 0 - } else { - Serial.println(); // new line for next indexes 10, 20 etc. - } - Serial.print(i); - Serial.print(F(": ")); - } - // Print number of values in array and duration if != 0 - Serial.print(aArray[i]); - if (aArray[i] != 0) { - Serial.print('x'); - Serial.print(i * (uint16_t) MICROS_PER_TICK); - } - Serial.print(F(" | ")); - } - Serial.println(); -} -#endif - -/* - * @return false if more than 2 distinct duration values found - */ -bool aggregateArrayCounts(uint8_t aArray[], uint8_t aMaxIndex, uint8_t *aShortIndex, uint8_t *aLongIndex) { - uint8_t tSum = 0; - uint16_t tWeightedSum = 0; - for (uint_fast8_t i = 0; i <= aMaxIndex; i++) { - uint8_t tCurrentDurations = aArray[i]; - if (tCurrentDurations != 0) { - // Add it to sum and remove array content - tSum += tCurrentDurations; - tWeightedSum += (tCurrentDurations * i); - aArray[i] = 0; - } - if ((tCurrentDurations == 0 || i == aMaxIndex) && tSum != 0) { - // here we have a sum and a gap after the values - uint8_t tAggregateIndex = (tWeightedSum + (tSum / 2)) / tSum; // with rounding - aArray[tAggregateIndex] = tSum; // disabling this line increases code size by 2 - unbelievable! - // store aggregate for later decoding - if (*aShortIndex == 0) { - *aShortIndex = tAggregateIndex; - } else if (*aLongIndex == 0) { - *aLongIndex = tAggregateIndex; - } else { - // we have 3 bins => this is likely no pulse width or distance protocol. e.g. it can be RC5. - return false; - } - // initialize for next aggregation - tSum = 0; - tWeightedSum = 0; - } - } - return true; -} - -/* - * Try to decode a pulse distance or pulse width protocol. - * 1. Analyze all space and mark length - * 2. Decide if we have an pulse width or distance protocol - * 3. Try to decode with the mark and space data found in step 1 - * No data and address decoding, only raw data as result. - */ -bool IRrecv::decodeDistanceWidth() { - uint8_t tDurationArray[DURATION_ARRAY_SIZE]; // For up to 49 ticks / 2450 us - - /* - * Accept only protocols with at least 8 bits - */ - if (decodedIRData.rawDataPtr->rawlen < (2 * 8) + 4) { - IR_DEBUG_PRINT(F("PULSE_DISTANCE_WIDTH: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is less than 20")); - return false; - } - - uint_fast8_t i; - - // Reset duration array - memset(tDurationArray, 0, DURATION_ARRAY_SIZE); - - uint8_t tIndexOfMaxDuration = 0; - /* - * Count number of mark durations up to 49 ticks. Skip leading start and trailing stop bit. - */ - for (i = 3; i < (uint_fast8_t) decodedIRData.rawDataPtr->rawlen - 2; i += 2) { - auto tDurationTicks = decodedIRData.rawDataPtr->rawbuf[i]; - if (tDurationTicks < DURATION_ARRAY_SIZE) { - tDurationArray[tDurationTicks]++; // count duration if less than DURATION_ARRAY_SIZE (50) - if (tIndexOfMaxDuration < tDurationTicks) { - tIndexOfMaxDuration = tDurationTicks; - } - } else { -#if defined(LOCAL_DEBUG) - Serial.print(F("PULSE_DISTANCE_WIDTH: ")); - Serial.print(F("Mark ")); - Serial.print(tDurationTicks * MICROS_PER_TICK); - Serial.print(F(" is longer than maximum ")); - Serial.print(DURATION_ARRAY_SIZE * MICROS_PER_TICK); - Serial.print(F(" us. Index=")); - Serial.println(i); -#endif - return false; - } - } - - /* - * Aggregate mark counts to one duration bin - */ - uint8_t tMarkTicksShort = 0; - uint8_t tMarkTicksLong = 0; - bool tSuccess = aggregateArrayCounts(tDurationArray, tIndexOfMaxDuration, &tMarkTicksShort, &tMarkTicksLong); -#if defined(LOCAL_DEBUG) - Serial.println(F("Mark:")); - printDurations(tDurationArray, tIndexOfMaxDuration); -#endif - - if (!tSuccess) { -#if defined(LOCAL_DEBUG) - Serial.print(F("PULSE_DISTANCE_WIDTH: ")); - Serial.println(F("Mark aggregation failed, more than 2 distinct mark duration values found")); -#endif - return false; - } - - // Reset duration array - memset(tDurationArray, 0, DURATION_ARRAY_SIZE); - - /* - * Count number of space durations. Skip leading start and trailing stop bit. - */ - tIndexOfMaxDuration = 0; - for (i = 4; i < (uint_fast8_t) decodedIRData.rawDataPtr->rawlen - 2; i += 2) { - auto tDurationTicks = decodedIRData.rawDataPtr->rawbuf[i]; - if (tDurationTicks < DURATION_ARRAY_SIZE) { - tDurationArray[tDurationTicks]++; - if (tIndexOfMaxDuration < tDurationTicks) { - tIndexOfMaxDuration = tDurationTicks; - } - } else { -#if defined(LOCAL_DEBUG) - Serial.print(F("PULSE_DISTANCE_WIDTH: ")); - Serial.print(F("Space ")); - Serial.print(tDurationTicks * MICROS_PER_TICK); - Serial.print(F(" is longer than ")); - Serial.print(DURATION_ARRAY_SIZE * MICROS_PER_TICK); - Serial.print(F(" us. Index=")); - Serial.println(i); -#endif - return false; - } - } - - /* - * Aggregate space counts to one duration bin - */ - uint8_t tSpaceTicksShort = 0; - uint8_t tSpaceTicksLong = 0; - tSuccess = aggregateArrayCounts(tDurationArray, tIndexOfMaxDuration, &tSpaceTicksShort, &tSpaceTicksLong); -#if defined(LOCAL_DEBUG) - Serial.println(F("Space:")); - printDurations(tDurationArray, tIndexOfMaxDuration); -#endif - - if (!tSuccess) { -#if defined(LOCAL_DEBUG) - Serial.print(F("PULSE_DISTANCE_WIDTH: ")); - Serial.println(F("Space aggregation failed, more than 2 distinct space duration values found")); -#endif - return false; - } - - /* - * Print characteristics of this protocol. Durations are in ticks. - * Number of bits, start bit, start pause, long mark, long space, short mark, short space - * - * NEC: 32, 180, 90, 0, 34, 11, 11 - * Samsung32: 32, 90, 90, 0, 34, 11, 11 - * LG: 28, 180, 84, 0, 32, 10, 11 - * JVC: 16, 168, 84, 0, 32, 10, 10 - * Kaseikyo: 48. 69, 35, 0, 26, 9, 9 - * Sony: 12|15|20, 48, 12, 24, 0, 12, 12 // the only known pulse width protocol - */ -#if defined(LOCAL_DEBUG) - Serial.print(F("DistanceWidthTimingInfoStruct: ")); - Serial.print(decodedIRData.rawDataPtr->rawbuf[1] * MICROS_PER_TICK); - Serial.print(F(", ")); - Serial.print(decodedIRData.rawDataPtr->rawbuf[2] * MICROS_PER_TICK); - Serial.print(F(", ")); - Serial.print(tMarkTicksLong * MICROS_PER_TICK); - Serial.print(F(", ")); - Serial.print(tSpaceTicksLong * MICROS_PER_TICK); - Serial.print(F(", ")); - Serial.print(tMarkTicksShort * MICROS_PER_TICK); - Serial.print(F(", ")); - Serial.println(tSpaceTicksShort * MICROS_PER_TICK); -#endif - uint8_t tStartIndex = 3; - // skip leading start bit for decoding. - uint16_t tNumberOfBits = (decodedIRData.rawDataPtr->rawlen / 2) - 1; - if (tSpaceTicksLong > 0 && tMarkTicksLong == 0) { - // For PULSE_DISTANCE a stop bit is mandatory, for PULSE_WIDTH it is not required! - tNumberOfBits--; // Correct for stop bit - } - decodedIRData.numberOfBits = tNumberOfBits; - uint8_t tNumberOfAdditionalArrayValues = (tNumberOfBits - 1) / BITS_IN_RAW_DATA_TYPE; - - /* - * We can have the following protocol timings - * Pulse distance: Pulses/marks are constant, pause/spaces have different length, like NEC. - * Pulse width: Pulses/marks have different length, pause/spaces are constant, like Sony. - * Pulse distance width: Pulses/marks and pause/spaces have different length, often the bit length is constant, like MagiQuest. - * Pulse distance width can be decoded by pulse width decoder, if this decoder does not check the length of pause/spaces. - */ - - if (tMarkTicksLong == 0 && tSpaceTicksLong == 0) { -#if defined(LOCAL_DEBUG) - Serial.print(F("PULSE_DISTANCE: ")); - Serial.println(F("Only 1 distinct duration value for each space and mark found")); -#endif - return false; - } - unsigned int tSpaceMicrosShort; -#if defined DECODE_STRICT_CHECKS - if(tMarkTicksLong > 0 && tSpaceTicksLong > 0) { - // We have different mark and space length here, so signal decodePulseDistanceWidthData() not to check against constant length decodePulseDistanceWidthData - tSpaceMicrosShort = 0; - } -#endif - tSpaceMicrosShort = tSpaceTicksShort * MICROS_PER_TICK; - unsigned int tMarkMicrosShort = tMarkTicksShort * MICROS_PER_TICK; - unsigned int tMarkMicrosLong = tMarkTicksLong * MICROS_PER_TICK; - unsigned int tSpaceMicrosLong = tSpaceTicksLong * MICROS_PER_TICK; - - for (uint_fast8_t i = 0; i <= tNumberOfAdditionalArrayValues; ++i) { - uint8_t tNumberOfBitsForOneDecode = tNumberOfBits; - /* - * Decode in 32/64 bit chunks. Only the last chunk can contain less than 32/64 bits - */ - if (tNumberOfBitsForOneDecode > BITS_IN_RAW_DATA_TYPE) { - tNumberOfBitsForOneDecode = BITS_IN_RAW_DATA_TYPE; - } - bool tResult; - if (tMarkTicksLong > 0) { - /* - * Here short and long mark durations found. - */ - decodedIRData.protocol = PULSE_WIDTH; - tResult = decodePulseDistanceWidthData(tNumberOfBitsForOneDecode, tStartIndex, tMarkMicrosLong, tMarkMicrosShort, - tSpaceMicrosShort, 0, -#if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER) - true -#else - false -#endif - ); - } else { - /* - * Here short and long space durations found. - */ - decodedIRData.protocol = PULSE_DISTANCE; - tResult = decodePulseDistanceWidthData(tNumberOfBitsForOneDecode, tStartIndex, tMarkMicrosShort, tMarkMicrosShort, - tSpaceMicrosLong, tSpaceMicrosShort, -#if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER) - true -#else - false -#endif - ); - } - if (!tResult) { -#if defined(LOCAL_DEBUG) - Serial.print(F("PULSE_WIDTH: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } -#if defined(LOCAL_DEBUG) - Serial.print(F("PULSE_WIDTH: ")); - Serial.print(F("decodedRawData=0x")); - Serial.println(decodedIRData.decodedRawData, HEX); -#endif - // fill array with decoded data - decodedIRData.decodedRawDataArray[i] = decodedIRData.decodedRawData; - tStartIndex += (2 * BITS_IN_RAW_DATA_TYPE); - tNumberOfBits -= BITS_IN_RAW_DATA_TYPE; - } - -#if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER) - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; -#endif - - // Check for repeat - checkForRepeatSpaceTicksAndSetFlag(DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS / MICROS_PER_TICK); - - /* - * Store timing data to reproduce frame for sending - */ - decodedIRData.DistanceWidthTimingInfo.HeaderMarkMicros = (decodedIRData.rawDataPtr->rawbuf[1] * MICROS_PER_TICK); - decodedIRData.DistanceWidthTimingInfo.HeaderSpaceMicros = (decodedIRData.rawDataPtr->rawbuf[2] * MICROS_PER_TICK); - decodedIRData.DistanceWidthTimingInfo.ZeroMarkMicros = tMarkMicrosShort; - decodedIRData.DistanceWidthTimingInfo.ZeroSpaceMicros = tSpaceMicrosShort; - if (tMarkMicrosLong != 0) { - decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosLong; - - decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosShort; - if (tSpaceMicrosLong != 0) { - // Assume long space for zero when we have PulseDistanceWidth -> enables constant bit length - decodedIRData.DistanceWidthTimingInfo.ZeroSpaceMicros = tSpaceMicrosLong; - } - } else { - decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosShort; - - // Here tMarkMicrosLong is 0 => tSpaceMicrosLong != 0 - decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosLong; - } - -#if defined(LOCAL_DEBUG) - Serial.print(F("DistanceWidthTimingInfo=")); - IrReceiver.printDistanceWidthTimingInfo(&Serial, &decodedIRData.DistanceWidthTimingInfo); - Serial.println(); -#endif - return true; -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_DISTANCE_WIDTH_HPP diff --git a/IRremote/src/ir_FAST.hpp b/IRremote/src/ir_FAST.hpp deleted file mode 100644 index 09998ac0e8b7344d7d11e91c16a87c8af9f759ec..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_FAST.hpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * ir_FAST.hpp - * - * Contains functions for receiving and sending FAST IR protocol with 8 bit command - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_FAST_HPP -#define _IR_FAST_HPP - -#include "TinyIR.h" - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -// generated with https://patorjk.com/software/taag/#p=display&f=Alphabet&t=FAST -//============================================================================== -// FFFF AA SSS TTTTTT -// F A A S TT -// FFF AAAA SSS TT -// F A A S TT -// F A A SSSS TT -//============================================================================== -#include "TinyIR.h" -/* -Protocol=FAST Address=0x0 Command=0x76 Raw-Data=0x8976 16 bits LSB first - +2100,-1050 - + 550,- 500 + 550,-1550 + 550,-1550 + 550,- 500 - + 550,-1550 + 550,-1550 + 550,-1550 + 550,- 500 - + 550,-1550 + 550,- 500 + 550,- 500 + 550,-1550 - + 550,- 500 + 550,- 500 + 550,- 500 + 550,-1550 - + 550 -Sum: 28900 -*/ -struct PulseDistanceWidthProtocolConstants FASTProtocolConstants = { FAST, FAST_KHZ, FAST_HEADER_MARK, FAST_HEADER_SPACE, -FAST_BIT_MARK, FAST_ONE_SPACE, FAST_BIT_MARK, FAST_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, (FAST_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), -NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ - -/** - * The FAST protocol repeats by skipping the header mark and space -> this leads to a poor repeat detection for JVC protocol. - */ -void IRsend::sendFAST(uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - // Set IR carrier frequency - enableIROut(FAST_KHZ); // 38 kHz - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - - mark(FAST_HEADER_MARK); - space(FAST_HEADER_SPACE); - - sendPulseDistanceWidthData(&FASTProtocolConstants, aCommand | (((uint8_t)(~aCommand)) << 8), FAST_BITS); - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - // send repeated command in a fixed raster - delay(FAST_REPEAT_DISTANCE / MICROS_IN_ONE_MILLI); - } - } -} - -bool IRrecv::decodeFAST() { - -// uint_fast8_t tRawlen = decodedIRData.rawDataPtr->rawlen; // Using a local variable does not improve code size - - // Check we have the right amount of data (36). The +4 is for initial gap, start bit mark and space + stop bit mark. - if (decodedIRData.rawDataPtr->rawlen != ((2 * FAST_BITS) + 4)) { - IR_DEBUG_PRINT(F("FAST: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 36")); - return false; - } - - if (!checkHeader(&FASTProtocolConstants)) { - return false; - } - - if (!decodePulseDistanceWidthData(&FASTProtocolConstants, FAST_BITS)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("FAST: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - - WordUnion tValue; - tValue.UWord = decodedIRData.decodedRawData; - - if (tValue.UByte.LowByte != (uint8_t)~(tValue.UByte.HighByte)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("FAST: ")); - Serial.print(F("8 bit parity is not correct. Expected=0x")); - Serial.print((uint8_t)~(tValue.UByte.LowByte), HEX); - Serial.print(F(" received=0x")); - Serial.print(tValue.UByte.HighByte, HEX); - Serial.print(F(" data=0x")); - Serial.println(tValue.UWord, HEX); -#endif - decodedIRData.flags = IRDATA_FLAGS_PARITY_FAILED; - } - - checkForRepeatSpaceTicksAndSetFlag(FAST_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK); - - // Success -// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value - decodedIRData.command = tValue.UByte.LowByte; - decodedIRData.address = 0; // No address for this protocol - decodedIRData.numberOfBits = FAST_BITS; - decodedIRData.protocol = FAST; - - return true; -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_FAST_HPP diff --git a/IRremote/src/ir_JVC.hpp b/IRremote/src/ir_JVC.hpp deleted file mode 100644 index 89f9f919f3c74eb1a070ccb86850e9b18d4bae32..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_JVC.hpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * ir_JVC.hpp - * - * Contains functions for receiving and sending JVC IR Protocol in "raw" and standard format with 8 bit address and 8 bit command - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2017-2023 Kristian Lauszus, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_JVC_HPP -#define _IR_JVC_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// JJJJJ V V CCCC -// J V V C -// J V V C -// J J V V C -// J V CCCC -//============================================================================== -/* - +8400,-4150 - + 550,-1550 + 550,- 500 + 550,- 500 + 550,- 500 - + 550,-1500 + 600,-1500 + 600,-1500 + 550,-1550 - + 550,- 500 + 550,-1550 + 550,-1550 + 550,- 500 - + 500,-1600 + 550,-1550 + 550,-1500 + 600,- 500 - + 550 - Sum: 40350 - */ -// https://www.sbprojects.net/knowledge/ir/jvc.php -// http://www.hifi-remote.com/johnsfine/DecodeIR.html#JVC -// IRP: {38k,525}<1,-1|1,-3>(16,-8,(D:8,F:8,1,-45)+) -// LSB first, 1 start bit + 8 bit address + 8 bit command + 1 stop bit. -// The JVC protocol repeats by skipping the header mark and space -> this leads to a poor repeat detection for JVC protocol. -// Some JVC devices require to send 3 repeats. https://github.com/Arduino-IRremote/Arduino-IRremote/issues/21 -#define JVC_ADDRESS_BITS 8 // 8 bit address -#define JVC_COMMAND_BITS 8 // Command - -#define JVC_BITS (JVC_ADDRESS_BITS + JVC_COMMAND_BITS) // 16 - The number of bits in the protocol -#define JVC_UNIT 526 // 20 periods of 38 kHz (526.315789) - -#define JVC_HEADER_MARK (16 * JVC_UNIT) // 8400 -#define JVC_HEADER_SPACE (8 * JVC_UNIT) // 4200 - -#define JVC_BIT_MARK JVC_UNIT // The length of a Bit:Mark -#define JVC_ONE_SPACE (3 * JVC_UNIT) // 1578 - The length of a Bit:Space for 1's -#define JVC_ZERO_SPACE JVC_UNIT // The length of a Bit:Space for 0's - -#define JVC_REPEAT_DISTANCE (uint16_t)(45 * JVC_UNIT) // 23625 - Commands are repeated with a distance of 23 ms for as long as the key on the remote control is held down. -#define JVC_REPEAT_PERIOD 65000 // assume around 40 ms for a JVC frame. JVC IR Remotes: RM-SA911U, RM-SX463U have 45 ms period - -struct PulseDistanceWidthProtocolConstants JVCProtocolConstants = { JVC, JVC_KHZ, JVC_HEADER_MARK, JVC_HEADER_SPACE, JVC_BIT_MARK, -JVC_ONE_SPACE, JVC_BIT_MARK, JVC_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, (JVC_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ - -/** - * The JVC protocol repeats by skipping the header mark and space -> this leads to a poor repeat detection for JVC protocol. - */ -void IRsend::sendJVC(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - // Set IR carrier frequency - enableIROut (JVC_KHZ); // 38 kHz - - if (aNumberOfRepeats < 0) { - // The JVC protocol repeats by skipping the header. - aNumberOfRepeats = 0; - } else { - mark(JVC_HEADER_MARK); - space(JVC_HEADER_SPACE); - } - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - - // Address + command - sendPulseDistanceWidthData(&JVCProtocolConstants, aAddress | (aCommand << JVC_ADDRESS_BITS), JVC_BITS); - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - // send repeated command in a fixed raster - delay(JVC_REPEAT_DISTANCE / MICROS_IN_ONE_MILLI); - } - } -} - -bool IRrecv::decodeJVC() { - -// uint_fast8_t tRawlen = decodedIRData.rawDataPtr->rawlen; // Using a local variable does not improve code size - - // Check we have the right amount of data (36 or 34). The +4 is for initial gap, start bit mark and space + stop bit mark. - // +4 is for first frame, +2 is for repeats - if (decodedIRData.rawDataPtr->rawlen != ((2 * JVC_BITS) + 2) && decodedIRData.rawDataPtr->rawlen != ((2 * JVC_BITS) + 4)) { - IR_DEBUG_PRINT(F("JVC: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 34 or 36")); - return false; - } - - if (decodedIRData.rawDataPtr->rawlen == ((2 * JVC_BITS) + 2)) { - /* - * Check for repeat - * Check leading space and first and last mark length - */ - if (decodedIRData.rawDataPtr->rawbuf[0] < ((JVC_REPEAT_DISTANCE + (JVC_REPEAT_DISTANCE / 4) / MICROS_PER_TICK)) - && matchMark(decodedIRData.rawDataPtr->rawbuf[1], JVC_BIT_MARK) - && matchMark(decodedIRData.rawDataPtr->rawbuf[decodedIRData.rawDataPtr->rawlen - 1], JVC_BIT_MARK)) { - /* - * We have a repeat here, so do not check for start bit - */ - decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST; - decodedIRData.address = lastDecodedAddress; - decodedIRData.command = lastDecodedCommand; - decodedIRData.protocol = JVC; - } - } else { - - if (!checkHeader(&JVCProtocolConstants)) { - return false; - } - - if (!decodePulseDistanceWidthData(&JVCProtocolConstants, JVC_BITS)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("JVC: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - - // Success -// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value - decodedIRData.command = decodedIRData.decodedRawData >> JVC_ADDRESS_BITS; // upper 8 bits of LSB first value - decodedIRData.address = decodedIRData.decodedRawData & 0xFF; // lowest 8 bit of LSB first value - decodedIRData.numberOfBits = JVC_BITS; - decodedIRData.protocol = JVC; - } - - return true; -} - -/********************************************************************************* - * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials - *********************************************************************************/ -bool IRrecv::decodeJVCMSB(decode_results *aResults) { - unsigned int offset = 1; // Skip first space - - // Check for repeat - if ((aResults->rawlen - 1 == 33) && matchMark(aResults->rawbuf[offset], JVC_BIT_MARK) - && matchMark(aResults->rawbuf[aResults->rawlen - 1], JVC_BIT_MARK)) { - aResults->bits = 0; - aResults->value = 0xFFFFFFFF; - decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT; - decodedIRData.protocol = JVC; - return true; - } - - // Initial mark - if (!matchMark(aResults->rawbuf[offset], JVC_HEADER_MARK)) { - return false; - } - offset++; - - // Check we have enough data - +3 for start bit mark and space + stop bit mark - if (aResults->rawlen <= (2 * JVC_BITS) + 3) { - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(aResults->rawlen); - IR_DEBUG_PRINTLN(F(" is too small. >= 36 is required.")); - return false; - } - - // Initial space - if (!matchSpace(aResults->rawbuf[offset], JVC_HEADER_SPACE)) { - return false; - } - offset++; - - if (!decodePulseDistanceWidthData(JVC_BITS, offset, JVC_BIT_MARK, 0, JVC_ONE_SPACE, JVC_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST)) { - return false; - } - - // Stop bit - if (!matchMark(aResults->rawbuf[offset + (2 * JVC_BITS)], JVC_BIT_MARK)) { -#if defined(LOCAL_DEBUG) - Serial.println(F("Stop bit mark length is wrong")); -#endif - return false; - } - - // Success - aResults->value = decodedIRData.decodedRawData; - aResults->bits = JVC_BITS; - aResults->decode_type = JVC; - decodedIRData.protocol = JVC; - - return true; -} - -/** - * With Send sendJVCMSB() you can send your old 32 bit codes. - * To convert one into the other, you must reverse the byte positions and then reverse all bit positions of each byte. - * Or write it as one binary string and reverse/mirror it. - * Example: - * 0xCB340102 byte reverse -> 02 01 34 CB bit reverse-> 40 80 2C D3. - * 0xCB340102 is binary 11001011001101000000000100000010. - * 0x40802CD3 is binary 01000000100000000010110011010011. - * If you read the first binary sequence backwards (right to left), you get the second sequence. - */ -void IRsend::sendJVCMSB(unsigned long data, int nbits, bool repeat) { - // Set IR carrier frequency - enableIROut (JVC_KHZ); - - // Only send the Header if this is NOT a repeat command - if (!repeat) { - mark(JVC_HEADER_MARK); - space(JVC_HEADER_SPACE); - } - - // Old version with MSB first Data - sendPulseDistanceWidthData(JVC_BIT_MARK, JVC_ONE_SPACE, JVC_BIT_MARK, JVC_ZERO_SPACE, data, nbits, PROTOCOL_IS_MSB_FIRST); -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_JVC_HPP diff --git a/IRremote/src/ir_Kaseikyo.hpp b/IRremote/src/ir_Kaseikyo.hpp deleted file mode 100644 index 294ea94e8181bd36a594e25dcbcadf0dd4eaac99..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_Kaseikyo.hpp +++ /dev/null @@ -1,322 +0,0 @@ -/* - * ir_Kaseikyo.hpp - * - * Contains functions for receiving and sending Kaseikyo/Panasonic IR Protocol in "raw" and standard format with 16 bit address + 8 bit command - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_KASEIKYO_HPP -#define _IR_KASEIKYO_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// K K AA SSS EEEE III K K Y Y OOO -// K K A A S E I K K Y Y O O -// KK AAAA SSS EEE I KK Y O O -// K K A A S E I K K Y O O -// K K A A SSSS EEEE III K K Y OOO -//============================================================================== -//============================================================================== -// PPPP AAA N N AAA SSSS OOO N N IIIII CCCC -// P P A A NN N A A S O O NN N I C -// PPPP AAAAA N N N AAAAA SSS O O N N N I C -// P A A N NN A A S O O N NN I C -// P A A N N A A SSSS OOO N N IIIII CCCC -//============================================================================== -/* - Protocol=Panasonic Address=0xFF1 Command=0x76 Raw-Data=0x9976FF10 48 bits LSB first - +3450,-1700 - + 450,- 400 + 500,-1250 + 450,- 400 + 500,- 400 - + 450,- 400 + 400,- 450 + 500,- 350 + 450,- 450 - + 450,- 400 + 450,- 400 + 500,- 400 + 450,- 400 - + 450,- 400 + 500,-1250 + 450,- 400 + 500,- 350 - + 500,- 400 + 450,- 400 + 450,- 450 + 450,- 400 - + 450,-1250 + 500,- 400 + 450,- 400 + 450,- 400 - + 450,-1300 + 450,-1250 + 450,-1300 + 400,-1300 - + 450,-1300 + 450,-1250 + 450,-1250 + 500,-1250 - + 450,- 450 + 450,-1250 + 450,-1250 + 500,- 400 - + 450,-1250 + 450,-1300 + 450,-1250 + 450,- 450 - + 450,-1250 + 450,- 400 + 450,- 400 + 500,-1250 - + 450,-1250 + 450,- 400 + 500,- 400 + 450,-1250 - + 450 - Sum: 64300 - */ -// http://www.hifi-remote.com/johnsfine/DecodeIR.html#Panasonic -// http://www.hifi-remote.com/johnsfine/DecodeIR.html#Kaseikyo -// The first two (8-bit) bytes contains the vendor code. -// There are multiple interpretations of the next fields: -// IRP: {37k,432}<1,-1|1,-3>(8,-4,M:8,N:8,X:4,D:4,S:8,F:8,G:8,1,-173)+ {X=M:4:0^M:4:4^N:4:0^N:4:4} -// 1. interpretation: After the vendor code, the next byte is 4 bit VendorID parity and 4 bit Device and Subdevice -// The 5th byte is the function and the last (6.th) byte is xor of the three bytes before it. -// 0_______ 1_______ 2______ 3_______ 4_______ 5 -// 01234567 89ABCDEF 01234567 01234567 01234567 01234567 -// 01000000 00100100 Dev____ Sub_Dev_ Fun____ XOR( B2, B3, B4) - showing Panasonic vendor code 0x2002 -// see: http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152 -// -// 2. interpretation: LSB first, start bit + 16 VendorID + 4 VendorID parity + 4 Genre1 + 4 Genre2 + 10 Command + 2 ID + 8 Parity + stop bit -// see: https://www.mikrocontroller.net/articles/IRMP_-_english#KASEIKYO -// 32 bit raw data LSB is VendorID parity. -// -// We reduce it to: IRP: {37k,432}<1,-1|1,-3>(8,-4,V:16,X:4,D:4,S:8,F:8,(X^D^S^F):8,1,-173)+ {X=M:4:0^M:4:4^N:4:0^N:4:4} -// start bit + 16 VendorID + 4 VendorID parity + 12 Address + 8 Command + 8 Parity of VendorID parity, Address and Command + stop bit -// -#define KASEIKYO_VENDOR_ID_BITS 16 -#define KASEIKYO_VENDOR_ID_PARITY_BITS 4 -#define KASEIKYO_ADDRESS_BITS 12 -#define KASEIKYO_COMMAND_BITS 8 -#define KASEIKYO_PARITY_BITS 8 -#define KASEIKYO_BITS (KASEIKYO_VENDOR_ID_BITS + KASEIKYO_VENDOR_ID_PARITY_BITS + KASEIKYO_ADDRESS_BITS + KASEIKYO_COMMAND_BITS + KASEIKYO_PARITY_BITS) // 48 -#define KASEIKYO_UNIT 432 // 16 pulses of 37 kHz (432,432432) - Pronto 0x70 | 0x10 - -#define KASEIKYO_HEADER_MARK (8 * KASEIKYO_UNIT) // 3456 -#define KASEIKYO_HEADER_SPACE (4 * KASEIKYO_UNIT) // 1728 - -#define KASEIKYO_BIT_MARK KASEIKYO_UNIT -#define KASEIKYO_ONE_SPACE (3 * KASEIKYO_UNIT) // 1296 -#define KASEIKYO_ZERO_SPACE KASEIKYO_UNIT - -#define KASEIKYO_AVERAGE_DURATION 56000 -#define KASEIKYO_REPEAT_PERIOD 130000 -#define KASEIKYO_REPEAT_DISTANCE (KASEIKYO_REPEAT_PERIOD - KASEIKYO_AVERAGE_DURATION) // 74 ms -#define KASEIKYO_MAXIMUM_REPEAT_DISTANCE (KASEIKYO_REPEAT_DISTANCE + (KASEIKYO_REPEAT_DISTANCE / 4)) // Just a guess - -#define PANASONIC_VENDOR_ID_CODE 0x2002 -#define DENON_VENDOR_ID_CODE 0x3254 -#define MITSUBISHI_VENDOR_ID_CODE 0xCB23 -#define SHARP_VENDOR_ID_CODE 0x5AAA -#define JVC_VENDOR_ID_CODE 0x0103 - -struct PulseDistanceWidthProtocolConstants KaseikyoProtocolConstants = { KASEIKYO, KASEIKYO_KHZ, KASEIKYO_HEADER_MARK, -KASEIKYO_HEADER_SPACE, KASEIKYO_BIT_MARK, KASEIKYO_ONE_SPACE, KASEIKYO_BIT_MARK, KASEIKYO_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST - , (KASEIKYO_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ - -/** - * Address can be interpreted as sub-device << 8 + device - */ -void IRsend::sendKaseikyo(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint16_t aVendorCode) { - // Set IR carrier frequency - enableIROut (KASEIKYO_KHZ); // 37 kHz - - // Vendor Parity - uint8_t tVendorParity = aVendorCode ^ (aVendorCode >> 8); - tVendorParity = (tVendorParity ^ (tVendorParity >> 4)) & 0xF; - -#if __INT_WIDTH__ < 32 - LongUnion tSendValue; - // Compute parity - tSendValue.UWord.LowWord = (aAddress << KASEIKYO_VENDOR_ID_PARITY_BITS) | tVendorParity; // set low nibble to parity - tSendValue.UBytes[2] = aCommand; - tSendValue.UBytes[3] = aCommand ^ tSendValue.UBytes[0] ^ tSendValue.UBytes[1]; // Parity - IRRawDataType tRawKaseikyoData[2]; - tRawKaseikyoData[0] = (uint32_t) tSendValue.UWord.LowWord << 16 | aVendorCode; // LSB of tRawKaseikyoData[0] is sent first - tRawKaseikyoData[1] = tSendValue.UWord.HighWord; - sendPulseDistanceWidthFromArray(&KaseikyoProtocolConstants, &tRawKaseikyoData[0], KASEIKYO_BITS, aNumberOfRepeats); -#else - LongLongUnion tSendValue; - tSendValue.UWords[0] = aVendorCode; - // Compute parity - tSendValue.UWords[1] = (aAddress << KASEIKYO_VENDOR_ID_PARITY_BITS) | tVendorParity; // set low nibble to parity - tSendValue.UBytes[4] = aCommand; - tSendValue.UBytes[5] = aCommand ^ tSendValue.UBytes[2] ^ tSendValue.UBytes[3]; // Parity - sendPulseDistanceWidth(&KaseikyoProtocolConstants, tSendValue.ULongLong, KASEIKYO_BITS, aNumberOfRepeats); -#endif -} - -/** - * Stub using Kaseikyo with PANASONIC_VENDOR_ID_CODE - */ -void IRsend::sendPanasonic(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - sendKaseikyo(aAddress, aCommand, aNumberOfRepeats, PANASONIC_VENDOR_ID_CODE); -} - -/** - * Stub using Kaseikyo with DENON_VENDOR_ID_CODE - */ -void IRsend::sendKaseikyo_Denon(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - sendKaseikyo(aAddress, aCommand, aNumberOfRepeats, DENON_VENDOR_ID_CODE); -} - -/** - * Stub using Kaseikyo with MITSUBISHI_VENDOR_ID_CODE - */ -void IRsend::sendKaseikyo_Mitsubishi(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - sendKaseikyo(aAddress, aCommand, aNumberOfRepeats, MITSUBISHI_VENDOR_ID_CODE); -} - -/** - * Stub using Kaseikyo with SHARP_VENDOR_ID_CODE - */ -void IRsend::sendKaseikyo_Sharp(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - sendKaseikyo(aAddress, aCommand, aNumberOfRepeats, SHARP_VENDOR_ID_CODE); -} - -/** - * Stub using Kaseikyo with JVC_VENDOR_ID_CODE - */ -void IRsend::sendKaseikyo_JVC(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - sendKaseikyo(aAddress, aCommand, aNumberOfRepeats, JVC_VENDOR_ID_CODE); -} - -/* - * Tested with my Panasonic DVD/TV remote - */ -bool IRrecv::decodeKaseikyo() { - - decode_type_t tProtocol; - // Check we have enough data (96 + 4) 4 for initial gap, start bit mark and space + stop bit mark - if (decodedIRData.rawDataPtr->rawlen != ((2 * KASEIKYO_BITS) + 4)) { - IR_DEBUG_PRINT(F("Kaseikyo: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 100")); - return false; - } - - if (!checkHeader(&KaseikyoProtocolConstants)) { - return false; - } - - // decode first 16 Vendor ID bits - if (!decodePulseDistanceWidthData(&KaseikyoProtocolConstants, KASEIKYO_VENDOR_ID_BITS)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Kaseikyo: ")); - Serial.println(F("Vendor ID decode failed")); -#endif - return false; - } - - uint16_t tVendorId = decodedIRData.decodedRawData; - if (tVendorId == PANASONIC_VENDOR_ID_CODE) { - tProtocol = PANASONIC; - } else if (tVendorId == SHARP_VENDOR_ID_CODE) { - tProtocol = KASEIKYO_SHARP; - } else if (tVendorId == DENON_VENDOR_ID_CODE) { - tProtocol = KASEIKYO_DENON; - } else if (tVendorId == JVC_VENDOR_ID_CODE) { - tProtocol = KASEIKYO_JVC; - } else if (tVendorId == MITSUBISHI_VENDOR_ID_CODE) { - tProtocol = KASEIKYO_MITSUBISHI; - } else { - tProtocol = KASEIKYO; - } - - // Vendor Parity - uint8_t tVendorParity = tVendorId ^ (tVendorId >> 8); - tVendorParity = (tVendorParity ^ (tVendorParity >> 4)) & 0xF; - - /* - * Decode next 32 bits, 8 VendorID parity parity + 12 address (device and subdevice) + 8 command + 8 parity - */ - if (!decodePulseDistanceWidthData(&KaseikyoProtocolConstants, - KASEIKYO_VENDOR_ID_PARITY_BITS + KASEIKYO_ADDRESS_BITS + KASEIKYO_COMMAND_BITS + KASEIKYO_PARITY_BITS, - 3 + (2 * KASEIKYO_VENDOR_ID_BITS))) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Kaseikyo: ")); - Serial.println(F("VendorID parity, address, command + parity decode failed")); -#endif - return false; - } - - // Success -// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value - LongUnion tValue; - tValue.ULong = decodedIRData.decodedRawData; -#if __INT_WIDTH__ >= 32 - // workaround until complete refactoring for 64 bit - decodedIRData.decodedRawData = (decodedIRData.decodedRawData << 16) | tVendorId; // store all 48 bits in decodedRawData -#endif - decodedIRData.address = (tValue.UWord.LowWord >> KASEIKYO_VENDOR_ID_PARITY_BITS); // remove 4 bit vendor parity - decodedIRData.command = tValue.UByte.MidHighByte; - uint8_t tParity = tValue.UByte.LowByte ^ tValue.UByte.MidLowByte ^ tValue.UByte.MidHighByte; - - if (tVendorParity != (tValue.UByte.LowByte & 0xF)) { - decodedIRData.flags = IRDATA_FLAGS_PARITY_FAILED | IRDATA_FLAGS_IS_LSB_FIRST; - -#if defined(LOCAL_DEBUG) - Serial.print(F("Kaseikyo: ")); - Serial.print(F("4 bit VendorID parity is not correct. Expected=0x")); - Serial.print(tVendorParity, HEX); - Serial.print(F(" received=0x")); - Serial.print(decodedIRData.decodedRawData, HEX); - Serial.print(F(" VendorID=0x")); - Serial.println(tVendorId, HEX); -#endif - } - - if (tProtocol == KASEIKYO) { - decodedIRData.flags |= IRDATA_FLAGS_EXTRA_INFO; - decodedIRData.extra = tVendorId; // Store (unknown) vendor ID - } - - if (tValue.UByte.HighByte != tParity) { - decodedIRData.flags |= IRDATA_FLAGS_PARITY_FAILED; - -#if defined(LOCAL_DEBUG) - Serial.print(F("Kaseikyo: ")); - Serial.print(F("8 bit parity is not correct. Expected=0x")); - Serial.print(tParity, HEX); - Serial.print(F(" received=0x")); - Serial.print(decodedIRData.decodedRawData >> KASEIKYO_COMMAND_BITS, HEX); - Serial.print(F(" address=0x")); - Serial.print(decodedIRData.address, HEX); - Serial.print(F(" command=0x")); - Serial.println(decodedIRData.command, HEX); -#endif - } - - decodedIRData.numberOfBits = KASEIKYO_BITS; - decodedIRData.protocol = tProtocol; - - // check for repeat - checkForRepeatSpaceTicksAndSetFlag(KASEIKYO_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK); - - return true; -} - -/* - * Removed void IRsend::sendPanasonic(uint16_t aAddress, uint32_t aData) - * and bool IRrecv::decodePanasonicMSB(decode_results *aResults) - * since their implementations were wrong (wrong length), and nobody recognized it - */ - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_KASEIKYO_HPP diff --git a/IRremote/src/ir_LG.hpp b/IRremote/src/ir_LG.hpp deleted file mode 100644 index 6990cff78d60238057465eadcbea76a4f78eff45..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_LG.hpp +++ /dev/null @@ -1,349 +0,0 @@ -/* - * ir_LG.hpp - * - * Contains functions for receiving and sending LG IR Protocol for air conditioner - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2017-2023 Darryl Smith, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_LG_HPP -#define _IR_LG_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// L GGGG -// L G -// L G GG -// L G G -// LLLLL GGG -//============================================================================== -/* - * Protocol=LG Address=0xF1 Command=0x7776 Raw-Data=0xF17776B 28 bits MSB first - +8950,-4150 - + 500,-1550 + 550,-1550 + 500,-1550 + 500,-1600 - + 500,- 700 + 350,- 600 + 450,- 600 + 450,-1550 - + 500,- 550 + 500,-1550 + 500,-1600 + 500,-1550 - + 550,- 550 + 500,-1550 + 500,-1550 + 550,-1550 - + 500,- 550 + 500,-1550 + 500,-1600 + 500,-1550 - + 500,- 550 + 500,-1550 + 500,-1600 + 500,- 550 - + 500,-1550 + 500,- 600 + 450,-1600 + 500,-1550 - + 500 - Sum: 62400 - */ - -// LG originally added by Darryl Smith (based on the JVC protocol) -// see: https://github.com/Arduino-IRremote/Arduino-IRremote/tree/master/examples/LGAirConditionerSendDemo -// see: https://www.mikrocontroller.net/articles/IRMP_-_english#LGAIR -// MSB first, 1 start bit + 8 bit address + 16 bit command + 4 bit checksum + 1 stop bit (28 data bits). -// Bit and repeat timing is like NEC -// LG2 has different header timing and a shorter bit time -/* - * LG remote IR-LED measurements: Type AKB 73315611 for air conditioner, Ver1.1 from 2011.03.01 - * Protocol: LG2 - * Internal crystal: 4 MHz - * Header: 8.9 ms mark 4.15 ms space - * Data: 500 / 540 and 500 / 1580; - * Clock is not synchronized with gate so you have 19 and sometimes 19 and a spike pulses for mark - * Duty: 9 us on 17 us off => around 33 % duty - * NO REPEAT: If value like temperature has changed during long press, the last value is send at button release. - * If you do a double press, the next value can be sent after around 118 ms. Tested with the fan button. - - * LG remote IR-LED measurements: Type AKB 75095308 for LG TV - * Protocol: NEC!!! - * Frequency 37.88 kHz - * Header: 9.0 ms mark 4.5 ms space - * Data: 560 / 560 and 560 / 1680; - * Clock is synchronized with gate, mark always starts with a full period - * Duty: 13 us on 13 us off => 50 % duty - * Repeat: 110 ms 9.0 ms mark, 2250 us space, 560 stop - * LSB first! - * - * The codes of the LG air conditioner are documented in https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/ac_LG.cpp - */ -#define LG_ADDRESS_BITS 8 -#define LG_COMMAND_BITS 16 -#define LG_CHECKSUM_BITS 4 -#define LG_BITS (LG_ADDRESS_BITS + LG_COMMAND_BITS + LG_CHECKSUM_BITS) // 28 - -#define LG_UNIT 500 // 19 periods of 38 kHz - -#define LG_HEADER_MARK (18 * LG_UNIT) // 9000 -#define LG_HEADER_SPACE 4200 // 4200 | 84 - -#define LG2_HEADER_MARK (19 * LG_UNIT) // 9500 -#define LG2_HEADER_SPACE (6 * LG_UNIT) // 3000 - -#define LG_BIT_MARK LG_UNIT -#define LG_ONE_SPACE 1580 // 60 periods of 38 kHz -#define LG_ZERO_SPACE 550 - -#define LG_REPEAT_HEADER_SPACE (4 * LG_UNIT) // 2250 -#define LG_REPEAT_PERIOD 110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down. -//#define LG_AVERAGE_DURATION 58000 // LG_HEADER_MARK + LG_HEADER_SPACE + 32 * 2,5 * LG_UNIT) + LG_UNIT // 2.5 because we assume more zeros than ones -//#define LG_REPEAT_DURATION (LG_HEADER_MARK + LG_REPEAT_HEADER_SPACE + LG_BIT_MARK) -//#define LG_REPEAT_DISTANCE (LG_REPEAT_PERIOD - LG_AVERAGE_DURATION) // 52 ms - -struct PulseDistanceWidthProtocolConstants LGProtocolConstants = { LG, LG_KHZ, LG_HEADER_MARK, LG_HEADER_SPACE, LG_BIT_MARK, -LG_ONE_SPACE, LG_BIT_MARK, LG_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST, (LG_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), &sendNECSpecialRepeat }; - -struct PulseDistanceWidthProtocolConstants LG2ProtocolConstants = { LG2, LG_KHZ, LG2_HEADER_MARK, LG2_HEADER_SPACE, LG_BIT_MARK, -LG_ONE_SPACE, LG_BIT_MARK, LG_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST, (LG_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), &sendLG2SpecialRepeat }; - -/************************************ - * Start of send and decode functions - ************************************/ -/* - * Send special LG2 repeat not used yet - */ -void IRsend::sendLG2Repeat() { - enableIROut (LG_KHZ); // 38 kHz - mark(LG2_HEADER_MARK); // + 3000 - space(LG_REPEAT_HEADER_SPACE); // - 2250 - mark(LG_BIT_MARK); // + 500 -} - -/** - * Static function for sending special repeat frame. - * For use in ProtocolConstants. Saves up to 250 bytes compared to a member function. - */ -void sendLG2SpecialRepeat() { - IrSender.enableIROut(LG_KHZ); // 38 kHz - IrSender.mark(LG2_HEADER_MARK); // + 3000 - IrSender.space(LG_REPEAT_HEADER_SPACE); // - 2250 - IrSender.mark(LG_BIT_MARK); // + 500 -} - -uint32_t IRsend::computeLGRawDataAndChecksum(uint8_t aAddress, uint16_t aCommand) { - uint32_t tRawData = ((uint32_t) aAddress << (LG_COMMAND_BITS + LG_CHECKSUM_BITS)) | ((uint32_t) aCommand << LG_CHECKSUM_BITS); - /* - * My guess of the 4 bit checksum - * Addition of all 4 nibbles of the 16 bit command - */ - uint8_t tChecksum = 0; - uint16_t tTempForChecksum = aCommand; - for (int i = 0; i < 4; ++i) { - tChecksum += tTempForChecksum & 0xF; // add low nibble - tTempForChecksum >>= 4; // shift by a nibble - } - return (tRawData | (tChecksum & 0xF)); -} - -/** - * LG uses the NEC repeat. - */ -void IRsend::sendLG(uint8_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats) { - sendPulseDistanceWidth(&LGProtocolConstants, computeLGRawDataAndChecksum(aAddress, aCommand), LG_BITS, aNumberOfRepeats); -} - -/** - * LG2 uses a special repeat. - */ -void IRsend::sendLG2(uint8_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats) { - sendPulseDistanceWidth(&LG2ProtocolConstants, computeLGRawDataAndChecksum(aAddress, aCommand), LG_BITS, aNumberOfRepeats); -} - -bool IRrecv::decodeLG() { - decode_type_t tProtocol = LG; - uint16_t tHeaderSpace = LG_HEADER_SPACE; - - /* - * First check for right data length - * Next check start bit - * Next try the decode - */ - -// Check we have the right amount of data (60). The +4 is for initial gap, start bit mark and space + stop bit mark. - if (decodedIRData.rawDataPtr->rawlen != ((2 * LG_BITS) + 4) && (decodedIRData.rawDataPtr->rawlen != 4)) { - IR_DEBUG_PRINT(F("LG: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 60 or 4")); - return false; - } - -// Check header "mark" this must be done for repeat and data - if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], LG_HEADER_MARK)) { - if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], LG2_HEADER_MARK)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("LG: ")); - Serial.println(F("Header mark is wrong")); -#endif - return false; - } else { - tProtocol = LG2; - tHeaderSpace = LG2_HEADER_SPACE; - } - } - -// Check for repeat - here we have another header space length - if (decodedIRData.rawDataPtr->rawlen == 4) { - if (matchSpace(decodedIRData.rawDataPtr->rawbuf[2], LG_REPEAT_HEADER_SPACE) - && matchMark(decodedIRData.rawDataPtr->rawbuf[3], LG_BIT_MARK)) { - decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_MSB_FIRST; - decodedIRData.address = lastDecodedAddress; - decodedIRData.command = lastDecodedCommand; - decodedIRData.protocol = lastDecodedProtocol; - return true; - } -#if defined(LOCAL_DEBUG) - Serial.print(F("LG: ")); - Serial.print(F("Repeat header space is wrong")); -#endif - return false; - } - -// Check command header space - if (!matchSpace(decodedIRData.rawDataPtr->rawbuf[2], tHeaderSpace)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("LG: ")); - Serial.println(F("Header space length is wrong")); -#endif - return false; - } - - if (!decodePulseDistanceWidthData(&LGProtocolConstants, LG_BITS)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("LG: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - -// Success - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; - decodedIRData.command = (decodedIRData.decodedRawData >> LG_CHECKSUM_BITS) & 0xFFFF; - decodedIRData.address = decodedIRData.decodedRawData >> (LG_COMMAND_BITS + LG_CHECKSUM_BITS); // first 8 bit - - /* - * My guess of the checksum - */ - uint8_t tChecksum = 0; - uint16_t tTempForChecksum = decodedIRData.command; - for (int i = 0; i < 4; ++i) { - tChecksum += tTempForChecksum & 0xF; // add low nibble - tTempForChecksum >>= 4; // shift by a nibble - } -// Checksum check - if ((tChecksum & 0xF) != (decodedIRData.decodedRawData & 0xF)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("LG: ")); - Serial.print(F("4 bit checksum is not correct. expected=0x")); - Serial.print(tChecksum, HEX); - Serial.print(F(" received=0x")); - Serial.print((decodedIRData.decodedRawData & 0xF), HEX); - Serial.print(F(" data=0x")); - Serial.println(decodedIRData.command, HEX); -#endif - decodedIRData.flags |= IRDATA_FLAGS_PARITY_FAILED; - } - - decodedIRData.protocol = tProtocol; // LG or LG2 - decodedIRData.numberOfBits = LG_BITS; - - return true; -} - -/********************************************************************************* - * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials - *********************************************************************************/ - -/** - * Here you can put your raw data, even one with "wrong" checksum. - * @param aRawData The lowest 28 (LG_BITS) bit of this value are sent MSB first. - * @param aNumberOfRepeats If < 0 then only a special repeat frame will be sent. - */ -void IRsend::sendLGRaw(uint32_t aRawData, int_fast8_t aNumberOfRepeats) { - sendPulseDistanceWidth(&LGProtocolConstants, aRawData, LG_BITS, aNumberOfRepeats); -} - -bool IRrecv::decodeLGMSB(decode_results *aResults) { - unsigned int offset = 1; // Skip first space - -// Check we have enough data (60) - +4 for initial gap, start bit mark and space + stop bit mark - if (aResults->rawlen != (2 * LG_BITS) + 4) { - return false; - } - -// Initial mark/space - if (!matchMark(aResults->rawbuf[offset], LG_HEADER_MARK)) { - return false; - } - offset++; - - if (!matchSpace(aResults->rawbuf[offset], LG_HEADER_SPACE)) { - return false; - } - offset++; - - if (!decodePulseDistanceWidthData(LG_BITS, offset, LG_BIT_MARK, 0, LG_ONE_SPACE, LG_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST)) { - return false; - } -// Stop bit - if (!matchMark(aResults->rawbuf[offset + (2 * LG_BITS)], LG_BIT_MARK)) { -#if defined(LOCAL_DEBUG) - Serial.println(F("Stop bit mark length is wrong")); -#endif - return false; - } - -// Success - aResults->value = decodedIRData.decodedRawData; - aResults->bits = LG_BITS; - aResults->decode_type = LG; - decodedIRData.protocol = LG; - return true; -} - -//+============================================================================= -void IRsend::sendLG(unsigned long data, int nbits) { -// Set IR carrier frequency - enableIROut (LG_KHZ); -#if !(defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)) -// Serial.println(F( -// "The function sendLG(data, nbits) is deprecated and may not work as expected! Use sendLGRaw(data, NumberOfRepeats) or better sendLG(Address, Command, NumberOfRepeats).")); -#endif -// Header - mark(LG_HEADER_MARK); - space(LG_HEADER_SPACE); -// mark(LG_BIT_MARK); - -// Data + stop bit - sendPulseDistanceWidthData(LG_BIT_MARK, LG_ONE_SPACE, LG_BIT_MARK, LG_ZERO_SPACE, data, nbits, PROTOCOL_IS_MSB_FIRST); -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_LG_HPP diff --git a/IRremote/src/ir_Lego.hpp b/IRremote/src/ir_Lego.hpp deleted file mode 100644 index 2f87be67336835acae21f48c799a01d7fec7d37d..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_Lego.hpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * ir_Lego.hpp - * - * Contains functions for receiving and sending Lego Power Functions IR Protocol - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_LEGO_HPP -#define _IR_LEGO_HPP - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// L EEEEEE EEEE OOOO -// L E E O O -// L EEEE E EEE O O -// L E E E O O -// LLLLLL EEEEEE EEEE OOOO -//============================================================================== -// from LEGO Power Functions RC Manual 26.02.2010 Version 1.20 -// https://github.com/jurriaan/Arduino-PowerFunctions/raw/master/LEGO_Power_Functions_RC_v120.pdf -// https://oberguru.net/elektronik/ir/codes/lego_power_functions_train.lircd.conf -// -// To ensure correct detection of IR messages six 38 kHz cycles are transmitted as mark. -// Low bit consists of 6 cycles of IR and 10 �cycles� of pause, -// high bit of 6 cycles IR and 21 �cycles� of pause and start bit of 6 cycles IR and 39 �cycles� of pause. -// Low bit range 316 - 526 us -// High bit range 526 � 947 us -// Start/stop bit range 947 � 1579 us -// If tm is the maximum message length (16ms) and Ch is the channel number, then -// The delay before transmitting the first message is: (4 � Ch)*tm -// The time from start to start for the next 2 messages is: 5*tm -// The time from start to start for the following messages is: (6 + 2*Ch)*tm -// Supported Devices -// LEGO Power Functions IR Receiver 8884 -// MSB first, 1 start bit + 4 bit channel, 4 bit mode + 4 bit command + 4 bit parity + 1 stop bit. -#define LEGO_CHANNEL_BITS 4 -#define LEGO_MODE_BITS 4 -#define LEGO_COMMAND_BITS 4 -#define LEGO_PARITY_BITS 4 - -#define LEGO_BITS (LEGO_CHANNEL_BITS + LEGO_MODE_BITS + LEGO_COMMAND_BITS + LEGO_PARITY_BITS) - -#define LEGO_HEADER_MARK 158 // 6 cycles -#define LEGO_HEADER_SPACE 1026 // 39 cycles - -#define LEGO_BIT_MARK 158 // 6 cycles -#define LEGO_ONE_SPACE 553 // 21 cycles -#define LEGO_ZERO_SPACE 263 // 10 cycles - -#define LEGO_AVERAGE_DURATION 11000 // LEGO_HEADER_MARK + LEGO_HEADER_SPACE + 16 * 600 + 158 - -#define LEGO_AUTO_REPEAT_PERIOD_MIN 110000 // Every frame is auto repeated 5 times. -#define LEGO_AUTO_REPEAT_PERIOD_MAX 230000 // space for channel 3 - -#define LEGO_MODE_EXTENDED 0 -#define LEGO_MODE_COMBO 1 -#define LEGO_MODE_SINGLE 0x4 // here the 2 LSB have meanings like Output A / Output B - -struct PulseDistanceWidthProtocolConstants LegoProtocolConstants = { LEGO_PF, 38, LEGO_HEADER_MARK, LEGO_HEADER_SPACE, LEGO_BIT_MARK, -LEGO_ONE_SPACE, LEGO_BIT_MARK, LEGO_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, (LEGO_AUTO_REPEAT_PERIOD_MIN - / MICROS_IN_ONE_MILLI), NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ -/* - * Here we process the structured data, and call the send raw data function - * @param aMode one of LEGO_MODE_EXTENDED, LEGO_MODE_COMBO, LEGO_MODE_SINGLE - */ -void IRsend::sendLegoPowerFunctions(uint8_t aChannel, uint8_t aCommand, uint8_t aMode, bool aDoSend5Times) { - aChannel &= 0x0F; // allow toggle and escape bits too - aCommand &= 0x0F; - aMode &= 0x0F; - uint8_t tParity = 0xF ^ aChannel ^ aMode ^ aCommand; - // send 4 bit channel, 4 bit mode, 4 bit command, 4 bit parity - uint16_t tRawData = (((aChannel << LEGO_MODE_BITS) | aMode) << (LEGO_COMMAND_BITS + LEGO_PARITY_BITS)) - | (aCommand << LEGO_PARITY_BITS) | tParity; - sendLegoPowerFunctions(tRawData, aChannel, aDoSend5Times); -} - -void IRsend::sendLegoPowerFunctions(uint16_t aRawData, uint8_t aChannel, bool aDoSend5Times) { - - IR_DEBUG_PRINT(F("sendLego aRawData=0x")); - IR_DEBUG_PRINTLN(aRawData, HEX); - - aChannel &= 0x03; // we have 4 channels - - uint_fast8_t tNumberOfRepeats = 0; - if (aDoSend5Times) { - tNumberOfRepeats = 4; - } -// required for repeat timing, see http://www.hackvandedam.nl/blog/?page_id=559 - uint8_t tRepeatPeriod = (LEGO_AUTO_REPEAT_PERIOD_MIN / MICROS_IN_ONE_MILLI) + (aChannel * 40); // from 110 to 230 - LegoProtocolConstants.RepeatPeriodMillis = tRepeatPeriod; - sendPulseDistanceWidth(&LegoProtocolConstants, aRawData, LEGO_BITS, tNumberOfRepeats); -} - -/* - * Mode is stored in the upper nibble of command - */ -bool IRrecv::decodeLegoPowerFunctions() { - - if (!checkHeader(&LegoProtocolConstants)) { - return false; - } - - // Check we have enough data - +4 for initial gap, start bit mark and space + stop bit mark - if (decodedIRData.rawDataPtr->rawlen != (2 * LEGO_BITS) + 4) { - IR_DEBUG_PRINT(F("LEGO: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 36")); - return false; - } - - if (!decodePulseDistanceWidthData(&LegoProtocolConstants, LEGO_BITS)) { - IR_DEBUG_PRINT(F("LEGO: ")); - IR_DEBUG_PRINTLN(F("Decode failed")); - return false; - } - - // Stop bit - if (!matchMark(decodedIRData.rawDataPtr->rawbuf[3 + (2 * LEGO_BITS)], LEGO_BIT_MARK)) { - IR_DEBUG_PRINT(F("LEGO: ")); - IR_DEBUG_PRINTLN(F("Stop bit mark length is wrong")); - return false; - } - - // Success - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; - uint16_t tDecodedValue = decodedIRData.decodedRawData; - uint8_t tToggleEscapeChannel = tDecodedValue >> (LEGO_MODE_BITS + LEGO_COMMAND_BITS + LEGO_PARITY_BITS); - uint8_t tMode = (tDecodedValue >> (LEGO_COMMAND_BITS + LEGO_PARITY_BITS)) & 0xF; - uint8_t tData = (tDecodedValue >> LEGO_PARITY_BITS) & 0xF; // lego calls this field "data" - uint8_t tParityReceived = tDecodedValue & 0xF; - - // This is parity as defined in the specifications - // But in some scans I saw 0x9 ^ .. as parity formula - uint8_t tParityComputed = 0xF ^ tToggleEscapeChannel ^ tMode ^ tData; - - // parity check - if (tParityReceived != tParityComputed) { - IR_DEBUG_PRINT(F("LEGO: ")); - IR_DEBUG_PRINT(F("Parity is not correct. expected=0x")); - IR_DEBUG_PRINT(tParityComputed, HEX); - IR_DEBUG_PRINT(F(" received=0x")); - IR_DEBUG_PRINT(tParityReceived, HEX); - IR_DEBUG_PRINT(F(", raw=0x")); - IR_DEBUG_PRINT(tDecodedValue, HEX); - IR_DEBUG_PRINT(F(", 3 nibbles are 0x")); - IR_DEBUG_PRINT(tToggleEscapeChannel, HEX); - IR_DEBUG_PRINT(F(", 0x")); - IR_DEBUG_PRINT(tMode, HEX); - IR_DEBUG_PRINT(F(", 0x")); - IR_DEBUG_PRINTLN(tData, HEX); - // might not be an error, so just continue - decodedIRData.flags = IRDATA_FLAGS_PARITY_FAILED | IRDATA_FLAGS_IS_MSB_FIRST; - } - - /* - * Check for autorepeat (should happen 4 times for one press) - */ - if (decodedIRData.rawDataPtr->rawbuf[0] < (LEGO_AUTO_REPEAT_PERIOD_MAX / MICROS_PER_TICK)) { - decodedIRData.flags |= IRDATA_FLAGS_IS_AUTO_REPEAT; - } - decodedIRData.address = tToggleEscapeChannel; - decodedIRData.command = tData | tMode << LEGO_COMMAND_BITS; - decodedIRData.numberOfBits = LEGO_BITS; - decodedIRData.protocol = LEGO_PF; - - return true; -} - -/********************************************************************************* - * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials - *********************************************************************************/ - -void IRsend::sendLegoPowerFunctions(uint16_t aRawData, bool aDoSend5Times) { - sendLegoPowerFunctions(aRawData, (aRawData >> (LEGO_MODE_BITS + LEGO_COMMAND_BITS + LEGO_PARITY_BITS)) & 0x3, aDoSend5Times); -} - -/** @}*/ -#endif // _IR_LEGO_HPP diff --git a/IRremote/src/ir_MagiQuest.hpp b/IRremote/src/ir_MagiQuest.hpp deleted file mode 100644 index 6e82550bf3ed79cc1b909cba0c461ac986d96116..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_MagiQuest.hpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - * ir_MagiQuest.hpp - * - * Contains functions for receiving and sending MagiQuest Protocol - * Based off the Magiquest fork of Arduino-IRremote by mpflaga https://github.com/mpflaga/Arduino-IRremote/ - * - * RESULT: - * The 31 bit wand ID is available in decodedRawData. - * The lower 16 bit of the ID is available in address. - * The magnitude is available in command. - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2017-2023 E. Stuart Hicks <ehicks@binarymagi.com>, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_MAGIQUEST_HPP -#define _IR_MAGIQUEST_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif -// -//============================================================================== -// -// M M AA GGG III QQQ U U EEEE SSS TTTTTT -// MM MM A A G I Q Q U U E S TT -// M M M AAAA G GG I Q Q U U EEE SSS TT -// M M A A G G I Q QQ U U E S TT -// M M A A GGG III QQQQ UUU EEEE SSSS TT -// Q -//============================================================================== -/* - * https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp - * https://github.com/Arduino-IRremote/Arduino-IRremote/discussions/1027#discussioncomment-3636857 - * https://github.com/Arduino-IRremote/Arduino-IRremote/issues/1015#issuecomment-1222247231 - - Protocol=MagiQuest Address=0xFF00 Command=0x176 Raw-Data=0x6BCDFF00 56 bits MSB first - + 250,- 800 + 250,- 850 + 250,- 850 + 250,- 850 // 8 zero start bits - + 250,- 850 + 300,- 800 + 250,- 850 + 250,- 850 - - // 31 ID bits - + 550,- 600 + 550,- 550 + 350,- 800 + 600,- 600 // 110 1 6 - + 200,- 950 + 550,- 600 + 550,- 600 + 550,- 600 // 011 1 B - 1(from above)011 => B - + 550,- 600 + 250,- 900 + 300,- 850 + 550,- 600 // 100 1 C - + 550,- 600 + 300,- 850 + 550,- 600 + 550,- 600 - + 550,- 600 + 550,- 600 + 550,- 600 + 550,- 600 - + 550,- 600 + 550,- 600 + 550,- 600 + 300,- 800 - + 350,- 850 + 300,- 850 + 300,- 850 + 300,- 850 - + 300,- 850 + 300,- 850 + 300,- 850 + 550,- 600 // 000 1 - 3 LSB ID bits 000 + 1 MSB magnitude bit 1 - - // 8 bit magnitude - + 300,- 850 + 550,- 600 + 550,- 600 + 550,- 600 - + 300,- 850 + 550,- 600 + 550,- 600 + 250,- 900 - - // Checksum (+ sum of the 5 bytes before == 0) - + 250,- 900 + 300,- 900 + 250,- 850 + 550,- 600 - + 600,- 550 + 300,- 900 + 250,- 850 + 550 - */ -// MSB first, 8 start bits (zero), 31 wand id bits, 9 magnitude bits 8 checksum bits and no stop bit => 56 bits -#define MAGIQUEST_CHECKSUM_BITS 8 // magiquest_t.cmd.checksum -#define MAGIQUEST_MAGNITUDE_BITS 9 // magiquest_t.cmd.magnitude -#define MAGIQUEST_WAND_ID_BITS 31 // magiquest_t.cmd.wand_id -> wand-id is handled as 32 bit and always even -#define MAGIQUEST_START_BITS 8 // magiquest_t.cmd.StartBits - -#define MAGIQUEST_PERIOD 1150 // Time for a full MagiQuest "bit" (1100 - 1200 usec) - -#define MAGIQUEST_DATA_BITS (MAGIQUEST_CHECKSUM_BITS + MAGIQUEST_MAGNITUDE_BITS + MAGIQUEST_WAND_ID_BITS) // 48 Size of the command without the start bits -#define MAGIQUEST_BITS (MAGIQUEST_CHECKSUM_BITS + MAGIQUEST_MAGNITUDE_BITS + MAGIQUEST_WAND_ID_BITS + MAGIQUEST_START_BITS) // 56 Size of the command with the start bits - -/* - * 0 = 25% mark & 75% space across 1 period - * 1150 * 0.25 = 288 usec mark - * 1150 - 288 = 862 usec space - * 1 = 50% mark & 50% space across 1 period - * 1150 * 0.5 = 575 usec mark - * 1150 - 575 = 575 usec space - */ -#define MAGIQUEST_UNIT (MAGIQUEST_PERIOD / 4) // 287.5 - -#define MAGIQUEST_ONE_MARK (2 * MAGIQUEST_UNIT) // 576 -#define MAGIQUEST_ONE_SPACE (2 * MAGIQUEST_UNIT) // 576 -#define MAGIQUEST_ZERO_MARK MAGIQUEST_UNIT // 287.5 -#define MAGIQUEST_ZERO_SPACE (3 * MAGIQUEST_UNIT) // 864 - -// assume 110 as repeat period -struct PulseDistanceWidthProtocolConstants MagiQuestProtocolConstants = { MAGIQUEST, 38, MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE, -MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE, MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST, 110, NULL }; -//+============================================================================= -// -/** - * @param aWandId 31 bit ID - * @param aMagnitude 9 bit Magnitude - */ -void IRsend::sendMagiQuest(uint32_t aWandId, uint16_t aMagnitude) { - - // Set IR carrier frequency - enableIROut(38); - - aMagnitude &= 0x1FF; // we have 9 bit - LongUnion tWandId; - tWandId.ULong = aWandId << 1; - uint8_t tChecksum = (tWandId.Bytes[0]) + tWandId.Bytes[1] + tWandId.Bytes[2] + tWandId.Bytes[3]; - tChecksum += aMagnitude + (aMagnitude >> 8); - tChecksum = ~tChecksum + 1; - - // 8 start bits - sendPulseDistanceWidthData(&MagiQuestProtocolConstants, 0, 8); - // 48 bit data - sendPulseDistanceWidthData(&MagiQuestProtocolConstants, aWandId, MAGIQUEST_WAND_ID_BITS); // send only 31 bit, do not send MSB here - sendPulseDistanceWidthData(&MagiQuestProtocolConstants, aMagnitude, MAGIQUEST_MAGNITUDE_BITS); - sendPulseDistanceWidthData(&MagiQuestProtocolConstants, tChecksum, MAGIQUEST_CHECKSUM_BITS); -#if defined(LOCAL_DEBUG) - // must be after sending, in order not to destroy the send timing - Serial.print(F("MagiQuest checksum=0x")); - Serial.println(tChecksum, HEX); -#endif -} - -//+============================================================================= -// -/* - * decodes a 56 bit result, which is not really compatible with standard decoder layout - * magnitude is stored in command - * 31 bit wand_id is stored in decodedRawData - * lower 16 bit of wand_id is stored in address - */ -bool IRrecv::decodeMagiQuest() { - - // Check we have the right amount of data, magnitude and ID bits and 8 start bits + 0 stop bit - if (decodedIRData.rawDataPtr->rawlen != (2 * MAGIQUEST_BITS)) { - IR_DEBUG_PRINT(F("MagiQuest: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 112")); - return false; - } - - /* - * Check for 8 zero header bits - */ - if (!decodePulseDistanceWidthData(&MagiQuestProtocolConstants, MAGIQUEST_START_BITS, 1)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("MagiQuest: ")); - Serial.println(F("Start bit decode failed")); -#endif - return false; - } - if (decodedIRData.decodedRawData != 0) { -#if defined(LOCAL_DEBUG) - Serial.print(F("MagiQuest: ")); - Serial.print(F("Not 8 leading zero start bits received, RawData=0x")); - Serial.println(decodedIRData.decodedRawData, HEX); -#endif - return false; - } - - /* - * Decode the 31 bit ID - */ - if (!decodePulseDistanceWidthData(&MagiQuestProtocolConstants, MAGIQUEST_WAND_ID_BITS, (MAGIQUEST_START_BITS * 2) + 1)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("MagiQuest: ")); - Serial.println(F("ID decode failed")); -#endif - return false; - } - LongUnion tDecodedRawData; -#if defined(LOCAL_DEBUG) - Serial.print(F("31 bit WandId=0x")); - Serial.println(decodedIRData.decodedRawData, HEX); -#endif - uint32_t tWandId = decodedIRData.decodedRawData; // save tWandId for later use - tDecodedRawData.ULong = decodedIRData.decodedRawData << 1; // shift for checksum computation - uint8_t tChecksum = tDecodedRawData.Bytes[0] + tDecodedRawData.Bytes[1] + tDecodedRawData.Bytes[2] + tDecodedRawData.Bytes[3]; -#if defined(LOCAL_DEBUG) - Serial.print(F("31 bit WandId=0x")); - Serial.print(decodedIRData.decodedRawData, HEX); - Serial.print(F(" shifted=0x")); - Serial.println(tDecodedRawData.ULong, HEX); -#endif - /* - * Decode the 9 bit Magnitude + 8 bit checksum - */ - if (!decodePulseDistanceWidthData(&MagiQuestProtocolConstants, MAGIQUEST_MAGNITUDE_BITS + MAGIQUEST_CHECKSUM_BITS, - ((MAGIQUEST_WAND_ID_BITS + MAGIQUEST_START_BITS) * 2) + 1)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("MagiQuest: ")); - Serial.println(F("Magnitude + checksum decode failed")); -#endif - return false; - } - -#if defined(LOCAL_DEBUG) - Serial.print(F("Magnitude + checksum=0x")); - Serial.println(decodedIRData.decodedRawData, HEX); -#endif - tDecodedRawData.ULong = decodedIRData.decodedRawData; - decodedIRData.command = tDecodedRawData.UBytes[1] | tDecodedRawData.UBytes[2] << 8; // Values observed are 0x102,01,04,37,05,38,2D| 02,06,04|03,103,12,18,0E|09 - - tChecksum += tDecodedRawData.UBytes[2] /* only one bit */+ tDecodedRawData.UBytes[1] + tDecodedRawData.UBytes[0]; - if (tChecksum != 0) { - decodedIRData.flags |= IRDATA_FLAGS_PARITY_FAILED; -#if defined(LOCAL_DEBUG) - Serial.print(F("Checksum 0x")); - Serial.print(tChecksum, HEX); - Serial.println(F(" is not 0")); -#endif - } - - // Success - decodedIRData.decodedRawData = tWandId; // 31 bit wand_id - decodedIRData.address = tWandId; // lower 16 bit of wand_id - decodedIRData.extra = tWandId >> 16; // upper 15 bit of wand_id - - decodedIRData.protocol = MAGIQUEST; - decodedIRData.numberOfBits = MAGIQUEST_BITS; - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; - - return true; -} -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_MAGIQUEST_HPP diff --git a/IRremote/src/ir_NEC.hpp b/IRremote/src/ir_NEC.hpp deleted file mode 100644 index 1c02e7d4f71e5b0d6512788e6dc80a4f8d7fb3bc..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_NEC.hpp +++ /dev/null @@ -1,432 +0,0 @@ -/* - * ir_NEC.hpp - * - * Contains functions for receiving and sending NEC IR Protocol in "raw" and standard format with 16 or 8 bit address and 8 bit command - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_NEC_HPP -#define _IR_NEC_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// N N EEEEE CCCC -// NN N E C -// N N N EEE C -// N NN E C -// N N EEEEE CCCC -//============================================================================== -/* - Protocol=NEC Address=0x4 Command=0x8 Raw-Data=0xF708FB04 32 bits LSB first - +8950,-4450 - + 600,- 500 + 650,- 500 + 600,-1650 + 600,- 550 - + 600,- 500 + 600,- 500 + 650,- 500 + 600,- 500 - + 650,-1650 + 600,-1600 + 650,- 500 + 600,-1650 - + 600,-1650 + 600,-1650 + 600,-1600 + 650,-1600 - + 650,- 500 + 600,- 550 + 600,- 500 + 600,-1650 - + 600,- 550 + 600,- 500 + 600,- 550 + 600,- 500 - + 600,-1650 + 600,-1650 + 600,-1650 + 600,- 550 - + 600,-1650 + 600,-1650 + 600,-1650 + 600,-1600 - + 650 - Sum: 68000 - - Protocol=NEC Address=0x8 Command=0x7 Repeat gap=40900us - rawData[4]: - -40900 - +10450,-2250 - + 700 - Sum: 13400 - */ -// http://www.hifi-remote.com/wiki/index.php/NEC -// https://www.sbprojects.net/knowledge/ir/nec.php -// for Apple see https://en.wikipedia.org/wiki/Apple_Remote - Fixed address 0x87EE, 8 bit device ID, 7 bit command, 1 bit parity - untested! -// ONKYO like NEC but 16 independent address and command bits -// APPLE like ONKYO with special NEC repeat but with constant address of 0x87EE and and 16 bit command interpreted as MSB = 8 bit device ID, LSB = 8 bit command -// PIONEER (not implemented) is NEC2 with 40 kHz -// LSB first, 1 start bit + 16 bit address (or 8 bit address and 8 bit inverted address) + 8 bit command + 8 bit inverted command + 1 stop bit. -// Standard NEC sends a special fixed repeat frame. -// NEC2 sends the same full frame after the 110 ms. I have a DVD remote with NEC2. -// NEC and NEC 2 only differ in the repeat frames, so the protocol can only be detected correctly after the first repeat. -// -// IRP: NEC {38.0k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,^108m,(16,-4,1,^108m)*) ==> "*" means send special repeat frames o ore more times -// IRP: NEC2 {38.0k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,^108m)+ ==> "+" means send frame 1 or more times (special repeat is missing here!) -// {38.0k,564} ==> 38.0k -> Frequency , 564 -> unit in microseconds (we use 560), no "msb", so "lsb" is assumed -// <1,-1|1,-3> ==> Zero is 1 unit mark and space | One is 1 unit mark and 3 units space -// 16,-8 ==> Start bit durations -// D:8,S:8,F:8,~F:8 ==> D:8 -> 8 bit bitfield for Device, S:8 -> 8 bit bitfield for Subdevice, F:8 -> 8 bit bitfield for Function, ~F:8 -> 8 bit inverted bitfield for Function -// 1,^108m ==> 1 -> unit mark Stop bit, ^108m -> wait until 108 milliseconds after start of protocol (we use 110) -// -#define NEC_ADDRESS_BITS 16 // 16 bit address or 8 bit address and 8 bit inverted address -#define NEC_COMMAND_BITS 16 // Command and inverted command - -#define NEC_BITS (NEC_ADDRESS_BITS + NEC_COMMAND_BITS) -#define NEC_UNIT 560 // 21.28 periods of 38 kHz, 11.2 ticks TICKS_LOW = 8.358 TICKS_HIGH = 15.0 - -#define NEC_HEADER_MARK (16 * NEC_UNIT) // 9000 | 180 -#define NEC_HEADER_SPACE (8 * NEC_UNIT) // 4500 | 90 - -#define NEC_BIT_MARK NEC_UNIT -#define NEC_ONE_SPACE (3 * NEC_UNIT) // 1690 | 33.8 TICKS_LOW = 25.07 TICKS_HIGH = 45.0 -#define NEC_ZERO_SPACE NEC_UNIT - -#define NEC_REPEAT_HEADER_SPACE (4 * NEC_UNIT) // 2250 - -#define NEC_AVERAGE_DURATION 62000 // NEC_HEADER_MARK + NEC_HEADER_SPACE + 32 * 2,5 * NEC_UNIT + NEC_UNIT // 2.5 because we assume more zeros than ones -#define NEC_MINIMAL_DURATION 49900 // NEC_HEADER_MARK + NEC_HEADER_SPACE + 32 * 2 * NEC_UNIT + NEC_UNIT // 2.5 because we assume more zeros than ones -#define NEC_REPEAT_DURATION (NEC_HEADER_MARK + NEC_REPEAT_HEADER_SPACE + NEC_BIT_MARK) // 12 ms -#define NEC_REPEAT_PERIOD 110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down. -#define NEC_REPEAT_DISTANCE (NEC_REPEAT_PERIOD - NEC_AVERAGE_DURATION) // 48 ms -#define NEC_MAXIMUM_REPEAT_DISTANCE (NEC_REPEAT_PERIOD - NEC_MINIMAL_DURATION + 10000) // 70 ms - -#define APPLE_ADDRESS 0x87EE - -struct PulseDistanceWidthProtocolConstants NECProtocolConstants = - { NEC, NEC_KHZ, NEC_HEADER_MARK, NEC_HEADER_SPACE, NEC_BIT_MARK, - NEC_ONE_SPACE, NEC_BIT_MARK, NEC_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, (NEC_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), - &sendNECSpecialRepeat }; - -// Like NEC but repeats are full frames instead of special NEC repeats -struct PulseDistanceWidthProtocolConstants NEC2ProtocolConstants = { NEC2, NEC_KHZ, NEC_HEADER_MARK, NEC_HEADER_SPACE, NEC_BIT_MARK, -NEC_ONE_SPACE, NEC_BIT_MARK, NEC_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, (NEC_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ - -/** - * Send special NEC repeat frame - * Repeat commands should be sent in a 110 ms raster. - */ -void IRsend::sendNECRepeat() { - enableIROut (NEC_KHZ); // 38 kHz - mark(NEC_HEADER_MARK); // + 9000 - space(NEC_REPEAT_HEADER_SPACE); // - 2250 - mark(NEC_BIT_MARK); // + 560 -} - -/** - * Static function for sending special repeat frame. - * For use in ProtocolConstants. Saves up to 250 bytes compared to a member function. - */ -void sendNECSpecialRepeat() { - IrSender.enableIROut(NEC_KHZ); // 38 kHz - IrSender.mark(NEC_HEADER_MARK); // + 9000 - IrSender.space(NEC_REPEAT_HEADER_SPACE); // - 2250 - IrSender.mark(NEC_BIT_MARK); // + 560 -} - -uint32_t IRsend::computeNECRawDataAndChecksum(uint16_t aAddress, uint16_t aCommand) { - LongUnion tRawData; - - // Address 16 bit LSB first - if ((aAddress & 0xFF00) == 0) { - // assume 8 bit address -> send 8 address bits and then 8 inverted address bits LSB first - tRawData.UByte.LowByte = aAddress; - tRawData.UByte.MidLowByte = ~tRawData.UByte.LowByte; - } else { - tRawData.UWord.LowWord = aAddress; - } - - // send 8 command bits and then 8 inverted command bits LSB first - tRawData.UByte.MidHighByte = aCommand; - tRawData.UByte.HighByte = ~aCommand; - return tRawData.ULong; -} - -/** - * NEC Send frame and special repeats - * There is NO delay after the last sent repeat! - * @param aNumberOfRepeats If < 0 then only a special repeat frame without leading and trailing space - * will be sent by calling NECProtocolConstants.SpecialSendRepeatFunction(). - */ -void IRsend::sendNEC(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - sendPulseDistanceWidth(&NECProtocolConstants, computeNECRawDataAndChecksum(aAddress, aCommand), NEC_BITS, aNumberOfRepeats); -} - -/* - * NEC2 Send frame and repeat the frame for each requested repeat - * There is NO delay after the last sent repeat! - * @param aNumberOfRepeats If < 0 then nothing is sent. - */ -void IRsend::sendNEC2(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - sendPulseDistanceWidth(&NEC2ProtocolConstants, computeNECRawDataAndChecksum(aAddress, aCommand), NEC_BITS, aNumberOfRepeats); -} - -/* - * Repeat commands should be sent in a 110 ms raster. - * There is NO delay after the last sent repeat! - * @param aNumberOfRepeats If < 0 then only a special repeat frame without leading and trailing space - * will be sent by calling NECProtocolConstants.SpecialSendRepeatFunction(). - */ -void IRsend::sendOnkyo(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats) { - sendPulseDistanceWidth(&NECProtocolConstants, (uint32_t) aCommand << 16 | aAddress, NEC_BITS, aNumberOfRepeats); -} - -/* - * Repeat commands should be sent in a 110 ms raster. - * There is NO delay after the last sent repeat! - * https://en.wikipedia.org/wiki/Apple_Remote - * https://gist.github.com/darconeous/4437f79a34e3b6441628 - * @param aAddress is the DeviceId* - * @param aNumberOfRepeats If < 0 then only a special repeat frame without leading and trailing space - * will be sent by calling NECProtocolConstants.SpecialSendRepeatFunction(). - */ -void IRsend::sendApple(uint8_t aDeviceId, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - LongUnion tRawData; - - // Address 16 bit LSB first - tRawData.UWord.LowWord = APPLE_ADDRESS; - - // send Apple code and then 8 command bits LSB first - tRawData.UByte.MidHighByte = aCommand; - tRawData.UByte.HighByte = aDeviceId; // e.g. 0xD7 - - sendPulseDistanceWidth(&NECProtocolConstants, tRawData.ULong, NEC_BITS, aNumberOfRepeats); -} - -/* - * Sends NEC1 protocol - * @param aNumberOfRepeats If < 0 then only a special repeat frame without leading and trailing space - * will be sent by calling NECProtocolConstants.SpecialSendRepeatFunction(). - */ -void IRsend::sendNECRaw(uint32_t aRawData, int_fast8_t aNumberOfRepeats) { - sendPulseDistanceWidth(&NECProtocolConstants, aRawData, NEC_BITS, aNumberOfRepeats); -} - -/** - * Decodes also Onkyo and Apple - */ -bool IRrecv::decodeNEC() { - /* - * First check for right data length - * Next check start bit - * Next try the decode - */ - // Check we have the right amount of data (68). The +4 is for initial gap, start bit mark and space + stop bit mark. - if (decodedIRData.rawDataPtr->rawlen != ((2 * NEC_BITS) + 4) && (decodedIRData.rawDataPtr->rawlen != 4)) { - IR_DEBUG_PRINT(F("NEC: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 68 or 4")); - return false; - } - - // Check header "mark" this must be done for repeat and data - if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], NEC_HEADER_MARK)) { - return false; - } - - // Check for repeat - here we have another header space length - if (decodedIRData.rawDataPtr->rawlen == 4) { - if (matchSpace(decodedIRData.rawDataPtr->rawbuf[2], NEC_REPEAT_HEADER_SPACE) - && matchMark(decodedIRData.rawDataPtr->rawbuf[3], NEC_BIT_MARK)) { - decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST; - decodedIRData.address = lastDecodedAddress; - decodedIRData.command = lastDecodedCommand; - decodedIRData.protocol = lastDecodedProtocol; - return true; - } - return false; - } - - // Check command header space - if (!matchSpace(decodedIRData.rawDataPtr->rawbuf[2], NEC_HEADER_SPACE)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("NEC: ")); - Serial.println(F("Header space length is wrong")); -#endif - return false; - } - - // Try to decode as NEC protocol - if (!decodePulseDistanceWidthData(&NECProtocolConstants, NEC_BITS)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("NEC: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - - // Success -// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value - LongUnion tValue; - tValue.ULong = decodedIRData.decodedRawData; - decodedIRData.command = tValue.UByte.MidHighByte; // 8 bit - -#if defined(DECODE_ONKYO) - // Here only Onkyo protocol is supported -> force 16 bit address and command decoding - decodedIRData.address = tValue.UWord.LowWord; // first 16 bit - decodedIRData.protocol = ONKYO; - decodedIRData.command = tValue.UWord.HighWord; // 16 bit command -#else - // Address - if (tValue.UWord.LowWord == APPLE_ADDRESS) { - /* - * Apple - */ - decodedIRData.protocol = APPLE; - decodedIRData.address = tValue.UByte.HighByte; - - } else { - /* - * NEC LSB first, so first sent bit is also LSB of decodedIRData.decodedRawData - */ - if (tValue.UByte.LowByte == (uint8_t)(~tValue.UByte.MidLowByte)) { - // standard 8 bit address NEC protocol - decodedIRData.address = tValue.UByte.LowByte; // first 8 bit - } else { - // extended NEC protocol - decodedIRData.address = tValue.UWord.LowWord; // first 16 bit - } - // Check for command if it is 8 bit NEC or 16 bit ONKYO - if (tValue.UByte.MidHighByte == (uint8_t)(~tValue.UByte.HighByte)) { - decodedIRData.protocol = NEC; - } else { - decodedIRData.protocol = ONKYO; - decodedIRData.command = tValue.UWord.HighWord; // 16 bit command - } - } -#endif - - decodedIRData.numberOfBits = NEC_BITS; - - // check for NEC2 repeat, do not check for same content ;-) - checkForRepeatSpaceTicksAndSetFlag(NEC_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK); - if (decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT) { - decodedIRData.protocol = NEC2; - } - return true; -} - -/********************************************************************************* - * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials - *********************************************************************************/ - -bool IRrecv::decodeNECMSB(decode_results *aResults) { - unsigned int offset = 1; // Index in to results; Skip first space. - -// Check header "mark" - if (!matchMark(aResults->rawbuf[offset], NEC_HEADER_MARK)) { - return false; - } - offset++; - -// Check for repeat - if ((aResults->rawlen == 4) && matchSpace(aResults->rawbuf[offset], NEC_REPEAT_HEADER_SPACE) - && matchMark(aResults->rawbuf[offset + 1], NEC_BIT_MARK)) { - aResults->bits = 0; - aResults->value = 0xFFFFFFFF; - decodedIRData.flags |= IRDATA_FLAGS_IS_REPEAT; - decodedIRData.protocol = NEC; - return true; - } - - // Check we have the right amount of data (32). +4 for initial gap, start bit mark and space + stop bit mark - if (aResults->rawlen != (2 * NEC_BITS) + 4) { - IR_DEBUG_PRINT(F("NEC MSB: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(aResults->rawlen); - IR_DEBUG_PRINTLN(F(" is not 68")); - return false; - } - -// Check header "space" - if (!matchSpace(aResults->rawbuf[offset], NEC_HEADER_SPACE)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("NEC MSB: ")); - Serial.println(F("Header space length is wrong")); -#endif - return false; - } - offset++; - - if (!decodePulseDistanceWidthData(NEC_BITS, offset, NEC_BIT_MARK, 0, NEC_ONE_SPACE, NEC_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("NEC MSB: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - - // Stop bit - if (!matchMark(aResults->rawbuf[offset + (2 * NEC_BITS)], NEC_BIT_MARK)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("NEC MSB: ")); - Serial.println(F("Stop bit mark length is wrong")); -#endif - return false; - } - -// Success - aResults->value = decodedIRData.decodedRawData; - aResults->bits = NEC_BITS; - aResults->decode_type = NEC; - decodedIRData.protocol = NEC; - - return true; -} - -/** - * With Send sendNECMSB() you can send your old 32 bit codes. - * To convert one into the other, you must reverse the byte positions and then reverse all bit positions of each byte. - * Or write it as one binary string and reverse/mirror it. - * Example: - * 0xCB340102 byte reverse -> 02 01 34 CB bit reverse-> 40 80 2C D3. - * 0xCB340102 is binary 11001011001101000000000100000010. - * 0x40802CD3 is binary 01000000100000000010110011010011. - * If you read the first binary sequence backwards (right to left), you get the second sequence. - */ -void IRsend::sendNECMSB(uint32_t data, uint8_t nbits, bool repeat) { - // Set IR carrier frequency - enableIROut (NEC_KHZ); - - if (data == 0xFFFFFFFF || repeat) { - sendNECRepeat(); - return; - } - - // Header - mark(NEC_HEADER_MARK); - space(NEC_HEADER_SPACE); - - // Old version with MSB first Data + stop bit - sendPulseDistanceWidthData(NEC_BIT_MARK, NEC_ONE_SPACE, NEC_BIT_MARK, NEC_ZERO_SPACE, data, nbits, PROTOCOL_IS_MSB_FIRST); -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_NEC_HPP diff --git a/IRremote/src/ir_Others.hpp b/IRremote/src/ir_Others.hpp deleted file mode 100644 index 29fcf6c9d9af0b7f0145973747eccbd8df6c8794..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_Others.hpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * ir_Others.hpp - * - * Contains functions for miscellaneous protocols - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ - -#ifndef _IR_OTHERS_HPP -#define _IR_OTHERS_HPP -//============================================================================== -// DDDD IIIII SSSS H H -// D D I S H H -// D D I SSS HHHHH -// D D I S H H -// DDDD IIIII SSSS H H -//============================================================================== - -// DISH support by Todd Treece -// -// The send function needs to be repeated 4 times -// Only send the last for characters of the hex. -// I.E. Use 0x1C10 instead of 0x0000000000001C10 as listed in the LIRC file. -// Here is the LIRC file I found that seems to match the remote codes from the -// oscilloscope: DISH NETWORK (echostar 301): -// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx -#define DISH_BITS 16 -#define DISH_HEADER_MARK 400 -#define DISH_HEADER_SPACE 6100 -#define DISH_BIT_MARK 400 -#define DISH_ONE_SPACE 1700 -#define DISH_ZERO_SPACE 2800 -#define DISH_REPEAT_SPACE 6200 // really? - -struct PulseDistanceWidthProtocolConstants DishProtocolConstants = { UNKNOWN, 56, DISH_HEADER_MARK, DISH_HEADER_SPACE, -DISH_BIT_MARK, DISH_ONE_SPACE, DISH_BIT_MARK, DISH_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST, 40, NULL }; - -void IRsend::sendDish(uint16_t aData) { - sendPulseDistanceWidth(&DishProtocolConstants, aData, DISH_BITS, 4); -} - -//============================================================================== -// W W H H Y Y N N TTTTT EEEEE RRRRR -// W W H H Y Y NN N T E R R -// W W W HHHHH Y N N N T EEE RRRR -// W W W H H Y N NN T E R R -// WWW H H Y N N T EEEEE R R -//============================================================================== -// Whynter A/C ARC-110WD added by Francesco Meschia -// see https://docs.google.com/spreadsheets/d/1dsr4Jh-nzC6xvSKGpLlPBF0NRwvlpyw-ozg8eZU813w/edit#gid=0 -// Looking at the code table the protocol is LSB first with start and stop bit. -// 4 bit checksum, constant address 0xAA00, 8 bit Command and 4 bit Command group -// but we use MSB first to be backwards compatible -#define WHYNTER_BITS 32 -#define WHYNTER_HEADER_MARK 2850 -#define WHYNTER_HEADER_SPACE 2850 -#define WHYNTER_BIT_MARK 750 -#define WHYNTER_ONE_SPACE 2150 -#define WHYNTER_ZERO_SPACE 750 - -struct PulseDistanceWidthProtocolConstants WhynterProtocolConstants = { WHYNTER, 38, WHYNTER_HEADER_MARK, WHYNTER_HEADER_SPACE, -WHYNTER_BIT_MARK, WHYNTER_ONE_SPACE, WHYNTER_BIT_MARK, WHYNTER_ZERO_SPACE, PROTOCOL_IS_MSB_FIRST, 110, NULL }; - -void IRsend::sendWhynter(uint32_t aData, uint8_t aNumberOfBitsToSend) { - sendPulseDistanceWidth(&WhynterProtocolConstants, aData, NEC_BITS, aNumberOfBitsToSend); -} - -bool IRrecv::decodeWhynter() { - // Check we have the right amount of data (68). The +4 is for initial gap, start bit mark and space + stop bit mark. - if (decodedIRData.rawDataPtr->rawlen != (2 * WHYNTER_BITS) + 4) { - return false; - } - if (!checkHeader(&WhynterProtocolConstants)) { - return false; - } - if (!decodePulseDistanceWidthData(&WhynterProtocolConstants, WHYNTER_BITS)) { - return false; - } - // Success - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; - decodedIRData.numberOfBits = WHYNTER_BITS; - decodedIRData.protocol = WHYNTER; - return true; -} - -/** @}*/ -#endif // _IR_OTHERS_HPP diff --git a/IRremote/src/ir_Pronto.hpp b/IRremote/src/ir_Pronto.hpp deleted file mode 100644 index 2a8c9bc32981aa247d8db4a1e430aa9c984a7f66..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_Pronto.hpp +++ /dev/null @@ -1,341 +0,0 @@ -/* - * @file ir_Pronto.hpp - * @brief In this file, the functions IRrecv::compensateAndPrintPronto and IRsend::sendPronto are defined. - * - * See http://www.harctoolbox.org/Glossary.html#ProntoSemantics - * Pronto database http://www.remotecentral.com/search.htm - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2020 Bengt Martensson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_PRONTO_HPP -#define _IR_PRONTO_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ - -//! @cond -// DO NOT EXPORT from this file -static const uint16_t learnedToken = 0x0000U; -static const uint16_t learnedNonModulatedToken = 0x0100U; -static const uint16_t bitsInHexadecimal = 4U; -static const uint16_t digitsInProntoNumber = 4U; -static const uint16_t numbersInPreamble = 4U; -static const uint16_t hexMask = 0xFU; -static const uint32_t referenceFrequency = 4145146UL; -static const uint16_t fallbackFrequency = 64767U; // To use with frequency = 0; -static const uint32_t microsecondsInSeconds = 1000000UL; -static const uint16_t PRONTO_DEFAULT_GAP = 45000; -//! @endcond - -static uint16_t toFrequencyKHz(uint16_t code) { - return ((referenceFrequency / code) + 500) / 1000; -} - -/* - * Parse the string given as Pronto Hex, and send it a number of times given as argument. - * The first number denotes the type of the signal. 0000 denotes a raw IR signal with modulation, - // The second number denotes a frequency code - */ -void IRsend::sendPronto(const uint16_t *data, uint16_t length, int_fast8_t aNumberOfRepeats) { - uint16_t timebase = (microsecondsInSeconds * data[1] + referenceFrequency / 2) / referenceFrequency; - uint16_t khz; - switch (data[0]) { - case learnedToken: // normal, "learned" - khz = toFrequencyKHz(data[1]); - break; - case learnedNonModulatedToken: // non-demodulated, "learned" - khz = 0U; - break; - default: - return; // There are other types, but they are not handled yet. - } - uint16_t intros = 2 * data[2]; - uint16_t repeats = 2 * data[3]; -#if defined(LOCAL_DEBUG) - Serial.print(F("sendPronto intros=")); - Serial.print(intros); - Serial.print(F(" repeats=")); - Serial.println(repeats); -#endif - if (numbersInPreamble + intros + repeats != length) { // inconsistent sizes - return; - } - - /* - * Generate a new microseconds timing array for sendRaw. - * If recorded by IRremote, intro contains the whole IR data and repeat is empty - */ - uint16_t durations[intros + repeats]; - for (uint16_t i = 0; i < intros + repeats; i++) { - uint32_t duration = ((uint32_t) data[i + numbersInPreamble]) * timebase; - durations[i] = (uint16_t) ((duration <= UINT16_MAX) ? duration : UINT16_MAX); - } - - /* - * Send the intro. intros is even. - * Do not send the trailing space here, send it if repeats are requested - */ - if (intros >= 2) { - sendRaw(durations, intros - 1, khz); - } - - if (repeats == 0 || aNumberOfRepeats == 0) { - // only send intro once - return; - } - - /* - * Now send the trailing space/gap of the intro and all the repeats - */ - if (intros >= 2) { - delay(durations[intros - 1] / MICROS_IN_ONE_MILLI); // equivalent to space(durations[intros - 1]); but allow bigger values for the gap - } - for (int i = 0; i < aNumberOfRepeats; i++) { - sendRaw(durations + intros, repeats - 1, khz); - if ((i + 1) < aNumberOfRepeats) { // skip last trailing space/gap, see above - delay(durations[intros + repeats - 1] / MICROS_IN_ONE_MILLI); - } - } -} - -/** - * Parse the string given as Pronto Hex, and send it a number of times given - * as the second argument. Thereby the division of the Pronto Hex into - * an intro-sequence and a repeat sequence is taken into account: - * First the intro sequence is sent, then the repeat sequence is sent times-1 times. - * However, if the intro sequence is empty, the repeat sequence is sent times times. - * <a href="http://www.harctoolbox.org/Glossary.html#ProntoSemantics">Reference</a>. - * - * Note: Using this function is very wasteful for the memory consumption on - * a small board. - * Normally it is a much better idea to use a tool like e.g. IrScrutinizer - * to transform Pronto type signals offline - * to a more memory efficient format. - * - * @param str C type string (null terminated) containing a Pronto Hex representation. - * @param aNumberOfRepeats Number of times to send the signal. - */ -void IRsend::sendPronto(const char *str, int_fast8_t aNumberOfRepeats) { - size_t len = strlen(str) / (digitsInProntoNumber + 1) + 1; - uint16_t data[len]; - const char *p = str; - char *endptr[1]; - for (uint16_t i = 0; i < len; i++) { - long x = strtol(p, endptr, 16); - if (x == 0 && i >= numbersInPreamble) { - // Alignment error?, bail immediately (often right result). - len = i; - break; - } - data[i] = static_cast<uint16_t>(x); // If input is conforming, there can be no overflow! - p = *endptr; - } - sendPronto(data, len, aNumberOfRepeats); -} - -#if defined(__AVR__) -/** - * Version of sendPronto that reads from PROGMEM, saving RAM memory. - * @param str pronto C type string (null terminated) containing a Pronto Hex representation. - * @param aNumberOfRepeats Number of times to send the signal. - */ -//far pointer (? for ATMega2560 etc.) -void IRsend::sendPronto_PF(uint_farptr_t str, int_fast8_t aNumberOfRepeats) { - size_t len = strlen_PF(str); - char work[len + 1]; - strncpy_PF(work, str, len); - sendPronto(work, aNumberOfRepeats); -} - -//standard pointer -void IRsend::sendPronto_P(const char *str, int_fast8_t aNumberOfRepeats) { - size_t len = strlen_P(str); - char work[len + 1]; - strncpy_P(work, str, len); - sendPronto(work, aNumberOfRepeats); -} -#endif - -void IRsend::sendPronto(const __FlashStringHelper *str, int_fast8_t aNumberOfRepeats) { - size_t len = strlen_P(reinterpret_cast<const char*>(str)); - char work[len + 1]; - strncpy_P(work, reinterpret_cast<const char*>(str), len); - return sendPronto(work, aNumberOfRepeats); -} - -static uint16_t effectiveFrequency(uint16_t frequency) { - return frequency > 0 ? frequency : fallbackFrequency; -} - -static uint16_t toTimebase(uint16_t frequency) { - return microsecondsInSeconds / effectiveFrequency(frequency); -} - -static uint16_t toFrequencyCode(uint16_t frequency) { - return referenceFrequency / effectiveFrequency(frequency); -} - -static char hexDigit(uint16_t x) { - return (char) (x <= 9 ? ('0' + x) : ('A' + (x - 10))); -} - -static void dumpDigit(Print *aSerial, uint16_t number) { - aSerial->print(hexDigit(number)); -} - -static void dumpNumber(Print *aSerial, uint16_t number) { - for (uint16_t i = 0; i < digitsInProntoNumber; i++) { - uint16_t shifts = bitsInHexadecimal * (digitsInProntoNumber - 1 - i); - dumpDigit(aSerial, (number >> shifts) & hexMask); - } - aSerial->print(' '); -} - -static void dumpDuration(Print *aSerial, uint32_t duration, uint16_t timebase) { - dumpNumber(aSerial, (duration + timebase / 2) / timebase); -} - -/* - * Compensate received values by MARK_EXCESS_MICROS, like it is done for decoding! - */ -static void compensateAndDumpSequence(Print *aSerial, const volatile uint16_t *data, size_t length, uint16_t timebase) { - for (size_t i = 0; i < length; i++) { - uint32_t tDuration = data[i] * MICROS_PER_TICK; - if (i & 1) { - // Mark - tDuration -= getMarkExcessMicros(); - } else { - tDuration += getMarkExcessMicros(); - } - dumpDuration(aSerial, tDuration, timebase); - } - - // append a gap - dumpDuration(aSerial, PRONTO_DEFAULT_GAP, timebase); -} - -/** - * Print the result (second argument) as Pronto Hex on the Print supplied as argument. - * Used in the ReceiveDump example. - * @param aSerial The Print object on which to write, for Arduino you can use &Serial. - * @param aFrequencyHertz Modulation frequency in Hz. Often 38000Hz. - */ -void IRrecv::compensateAndPrintIRResultAsPronto(Print *aSerial, uint16_t aFrequencyHertz) { - aSerial->println(F("Pronto Hex as string")); - aSerial->print(F("char prontoData[] = \"")); - dumpNumber(aSerial, aFrequencyHertz > 0 ? learnedToken : learnedNonModulatedToken); - dumpNumber(aSerial, toFrequencyCode(aFrequencyHertz)); - dumpNumber(aSerial, (decodedIRData.rawDataPtr->rawlen + 1) / 2); - dumpNumber(aSerial, 0); - uint16_t timebase = toTimebase(aFrequencyHertz); - compensateAndDumpSequence(aSerial, &decodedIRData.rawDataPtr->rawbuf[1], decodedIRData.rawDataPtr->rawlen - 1, timebase); // skip leading space - aSerial->println("\";"); -} - -/* - * Functions for dumping Pronto to a String. This is not very time and space efficient - * and can lead to resource problems especially on small processors like AVR's - */ - -static bool dumpDigit(String *aString, uint16_t number) { - aString->concat(hexDigit(number)); - return number; -} - -static size_t dumpNumber(String *aString, uint16_t number) { - - size_t size = 0; - - for (uint16_t i = 0; i < digitsInProntoNumber; i++) { - uint16_t shifts = bitsInHexadecimal * (digitsInProntoNumber - 1 - i); - size += dumpDigit(aString, (number >> shifts) & hexMask); - } - aString->concat(' '); - size++; - - return size; -} - -/* - * Compensate received values by MARK_EXCESS_MICROS, like it is done for decoding! - */ -static size_t dumpDuration(String *aString, uint32_t duration, uint16_t timebase) { - return dumpNumber(aString, (duration + timebase / 2) / timebase); -} - -static size_t compensateAndDumpSequence(String *aString, const volatile uint16_t *data, size_t length, uint16_t timebase) { - - size_t size = 0; - - for (size_t i = 0; i < length; i++) { - uint32_t tDuration = data[i] * MICROS_PER_TICK; - if (i & 1) { - // Mark - tDuration -= getMarkExcessMicros(); - } else { - tDuration += getMarkExcessMicros(); - } - size += dumpDuration(aString, tDuration, timebase); - } - - // append minimum gap - size += dumpDuration(aString, PRONTO_DEFAULT_GAP, timebase); - - return size; -} - -/* - * Writes Pronto HEX to a String object. - * Returns the amount of characters added to the string.(360 characters for a NEC code!) - */ -size_t IRrecv::compensateAndStorePronto(String *aString, uint16_t frequency) { - - size_t size = 0; - uint16_t timebase = toTimebase(frequency); - - size += dumpNumber(aString, frequency > 0 ? learnedToken : learnedNonModulatedToken); - size += dumpNumber(aString, toFrequencyCode(frequency)); - size += dumpNumber(aString, (decodedIRData.rawDataPtr->rawlen + 1) / 2); - size += dumpNumber(aString, 0); - size += compensateAndDumpSequence(aString, &decodedIRData.rawDataPtr->rawbuf[1], decodedIRData.rawDataPtr->rawlen - 1, - timebase); // skip leading space - - return size; -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_PRONTO_HPP diff --git a/IRremote/src/ir_RC5_RC6.hpp b/IRremote/src/ir_RC5_RC6.hpp deleted file mode 100644 index 594bb079a113a22bd3cfa4d379dd57698ed47a68..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_RC5_RC6.hpp +++ /dev/null @@ -1,613 +0,0 @@ -/* - * ir_RC5_RC6.hpp - * - * Contains functions for receiving and sending RC5, RC5X, RC6 protocols - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_RC5_RC6_HPP -#define _IR_RC5_RC6_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -uint8_t sLastSendToggleValue = 1; // To start first command with toggle 0 -//uint8_t sLastReceiveToggleValue = 3; // 3 -> start value - -//============================================================================== -// RRRR CCCC 55555 -// R R C 5 -// RRRR C 5555 -// R R C 5 -// R R CCCC 5555 -//============================================================================== -/* - Protocol=RC5 Address=0x11 Command=0x36 Raw-Data=0x1476 13 bits MSB first - + 900,- 900 - +1800,-1750 +1800,- 850 + 900,- 850 + 900,-1750 - + 950,- 850 + 900,- 850 +1800,-1750 + 950,- 850 - +1800 - Sum: 23100 - - RC5X with 7.th MSB of command set - Protocol=RC5 Address=0x11 Command=0x76 Toggle=1 Raw-Data=0xC76 13 bits MSB first - +1800,-1750 - + 850,- 900 +1800,- 850 + 950,- 850 + 900,-1750 - + 900,- 850 + 950,- 850 +1800,-1750 + 900,- 850 - +1800 - Sum: 23050 - */ -// -// see: https://www.sbprojects.net/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/Manchester_code -// https://forum.arduino.cc/t/sending-rc-5-extended-code-using-irsender/1045841/10 - Protocol Maranz Extended -// mark->space => 0 -// space->mark => 1 -// MSB first 1 start bit, 1 field bit, 1 toggle bit + 5 bit address + 6 bit command, no stop bit -// Field bit is 1 for RC5 and inverted 7. command bit for RC5X. That way the first 64 commands of RC5X remain compatible with the original RC5. -// SF TAAA AACC CCCC -// IR duty factor is 25%, -// -#define RC5_ADDRESS_BITS 5 -#define RC5_COMMAND_BITS 6 -#define RC5_COMMAND_FIELD_BIT 1 -#define RC5_TOGGLE_BIT 1 - -#define RC5_BITS (RC5_COMMAND_FIELD_BIT + RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS) // 13 - -#define RC5_UNIT 889 // 32 periods of 36 kHz (888.8888) - -#define MIN_RC5_MARKS ((RC5_BITS + 1) / 2) // 7. Divided by 2 to handle the bit sequence of 01010101 which gives one mark and space for each 2 bits - -#define RC5_DURATION (15L * RC5_UNIT) // 13335 -#define RC5_REPEAT_PERIOD (128L * RC5_UNIT) // 113792 -#define RC5_REPEAT_DISTANCE (RC5_REPEAT_PERIOD - RC5_DURATION) // 100 ms -#define RC5_MAXIMUM_REPEAT_DISTANCE (RC5_REPEAT_DISTANCE + (RC5_REPEAT_DISTANCE / 4)) // Just a guess - -/************************************ - * Start of send and decode functions - ************************************/ - -/** - * @param aCommand If aCommand is >=0x40 then we switch automatically to RC5X. - * @param aEnableAutomaticToggle Send toggle bit according to the state of the static sLastSendToggleValue variable. - */ -void IRsend::sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle) { - // Set IR carrier frequency - enableIROut (RC5_RC6_KHZ); - - uint16_t tIRData = ((aAddress & 0x1F) << RC5_COMMAND_BITS); - - if (aCommand < 0x40) { - // Auto discovery of RC5X, set field bit to 1 - tIRData |= 1 << (RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS); - } else { - // Mask bit 7 of command and let field bit 0 - aCommand &= 0x3F; - } - tIRData |= aCommand; - - if (aEnableAutomaticToggle) { - if (sLastSendToggleValue == 0) { - sLastSendToggleValue = 1; - // set toggled bit - tIRData |= 1 << (RC5_ADDRESS_BITS + RC5_COMMAND_BITS); - } else { - sLastSendToggleValue = 0; - } - } - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - - // start bit is sent by sendBiphaseData - sendBiphaseData(RC5_UNIT, tIRData, RC5_BITS); - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - // send repeated command in a fixed raster - delay(RC5_REPEAT_DISTANCE / MICROS_IN_ONE_MILLI); - } - } -} - -/** - * Try to decode data as RC5 protocol - * _ _ _ _ _ _ _ _ _ _ _ _ _ - * Clock _____| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| | - * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ End of each data bit period - * _ _ - Mark - * 2 Start bits for RC5 _____| |_| ... - Data starts with a space->mark bit - * - Space - * _ - * 1 Start bit for RC5X _____| ... - * - */ -bool IRrecv::decodeRC5() { - uint8_t tBitIndex; - uint32_t tDecodedRawData = 0; - - // Set Biphase decoding start values - initBiphaselevel(1, RC5_UNIT); // Skip gap space - - // Check we have the right amount of data (11 to 26). The +2 is for initial gap and start bit mark. - if (decodedIRData.rawDataPtr->rawlen < ((RC5_BITS + 1) / 2) + 2 && (RC5_BITS + 2) < decodedIRData.rawDataPtr->rawlen) { - // no debug output, since this check is mainly to determine the received protocol - IR_DEBUG_PRINT(F("RC5: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not between 9 and 15")); - return false; - } - -// Check start bit, the first space is included in the gap - if (getBiphaselevel() != MARK) { - IR_DEBUG_PRINT(F("RC5: ")); - IR_DEBUG_PRINTLN(F("first getBiphaselevel() is not MARK")); - return false; - } - - /* - * Get data bits - MSB first - */ - for (tBitIndex = 0; sBiphaseDecodeRawbuffOffset < decodedIRData.rawDataPtr->rawlen; tBitIndex++) { - // get next 2 levels and check for transition - uint8_t tStartLevel = getBiphaselevel(); - uint8_t tEndLevel = getBiphaselevel(); - - if ((tStartLevel == SPACE) && (tEndLevel == MARK)) { - // we have a space to mark transition here - tDecodedRawData = (tDecodedRawData << 1) | 1; - } else if ((tStartLevel == MARK) && (tEndLevel == SPACE)) { - // we have a mark to space transition here - tDecodedRawData = (tDecodedRawData << 1) | 0; - } else { -#if defined(LOCAL_DEBUG) - Serial.print(F("RC5: ")); - Serial.println(F("no transition found, decode failed")); -#endif - return false; - } - } - - // Success - decodedIRData.numberOfBits = tBitIndex; // must be RC5_BITS - - LongUnion tValue; - tValue.ULong = tDecodedRawData; - decodedIRData.decodedRawData = tDecodedRawData; - decodedIRData.command = tValue.UByte.LowByte & 0x3F; - decodedIRData.address = (tValue.UWord.LowWord >> RC5_COMMAND_BITS) & 0x1F; - - // Get the inverted 7. command bit for RC5X, the inverted value is always 1 for RC5 and serves as a second start bit. - if ((tValue.UWord.LowWord & (1 << (RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS))) == 0) { - decodedIRData.command += 0x40; - } - - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; - if (tValue.UByte.MidLowByte & 0x8) { - decodedIRData.flags = IRDATA_FLAGS_TOGGLE_BIT | IRDATA_FLAGS_IS_MSB_FIRST; - } - decodedIRData.protocol = RC5; - - // check for repeat - checkForRepeatSpaceTicksAndSetFlag(RC5_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK); - - return true; -} - -//+============================================================================= -// RRRR CCCC 6666 -// R R C 6 -// RRRR C 6666 -// R R C 6 6 -// R R CCCC 666 -//+============================================================================= -// -/* - Protocol=RC6 Address=0xF1 Command=0x76 Raw-Data=0xF176 20 bits MSB first - +2650,- 850 - + 500,- 850 + 500,- 400 + 450,- 450 + 450,- 850 - +1400,- 400 + 450,- 450 + 450,- 450 + 450,- 900 - + 450,- 450 + 450,- 400 + 950,- 850 + 900,- 450 - + 450,- 450 + 450,- 850 + 950,- 400 + 450,- 900 - + 450 - Sum: 23150 - */ -// Frame RC6: 1 start bit + 1 Bit "1" + 3 mode bits (000) + 1 toggle bit + 8 address + 8 command bits + 2666us pause -// Frame RC6A: 1 start bit + 1 Bit "1" + 3 mode bits (110) + 1 toggle bit + "1" + 14 customer bits + 8 system bits + 8 command bits (=31bits) + 2666us pause -// !!! toggle bit has another timing :-( !!! -// mark->space => 1 -// space->mark => 0 -// https://www.sbprojects.net/knowledge/ir/rc6.php -// https://www.mikrocontroller.net/articles/IRMP_-_english#RC6_.2B_RC6A -// https://en.wikipedia.org/wiki/Manchester_code -#define MIN_RC6_SAMPLES 1 - -#define RC6_RPT_LENGTH 46000 - -#define RC6_LEADING_BIT 1 -#define RC6_MODE_BITS 3 // never seen others than all 0 for Philips TV -#define RC6_TOGGLE_BIT 1 // toggles at every key press. Can be used to distinguish repeats from 2 key presses and has another timing :-(. -#define RC6_TOGGLE_BIT_INDEX RC6_MODE_BITS // fourth position, index = 3 -#define RC6_ADDRESS_BITS 8 -#define RC6_COMMAND_BITS 8 - -#define RC6_BITS (RC6_LEADING_BIT + RC6_MODE_BITS + RC6_TOGGLE_BIT + RC6_ADDRESS_BITS + RC6_COMMAND_BITS) // 21 - -#define RC6_UNIT 444 // 16 periods of 36 kHz (444.4444) - -#define RC6_HEADER_MARK (6 * RC6_UNIT) // 2666 -#define RC6_HEADER_SPACE (2 * RC6_UNIT) // 889 - -#define RC6_TRAILING_SPACE (6 * RC6_UNIT) // 2666 -#define MIN_RC6_MARKS 4 + ((RC6_ADDRESS_BITS + RC6_COMMAND_BITS) / 2) // 12, 4 are for preamble - -#define RC6_REPEAT_DISTANCE 107000 // just a guess but > 2.666ms -#define RC6_MAXIMUM_REPEAT_DISTANCE (RC6_REPEAT_DISTANCE + (RC6_REPEAT_DISTANCE / 4)) // Just a guess - -/** - * Main RC6 send function - */ -void IRsend::sendRC6(uint32_t aRawData, uint8_t aNumberOfBitsToSend) { - sendRC6Raw(aRawData, aNumberOfBitsToSend); -} -void IRsend::sendRC6Raw(uint32_t aRawData, uint8_t aNumberOfBitsToSend) { -// Set IR carrier frequency - enableIROut (RC5_RC6_KHZ); - -// Header - mark(RC6_HEADER_MARK); - space(RC6_HEADER_SPACE); - -// Start bit - mark(RC6_UNIT); - space(RC6_UNIT); - -// Data MSB first - uint32_t mask = 1UL << (aNumberOfBitsToSend - 1); - for (uint_fast8_t i = 1; mask; i++, mask >>= 1) { - // The fourth bit we send is the "double width toggle bit" - unsigned int t = (i == (RC6_TOGGLE_BIT_INDEX + 1)) ? (RC6_UNIT * 2) : (RC6_UNIT); - if (aRawData & mask) { - mark(t); - space(t); - } else { - space(t); - mark(t); - } - } -} - -/** - * Send RC6 64 bit raw data - * Can be used to send RC6A with ?31? data bits - */ -void IRsend::sendRC6(uint64_t aRawData, uint8_t aNumberOfBitsToSend) { - sendRC6Raw(aRawData, aNumberOfBitsToSend); -} -void IRsend::sendRC6Raw(uint64_t aRawData, uint8_t aNumberOfBitsToSend) { -// Set IR carrier frequency - enableIROut (RC5_RC6_KHZ); - -// Header - mark(RC6_HEADER_MARK); - space(RC6_HEADER_SPACE); - -// Start bit - mark(RC6_UNIT); - space(RC6_UNIT); - -// Data MSB first - uint64_t mask = 1ULL << (aNumberOfBitsToSend - 1); - for (uint_fast8_t i = 1; mask; i++, mask >>= 1) { - // The fourth bit we send is the "double width toggle bit" - unsigned int t = (i == (RC6_TOGGLE_BIT_INDEX + 1)) ? (RC6_UNIT * 2) : (RC6_UNIT); - if (aRawData & mask) { - mark(t); - space(t); - } else { - space(t); - mark(t); - } - } -} - -/** - * Assemble raw data for RC6 from parameters and toggle state and send - * We do not wait for the minimal trailing space of 2666 us - * @param aEnableAutomaticToggle Send toggle bit according to the state of the static sLastSendToggleValue variable. - */ -void IRsend::sendRC6(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle) { - - LongUnion tIRRawData; - tIRRawData.UByte.LowByte = aCommand; - tIRRawData.UByte.MidLowByte = aAddress; - - tIRRawData.UWord.HighWord = 0; // must clear high word - if (aEnableAutomaticToggle) { - if (sLastSendToggleValue == 0) { - sLastSendToggleValue = 1; - // set toggled bit - IR_DEBUG_PRINT(F("Set Toggle ")); - tIRRawData.UByte.MidHighByte = 1; // 3 Mode bits are 0 - } else { - sLastSendToggleValue = 0; - } - } - -#if defined(LOCAL_DEBUG) - Serial.print(F("RC6: ")); - Serial.print(F("sLastSendToggleValue=")); - Serial.print (sLastSendToggleValue); - Serial.print(F(" RawData=")); - Serial.println(tIRRawData.ULong, HEX); -#endif - - uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1; - while (tNumberOfCommands > 0) { - - // start and leading bits are sent by sendRC6 - sendRC6Raw(tIRRawData.ULong, RC6_BITS - 1); // -1 since the leading bit is additionally sent by sendRC6 - - tNumberOfCommands--; - // skip last delay! - if (tNumberOfCommands > 0) { - // send repeated command in a fixed raster - delay(RC6_REPEAT_DISTANCE / MICROS_IN_ONE_MILLI); - } - } -} - -/** - * Try to decode data as RC6 protocol - */ -bool IRrecv::decodeRC6() { - uint8_t tBitIndex; - uint32_t tDecodedRawData = 0; - - // Check we have the right amount of data (). The +3 for initial gap, start bit mark and space - if (decodedIRData.rawDataPtr->rawlen < MIN_RC6_MARKS + 3 && (RC6_BITS + 3) < decodedIRData.rawDataPtr->rawlen) { - IR_DEBUG_PRINT(F("RC6: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not between 15 and 25")); - return false; - } - - // Check header "mark" and "space", this must be done for repeat and data - if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], RC6_HEADER_MARK) - || !matchSpace(decodedIRData.rawDataPtr->rawbuf[2], RC6_HEADER_SPACE)) { - // no debug output, since this check is mainly to determine the received protocol - IR_DEBUG_PRINT(F("RC6: ")); - IR_DEBUG_PRINTLN(F("Header mark or space length is wrong")); - return false; - } - - // Set Biphase decoding start values - initBiphaselevel(3, RC6_UNIT); // Skip gap-space and start-bit mark + space - -// Process first bit, which is known to be a 1 (mark->space) - if (getBiphaselevel() != MARK) { - IR_DEBUG_PRINT(F("RC6: ")); - IR_DEBUG_PRINTLN(F("first getBiphaselevel() is not MARK")); - return false; - } - if (getBiphaselevel() != SPACE) { - IR_DEBUG_PRINT(F("RC6: ")); - IR_DEBUG_PRINTLN(F("second getBiphaselevel() is not SPACE")); - return false; - } - - for (tBitIndex = 0; sBiphaseDecodeRawbuffOffset < decodedIRData.rawDataPtr->rawlen; tBitIndex++) { - uint8_t tStartLevel; // start level of coded bit - uint8_t tEndLevel; // end level of coded bit - - tStartLevel = getBiphaselevel(); - if (tBitIndex == RC6_TOGGLE_BIT_INDEX) { - // Toggle bit is double wide; make sure second half is equal first half - if (tStartLevel != getBiphaselevel()) { -#if defined(LOCAL_DEBUG) - Serial.print(F("RC6: ")); - Serial.println(F("Toggle mark or space length is wrong")); -#endif - return false; - } - } - - tEndLevel = getBiphaselevel(); - if (tBitIndex == RC6_TOGGLE_BIT_INDEX) { - // Toggle bit is double wide; make sure second half matches - if (tEndLevel != getBiphaselevel()) { -#if defined(LOCAL_DEBUG) - Serial.print(F("RC6: ")); - Serial.println(F("Toggle mark or space length is wrong")); -#endif - return false; - } - } - - /* - * Determine tDecodedRawData bit value by checking the transition type - */ - if ((tStartLevel == MARK) && (tEndLevel == SPACE)) { - // we have a mark to space transition here - tDecodedRawData = (tDecodedRawData << 1) | 1; // inverted compared to RC5 - } else if ((tStartLevel == SPACE) && (tEndLevel == MARK)) { - // we have a space to mark transition here - tDecodedRawData = (tDecodedRawData << 1) | 0; - } else { -#if defined(LOCAL_DEBUG) - Serial.print(F("RC6: ")); - Serial.println(F("Decode failed")); -#endif - // we have no transition here or one level is -1 -> error - return false; // Error - } - } - -// Success - decodedIRData.numberOfBits = tBitIndex; - - LongUnion tValue; - tValue.ULong = tDecodedRawData; - decodedIRData.decodedRawData = tDecodedRawData; - - if (tBitIndex < 36) { - // RC6 8 address bits, 8 command bits - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; - decodedIRData.command = tValue.UByte.LowByte; - decodedIRData.address = tValue.UByte.MidLowByte; - // Check for toggle flag - if ((tValue.UByte.MidHighByte & 1) != 0) { - decodedIRData.flags = IRDATA_FLAGS_TOGGLE_BIT | IRDATA_FLAGS_IS_MSB_FIRST; - } - if (tBitIndex > 20) { - decodedIRData.flags |= IRDATA_FLAGS_EXTRA_INFO; - } - } else { - // RC6A - 32 bits - decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; - if ((tValue.UByte.MidLowByte & 0x80) != 0) { - decodedIRData.flags = IRDATA_FLAGS_TOGGLE_BIT | IRDATA_FLAGS_IS_MSB_FIRST; - } - tValue.UByte.MidLowByte &= 0x87F; // mask toggle bit - decodedIRData.command = tValue.UByte.LowByte; - decodedIRData.address = tValue.UByte.MidLowByte; - } - - // check for repeat, do not check toggle bit yet - checkForRepeatSpaceTicksAndSetFlag(RC6_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK); - - decodedIRData.protocol = RC6; - return true; -} - -/********************************************************************************* - * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials - *********************************************************************************/ - -/** - * Old version with 32 bit data - */ -void IRsend::sendRC5(uint32_t data, uint8_t nbits) { - // Set IR carrier frequency - enableIROut (RC5_RC6_KHZ); - - // Start - mark(RC5_UNIT); - space(RC5_UNIT); - mark(RC5_UNIT); - - // Data - Biphase code MSB first - for (uint32_t mask = 1UL << (nbits - 1); mask; mask >>= 1) { - if (data & mask) { - space(RC5_UNIT); // 1 is space, then mark - mark(RC5_UNIT); - } else { - mark(RC5_UNIT); - space(RC5_UNIT); - } - } -} - -/* - * Not longer required, use sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle) instead - */ -void IRsend::sendRC5ext(uint8_t addr, uint8_t cmd, bool toggle) { -// Set IR carrier frequency - enableIROut (RC5_RC6_KHZ); - - uint8_t addressBits = 5; - uint8_t commandBits = 7; -// unsigned long nbits = addressBits + commandBits; - -// Start - mark(RC5_UNIT); - -// Bit #6 of the command part, but inverted! - uint8_t cmdBit6 = (1UL << (commandBits - 1)) & cmd; - if (cmdBit6) { - // Inverted (1 -> 0 = mark-to-space) - mark(RC5_UNIT); - space(RC5_UNIT); - } else { - space(RC5_UNIT); - mark(RC5_UNIT); - } - commandBits--; - -// Toggle bit - static int toggleBit = 1; - if (toggle) { - if (toggleBit == 0) { - toggleBit = 1; - } else { - toggleBit = 0; - } - } - if (toggleBit) { - space(RC5_UNIT); - mark(RC5_UNIT); - } else { - mark(RC5_UNIT); - space(RC5_UNIT); - } - -// Address - for (uint_fast8_t mask = 1UL << (addressBits - 1); mask; mask >>= 1) { - if (addr & mask) { - space(RC5_UNIT); // 1 is space, then mark - mark(RC5_UNIT); - } else { - mark(RC5_UNIT); - space(RC5_UNIT); - } - } - -// Command - for (uint_fast8_t mask = 1UL << (commandBits - 1); mask; mask >>= 1) { - if (cmd & mask) { - space(RC5_UNIT); // 1 is space, then mark - mark(RC5_UNIT); - } else { - mark(RC5_UNIT); - space(RC5_UNIT); - } - } -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_RC5_RC6_HPP diff --git a/IRremote/src/ir_Samsung.hpp b/IRremote/src/ir_Samsung.hpp deleted file mode 100644 index c615906337a08e4de7c082e2d6a3c3e514f63f5c..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_Samsung.hpp +++ /dev/null @@ -1,368 +0,0 @@ -/* - * ir_Samsung.hpp - * - * Contains functions for receiving and sending Samsung IR Protocol in "raw" and standard format with 16 bit address and 16 or 32 bit command - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2017-2023 Darryl Smith, Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONSAMSUNGTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_SAMSUNG_HPP -#define _IR_SAMSUNG_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// SSSS AAA MMM SSSS U U N N GGGG -// S A A M M M S U U NN N G -// SSS AAAAA M M M SSS U U N N N G GG -// S A A M M S U U N NN G G -// SSSS A A M M SSSS UUU N N GGG -//============================================================================== -/* - * Address=0xFFF1 Command=0x76 Raw-Data=0x8976FFF1 - +4500,-4400 - + 600,-1600 + 650,- 500 + 600,- 500 + 650,- 500 - + 600,-1650 + 600,-1600 + 650,-1600 + 600,-1650 - + 600,-1600 + 600,-1650 + 600,-1650 + 600,-1600 - + 600,-1650 + 600,-1650 + 600,-1600 + 600,-1650 - + 600,- 500 + 650,-1600 + 600,-1650 + 600,- 500 - + 650,-1600 + 600,-1650 + 600,-1650 + 600,- 500 - + 600,-1650 + 600,- 500 + 600,- 550 + 600,-1600 - + 600,- 550 + 600,- 550 + 550,- 550 + 600,-1650 - + 550 - Sum: 68750 - */ -/* - * Samsung repeat frame can be the original frame again or a special repeat frame, - * then we call the protocol SamsungLG. They differ only in the handling of repeat, - * so we can not decide for the first frame which protocol is used. - */ -// see http://www.hifi-remote.com/wiki/index.php?title=DecodeIR#Samsung -// https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG32 -// https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG48 -// LSB first, 1 start bit + 16 bit address + 16 or 32 bit data + 1 stop bit. -// Here https://forum.arduino.cc/t/klimaanlage-per-ir-steuern/1051381/10 the address (0xB24D) is also 8 bits and then 8 inverted bits -// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F:8,1,^110)+ ==> 8 bit + 8 bit inverted data - Samsung32 -// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:16,1,^110)+ ==> 16 bit data - still Samsung32 -// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F:8,G:8,~G:8,1,^110)+ ==> 2 x (8 bit + 8 bit inverted data) - Samsung48 -// -#define SAMSUNG_ADDRESS_BITS 16 -#define SAMSUNG_COMMAND16_BITS 16 -#define SAMSUNG_COMMAND32_BITS 32 -#define SAMSUNG_BITS (SAMSUNG_ADDRESS_BITS + SAMSUNG_COMMAND16_BITS) -#define SAMSUNG48_BITS (SAMSUNG_ADDRESS_BITS + SAMSUNG_COMMAND32_BITS) - -// except SAMSUNG_HEADER_MARK, values are like NEC -#define SAMSUNG_UNIT 560 // 21.28 periods of 38 kHz, 11.2 ticks TICKS_LOW = 8.358 TICKS_HIGH = 15.0 -#define SAMSUNG_HEADER_MARK (8 * SAMSUNG_UNIT) // 4500 | 180 -#define SAMSUNG_HEADER_SPACE (8 * SAMSUNG_UNIT) // 4500 -#define SAMSUNG_BIT_MARK SAMSUNG_UNIT -#define SAMSUNG_ONE_SPACE (3 * SAMSUNG_UNIT) // 1690 | 33.8 TICKS_LOW = 25.07 TICKS_HIGH = 45.0 -#define SAMSUNG_ZERO_SPACE SAMSUNG_UNIT - -#define SAMSUNG_AVERAGE_DURATION 55000 // SAMSUNG_HEADER_MARK + SAMSUNG_HEADER_SPACE + 32 * 2,5 * SAMSUNG_UNIT + SAMSUNG_UNIT // 2.5 because we assume more zeros than ones -#define SAMSUNG_REPEAT_DURATION (SAMSUNG_HEADER_MARK + SAMSUNG_HEADER_SPACE + SAMSUNG_BIT_MARK + SAMSUNG_ZERO_SPACE + SAMSUNG_BIT_MARK) -#define SAMSUNG_REPEAT_PERIOD 110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down. -#define SAMSUNG_REPEAT_DISTANCE (SAMSUNG_REPEAT_PERIOD - SAMSUNG_AVERAGE_DURATION) -#define SAMSUNG_MAXIMUM_REPEAT_DISTANCE (SAMSUNG_REPEAT_DISTANCE + (SAMSUNG_REPEAT_DISTANCE / 4)) // Just a guess - -struct PulseDistanceWidthProtocolConstants SamsungProtocolConstants = { SAMSUNG, SAMSUNG_KHZ, SAMSUNG_HEADER_MARK, -SAMSUNG_HEADER_SPACE, SAMSUNG_BIT_MARK, SAMSUNG_ONE_SPACE, SAMSUNG_BIT_MARK, SAMSUNG_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, - (SAMSUNG_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), &sendSamsungLGSpecialRepeat }; - -/************************************ - * Start of send and decode functions - ************************************/ - -/** - * Send repeat - * Repeat commands should be sent in a 110 ms raster. - * This repeat was sent by an LG 6711R1P071A remote - */ -void IRsend::sendSamsungLGRepeat() { - enableIROut (SAMSUNG_KHZ); // 38 kHz - mark(SAMSUNG_HEADER_MARK); // + 4500 - space(SAMSUNG_HEADER_SPACE); // - 4500 - mark(SAMSUNG_BIT_MARK); // + 560 - space(SAMSUNG_ZERO_SPACE); // - 560 - mark(SAMSUNG_BIT_MARK); // + 560 -} - -/** - * Static function for sending special repeat frame. - * For use in ProtocolConstants. Saves up to 250 bytes compared to a member function. - */ -void sendSamsungLGSpecialRepeat() { - IrSender.enableIROut(SAMSUNG_KHZ); // 38 kHz - IrSender.mark(SAMSUNG_HEADER_MARK); // + 4500 - IrSender.space(SAMSUNG_HEADER_SPACE); // - 4500 - IrSender.mark(SAMSUNG_BIT_MARK); // + 560 - IrSender.space(SAMSUNG_ZERO_SPACE); // - 560 - IrSender.mark(SAMSUNG_BIT_MARK); // + 560 -} - -/* - * Sent e.g. by an LG 6711R1P071A remote - * @param aNumberOfRepeats If < 0 then only a special repeat frame will be sent - */ -void IRsend::sendSamsungLG(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats) { - if (aNumberOfRepeats < 0) { - sendSamsungLGRepeat(); - return; - } - - // send 16 bit address and 8 command bits and then 8 inverted command bits LSB first - LongUnion tRawData; - tRawData.UWord.LowWord = aAddress; - tRawData.UByte.MidHighByte = aCommand; - tRawData.UByte.HighByte = ~aCommand; - - sendPulseDistanceWidth(&SamsungProtocolConstants, tRawData.ULong, SAMSUNG_BITS, aNumberOfRepeats); -} - -/** - * Here we send Samsung32 - * If we get a command < 0x100, we send command and then ~command - * !!! Be aware, that this is flexible, but makes it impossible to send e.g. 0x0042 as 16 bit value!!! - * @param aNumberOfRepeats If < 0 then only a special repeat frame will be sent - */ -void IRsend::sendSamsung(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats) { - - // send 16 bit address - LongUnion tSendValue; - tSendValue.UWords[0] = aAddress; - if (aCommand < 0x100) { - // Send 8 command bits and then 8 inverted command bits LSB first - tSendValue.UBytes[2] = aCommand; - tSendValue.UBytes[3] = ~aCommand; - } else { - // Send 16 command bits - tSendValue.UWords[1] = aCommand; - } - - sendPulseDistanceWidth(&SamsungProtocolConstants, tSendValue.ULong, SAMSUNG_BITS, aNumberOfRepeats); -} - -/** - * Here we send Samsung48 - * We send 2 x (8 bit command and then ~command) - */ -void IRsend::sendSamsung48(uint16_t aAddress, uint32_t aCommand, int_fast8_t aNumberOfRepeats) { - - // send 16 bit address and 2 x ( 8 command bits and then 8 inverted command bits) LSB first -#if __INT_WIDTH__ < 32 - uint32_t tRawSamsungData[2]; // prepare 2 long for Samsung48 - - LongUnion tSendValue; - tSendValue.UWords[0] = aAddress; - tSendValue.UBytes[2] = aCommand; - tSendValue.UBytes[3] = ~aCommand; - uint8_t tUpper8BitsOfCommand = aCommand >> 8; - tRawSamsungData[1] = tUpper8BitsOfCommand | (~tUpper8BitsOfCommand) << 8; - tRawSamsungData[0] = tSendValue.ULong; - - sendPulseDistanceWidthFromArray(&SamsungProtocolConstants, &tRawSamsungData[0], SAMSUNG48_BITS, aNumberOfRepeats); -#else - LongLongUnion tSendValue; - tSendValue.UWords[0] = aAddress; - if (aCommand < 0x10000) { - tSendValue.UBytes[2] = aCommand; - tSendValue.UBytes[3] = ~aCommand; - uint8_t tUpper8BitsOfCommand = aCommand >> 8; - tSendValue.UBytes[4] = tUpper8BitsOfCommand; - tSendValue.UBytes[5] = ~tUpper8BitsOfCommand; - } else { - tSendValue.ULongLong = aAddress | aCommand << 16; - } - sendPulseDistanceWidth(&SamsungProtocolConstants, tSendValue.ULongLong, SAMSUNG48_BITS, aNumberOfRepeats); -#endif -} - -bool IRrecv::decodeSamsung() { - - // Check we have enough data (68). The +4 is for initial gap, start bit mark and space + stop bit mark - if (decodedIRData.rawDataPtr->rawlen != ((2 * SAMSUNG_BITS) + 4) - && decodedIRData.rawDataPtr->rawlen != ((2 * SAMSUNG48_BITS) + 4) && (decodedIRData.rawDataPtr->rawlen != 6)) { - IR_DEBUG_PRINT(F("Samsung: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 6 or 68 or 100")); - return false; - } - - if (!checkHeader(&SamsungProtocolConstants)) { - return false; - } - - // Check for SansungLG style repeat - if (decodedIRData.rawDataPtr->rawlen == 6) { - decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST; - decodedIRData.address = lastDecodedAddress; - decodedIRData.command = lastDecodedCommand; - decodedIRData.protocol = SAMSUNG_LG; - return true; - } - - /* - * Decode first 32 bits - */ - if (!decodePulseDistanceWidthData(&SamsungProtocolConstants, SAMSUNG_BITS, 3)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Samsung: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - LongUnion tValue; - tValue.ULong = decodedIRData.decodedRawData; - decodedIRData.address = tValue.UWord.LowWord; - - if (decodedIRData.rawDataPtr->rawlen == (2 * SAMSUNG48_BITS) + 4) { - /* - * Samsung48 - */ - // decode additional 16 bit - if (!decodePulseDistanceWidthData(&SamsungProtocolConstants, (SAMSUNG_COMMAND32_BITS - SAMSUNG_COMMAND16_BITS), - 3 + (2 * SAMSUNG_BITS))) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Samsung: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - - /* - * LSB data is already in tValue.UWord.HighWord! - * Put latest (MSB) bits in LowWord, LSB first would have them expect in HighWord so keep this in mind for decoding below - */ - tValue.UWord.LowWord = decodedIRData.decodedRawData; // We have only 16 bit in decodedRawData here -#if __INT_WIDTH__ >= 32 - // workaround until complete refactoring for 64 bit - decodedIRData.decodedRawData = (decodedIRData.decodedRawData << 32)| tValue.UWord.HighWord << 16 | decodedIRData.address; // store all 48 bits in decodedRawData -#endif - - /* - * Check parity of 32 bit command - */ - // receive 2 * (8 bits then 8 inverted bits) LSB first - if (tValue.UByte.MidHighByte != (uint8_t)(~tValue.UByte.HighByte) - && tValue.UByte.LowByte != (uint8_t)(~tValue.UByte.MidLowByte)) { - decodedIRData.flags = IRDATA_FLAGS_PARITY_FAILED | IRDATA_FLAGS_IS_LSB_FIRST; - } - - decodedIRData.command = tValue.UByte.LowByte << 8 | tValue.UByte.MidHighByte; // low and high word are swapped here, so fetch it this way - decodedIRData.numberOfBits = SAMSUNG48_BITS; - decodedIRData.protocol = SAMSUNG48; - - } else { - /* - * Samsung32 - */ - if (tValue.UByte.MidHighByte == (uint8_t)(~tValue.UByte.HighByte)) { - // 8 bit command protocol - decodedIRData.command = tValue.UByte.MidHighByte; // first 8 bit - } else { - // 16 bit command protocol - decodedIRData.command = tValue.UWord.HighWord; // first 16 bit - } - decodedIRData.numberOfBits = SAMSUNG_BITS; - decodedIRData.protocol = SAMSUNG; - } - - // check for repeat - checkForRepeatSpaceTicksAndSetFlag(SAMSUNG_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK); - - return true; -} - -// Old version with MSB first -bool IRrecv::decodeSAMSUNG(decode_results *aResults) { - unsigned int offset = 1; // Skip first space - - // Initial mark - if (!matchMark(aResults->rawbuf[offset], SAMSUNG_HEADER_MARK)) { - return false; - } - offset++; - - // Check for repeat -- like a NEC repeat - if ((aResults->rawlen == 4) && matchSpace(aResults->rawbuf[offset], 2250) - && matchMark(aResults->rawbuf[offset + 1], SAMSUNG_BIT_MARK)) { - aResults->bits = 0; - aResults->value = 0xFFFFFFFF; - decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT; - decodedIRData.protocol = SAMSUNG; - return true; - } - if (aResults->rawlen < (2 * SAMSUNG_BITS) + 4) { - return false; - } - - // Initial space - if (!matchSpace(aResults->rawbuf[offset], SAMSUNG_HEADER_SPACE)) { - return false; - } - offset++; - - if (!decodePulseDistanceWidthData(SAMSUNG_BITS, offset, SAMSUNG_BIT_MARK, 0, SAMSUNG_ONE_SPACE, SAMSUNG_ZERO_SPACE, - PROTOCOL_IS_MSB_FIRST)) { - return false; - } - - // Success - aResults->value = decodedIRData.decodedRawData; - aResults->bits = SAMSUNG_BITS; - aResults->decode_type = SAMSUNG; - decodedIRData.protocol = SAMSUNG; - return true; -} - -// Old version with MSB first -void IRsend::sendSAMSUNG(unsigned long data, int nbits) { - // Set IR carrier frequency - enableIROut (SAMSUNG_KHZ); - - // Header - mark(SAMSUNG_HEADER_MARK); - space(SAMSUNG_HEADER_SPACE); - - // Old version with MSB first Data + stop bit - sendPulseDistanceWidthData(SAMSUNG_BIT_MARK, SAMSUNG_ONE_SPACE, SAMSUNG_BIT_MARK, SAMSUNG_ZERO_SPACE, data, nbits, - PROTOCOL_IS_MSB_FIRST); -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_SAMSUNG_HPP diff --git a/IRremote/src/ir_Sony.hpp b/IRremote/src/ir_Sony.hpp deleted file mode 100644 index 591d58dcc5607d44b0b10023cc2d886b0a52622a..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_Sony.hpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * ir_Sony.hpp - * - * Contains functions for receiving and sending SIRCS/Sony IR Protocol in "raw" and standard format with 5 bit address 7 bit command - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_SONY_HPP -#define _IR_SONY_HPP - -#if defined(DEBUG) && !defined(LOCAL_DEBUG) -#define LOCAL_DEBUG -#else -//#define LOCAL_DEBUG // This enables debug output only for this file -#endif - -/** \addtogroup Decoder Decoders and encoders for different protocols - * @{ - */ -//============================================================================== -// SSSS OOO N N Y Y -// S O O NN N Y Y -// SSS O O N N N Y -// S O O N NN Y -// SSSS OOO N N Y -//============================================================================== -/* - * Protocol=Sony Address=0x4B9 Command=0x7 Raw-Data=0x25C87 20 bits LSB first - +2550,- 400 - // 7 command bits - +1300,- 450 +1350,- 450 +1300,- 450 + 700,- 450 - + 700,- 450 + 750,- 450 + 700,- 400 - // (5,8,) 13 address bits - +1300,- 500 - + 700,- 450 + 700,- 450 +1300,- 500 +1300,- 450 - +1300,- 450 + 700,- 450 +1350,- 400 + 750,- 450 - + 700,- 450 +1300,- 450 + 700,- 450 + 700 - Sum: 31100 - */ -/* - * Sony is the only protocol using the pulse width encoding, which requires no stop bit - */ -// see https://www.sbprojects.net/knowledge/ir/sirc.php -// https://www.mikrocontroller.net/articles/IRMP_-_english#SIRCS -// Frames are repeated every 45ms (measured from start to start) for as long as the key on the remote control is held down. -// This leads to a 15 ms gap for a Sony20 protocol! -// Here http://picprojects.org.uk/projects/sirc/ it is claimed, that many Sony remotes send each frame a minimum of 3 times. But 1 repeat (2 sends) has also been seen in real life. -// LSB first, start bit + 7 command + 5 to 13 address, no stop bit -// IRP: Sony12 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,^45m)+ ==> 40 kHz, Unit is 600, LSB, One mark is 2 units, Start bit is 4 units, 7 bit Function, 5 bit Device, no Stop bit, every 45 milliseconds -// IRP: Sony15 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:8,^45m)+ ==> 8 bit Device -// IRP: Sony20 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,S:8,^45m)+ ==> 5 bit Device, 8 bit Subdevice -// -#define SONY_ADDRESS_BITS 5 -#define SONY_COMMAND_BITS 7 -#define SONY_EXTRA_BITS 8 -#define SONY_BITS_MIN (SONY_COMMAND_BITS + SONY_ADDRESS_BITS) // 12 bits -#define SONY_BITS_15 (SONY_COMMAND_BITS + SONY_ADDRESS_BITS + 3) // 15 bits -#define SONY_BITS_MAX (SONY_COMMAND_BITS + SONY_ADDRESS_BITS + SONY_EXTRA_BITS) // 20 bits == SIRCS_20_PROTOCOL -#define SONY_UNIT 600 // 24 periods of 40kHz - -#define SONY_HEADER_MARK (4 * SONY_UNIT) // 2400 -#define SONY_ONE_MARK (2 * SONY_UNIT) // 1200 -#define SONY_ZERO_MARK SONY_UNIT -#define SONY_SPACE SONY_UNIT - -#define SONY_AVERAGE_DURATION_MIN 21000 // SONY_HEADER_MARK + SONY_SPACE + 12 * 2,5 * SONY_UNIT // 2.5 because we assume more zeros than ones -#define SONY_AVERAGE_DURATION_MAX 33000 // SONY_HEADER_MARK + SONY_SPACE + 20 * 2,5 * SONY_UNIT // 2.5 because we assume more zeros than ones -#define SONY_REPEAT_PERIOD 45000 // Commands are repeated every 45 ms (measured from start to start) for as long as the key on the remote control is held down. -#define SONY_MAXIMUM_REPEAT_DISTANCE (SONY_REPEAT_PERIOD - SONY_AVERAGE_DURATION_MIN) // 24 ms - -struct PulseDistanceWidthProtocolConstants SonyProtocolConstants = { SONY, SONY_KHZ, SONY_HEADER_MARK, SONY_SPACE, SONY_ONE_MARK, -SONY_SPACE, SONY_ZERO_MARK, SONY_SPACE, PROTOCOL_IS_LSB_FIRST, (SONY_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ - -/** - * @param numberOfBits should be one of SIRCS_12_PROTOCOL, SIRCS_15_PROTOCOL, SIRCS_20_PROTOCOL. Not checked! 20 -> send 13 address bits - */ -void IRsend::sendSony(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint8_t numberOfBits) { - uint32_t tData = (uint32_t) aAddress << 7 | (aCommand & 0x7F); - // send 5, 8, 13 address bits LSB first - sendPulseDistanceWidth(&SonyProtocolConstants, tData, numberOfBits, aNumberOfRepeats); -} - -bool IRrecv::decodeSony() { - - if (!checkHeader(&SonyProtocolConstants)) { - return false; - } - - // Check we have enough data. +2 for initial gap and start bit mark and space minus the last/MSB space. NO stop bit! 26, 32, 42 - if (decodedIRData.rawDataPtr->rawlen != (2 * SONY_BITS_MIN) + 2 && decodedIRData.rawDataPtr->rawlen != (2 * SONY_BITS_MAX) + 2 - && decodedIRData.rawDataPtr->rawlen != (2 * SONY_BITS_15) + 2) { - IR_DEBUG_PRINT(F("Sony: ")); - IR_DEBUG_PRINT(F("Data length=")); - IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen); - IR_DEBUG_PRINTLN(F(" is not 12, 15 or 20")); - return false; - } - - if (!decodePulseDistanceWidthData(&SonyProtocolConstants, (decodedIRData.rawDataPtr->rawlen - 1) / 2, 3)) { -#if defined(LOCAL_DEBUG) - Serial.print(F("Sony: ")); - Serial.println(F("Decode failed")); -#endif - return false; - } - - // Success -// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value - decodedIRData.command = decodedIRData.decodedRawData & 0x7F; // first 7 bits - decodedIRData.address = decodedIRData.decodedRawData >> 7; // next 5 or 8 or 13 bits - decodedIRData.numberOfBits = (decodedIRData.rawDataPtr->rawlen - 1) / 2; - decodedIRData.protocol = SONY; - - //Check for repeat - checkForRepeatSpaceTicksAndSetFlag(SONY_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK); - - return true; -} - -/********************************************************************************* - * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials - *********************************************************************************/ - -/* - * Old version with MSB first data - */ -#define SONY_DOUBLE_SPACE_USECS 500 // usually see 713 - not using ticks as get number wrap around -bool IRrecv::decodeSonyMSB(decode_results *aResults) { - long data = 0; - uint8_t bits = 0; - unsigned int offset = 0; // Dont skip first space, check its size - - if (aResults->rawlen < (2 * SONY_BITS_MIN) + 2) { - return false; - } - - // Some Sony's deliver repeats fast after first - // unfortunately can't spot difference from of repeat from two fast clicks - if (aResults->rawbuf[0] < (SONY_DOUBLE_SPACE_USECS / MICROS_PER_TICK)) { -#if defined(LOCAL_DEBUG) - Serial.println(F("IR Gap found")); -#endif - aResults->bits = 0; - aResults->value = 0xFFFFFFFF; - decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT; - decodedIRData.protocol = SONY; - return true; - } - offset++; - - // Check header "mark" - if (!matchMark(aResults->rawbuf[offset], SONY_HEADER_MARK)) { - return false; - } - offset++; - - // MSB first - Not compatible to standard, which says LSB first :-( - while (offset + 1 < aResults->rawlen) { - - // First check for the constant space length, we do not have a space at the end of raw data - // we are lucky, since the start space is equal the data space. - if (!matchSpace(aResults->rawbuf[offset], SONY_SPACE)) { - return false; - } - offset++; - - // bit value is determined by length of the mark - if (matchMark(aResults->rawbuf[offset], SONY_ONE_MARK)) { - data = (data << 1) | 1; - } else if (matchMark(aResults->rawbuf[offset], SONY_ZERO_MARK)) { - data = (data << 1) | 0; - } else { - return false; - } - offset++; - bits++; - - } - - aResults->bits = bits; - aResults->value = data; - aResults->decode_type = SONY; - decodedIRData.protocol = SONY; - return true; -} - -/** - * Old version with MSB first data - */ -void IRsend::sendSony(unsigned long data, int nbits) { - // Set IR carrier frequency - enableIROut (SONY_KHZ); - - // Header - mark(SONY_HEADER_MARK); - space(SONY_SPACE); - - // Old version with MSB first Data - sendPulseDistanceWidthData(SONY_ONE_MARK, SONY_SPACE, SONY_ZERO_MARK, SONY_SPACE, data, nbits, PROTOCOL_IS_MSB_FIRST); -} - -/** @}*/ -#if defined(LOCAL_DEBUG) -#undef LOCAL_DEBUG -#endif -#endif // _IR_SONY_HPP diff --git a/IRremote/src/ir_Template.hpp b/IRremote/src/ir_Template.hpp deleted file mode 100644 index 9855f51a3bd5581355263d288822290c55c25bcf..0000000000000000000000000000000000000000 --- a/IRremote/src/ir_Template.hpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - Assuming the protocol we are adding is for the (imaginary) manufacturer: Shuzu - - Our fantasy protocol is a standard protocol, so we can use this standard - template without too much work. Some protocols are quite unique and will require - considerably more work in this file! It is way beyond the scope of this text to - explain how to reverse engineer "unusual" IR protocols. But, unless you own an - oscilloscope, the starting point is probably to use the ReceiveDump.ino sketch and - try to spot the pattern! - - Before you start, make sure the IR library is working OK: - # Open up the Arduino IDE - # Load up the ReceiveDump.ino example sketch - # Run it - # Analyze your data to have an idea, what is the header timing, the bit timing, the address, the command and the checksum of your protocol. - - Now we can start to add our new protocol... - - 1. Copy this file to : ir_<YourProtocolName>.hpp - - 2. Replace all occurrences of "SHUZU" with the name of your protocol. - - 3. Tweak the #defines to suit your protocol. - - 4. If you're lucky, tweaking the #defines will make the decode and send() function - work. - - You have now written the code to support your new protocol! - - To integrate it into the IRremote library, you must search for "BOSEWAVE" - and add your protocol in the same way as it is already done for BOSEWAVE. - - You have to change the following files: - IRSend.hpp IRsend::write(IRData *aIRSendData + int_fast8_t aNumberOfRepeats) - IRProtocol.h Add it to decode_type_t - IRReceive.hpp IRrecv::decode() + printActiveIRProtocols(Print *aSerial) + getProtocolString(decode_type_t aProtocol) - IRremote.hpp At 3 occurrences of DECODE_XXX - IRremoteInt.h Add the declaration of the decode and send function - - Now open the Arduino IDE, load up the ReceiveDump.ino sketch, and run it. - Hopefully it will compile and upload. - If it doesn't, you've done something wrong. Check your work and look carefully at the error messages. - - If you get this far, I will assume you have successfully added your new protocol - - At last, delete this giant instructional comment. - - If you want us to include your work in the library so others may benefit - from your hard work, you have to extend the examples - IRremoteInfo, SmallReceiver, simple Receiver, SendDemo and UnitTest too - as well as the Readme.md - It is not an act, but required for completeness. - - Thanks - The maintainer - */ - -/* - * ir_Shuzu.hpp - * - * Contains functions for receiving and sending Shuzu IR Protocol ... - * - * Copyright (C) 2022 Shuzu Guru - * shuzu.guru@gmail.com - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************ - * MIT License - * - * Copyright (c) 2022 Unknown Contributor :-) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_SHUZU_HPP -#define _IR_SHUZU_HPP - -//============================================================================== -// -// -// S H U Z U -// -// -//============================================================================== -// see: https://www.... - -// LSB first, 1 start bit + 16 bit address + 8 bit command + 1 stop bit. -#define SHUZU_ADDRESS_BITS 16 // 16 bit address -#define SHUZU_COMMAND_BITS 8 // Command - -#define SHUZU_BITS (SHUZU_ADDRESS_BITS + SHUZU_COMMAND_BITS) // The number of bits in the protocol -#define SHUZU_UNIT 560 // All timings are in microseconds - -#define SHUZU_HEADER_MARK (16 * SHUZU_UNIT) // The length of the Header:Mark -#define SHUZU_HEADER_SPACE (8 * SHUZU_UNIT) // The length of the Header:Space - -#define SHUZU_BIT_MARK SHUZU_UNIT // The length of a Bit:Mark -#define SHUZU_ONE_SPACE (3 * SHUZU_UNIT) // The length of a Bit:Space for 1's -#define SHUZU_ZERO_SPACE SHUZU_UNIT // The length of a Bit:Space for 0's - -#define SHUZU_REPEAT_HEADER_SPACE (4 * SHUZU_UNIT) // 2250 - -#define SHUZU_REPEAT_PERIOD 110000 // From start to start -#define SHUZU_REPEAT_SPACE 45000 // SHUZU_REPEAT_PERIOD - default frame duration. Used for repeat detection. - -#define SHUZU_OTHER 1234 // Other things you may need to define - -// use BOSEWAVE, we have no SHUZU code -struct PulseDistanceWidthProtocolConstants ShuzuProtocolConstants = { BOSEWAVE, 38, SHUZU_HEADER_MARK, SHUZU_HEADER_SPACE, -SHUZU_BIT_MARK, SHUZU_ONE_SPACE, SHUZU_BIT_MARK, SHUZU_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, (SHUZU_REPEAT_PERIOD - / MICROS_IN_ONE_MILLI), NULL }; - -/************************************ - * Start of send and decode functions - ************************************/ - -void IRsend::sendShuzu(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats) { - - sendPulseDistanceWidth(&ShuzuProtocolConstants, (uint32_t) aCommand << 8 | aCommand, SHUZU_BITS, aNumberOfRepeats); -} - -bool IRrecv::decodeShuzu() { - /* - * First check for right data length - * Next check start bit / header - * Next try the decode - */ - // Check we have the right amount of data (28). The +4 is for initial gap, start bit mark and space + stop bit mark - if (decodedIRData.rawDataPtr->rawlen != (2 * SHUZU_BITS) + 4) { - // no debug output, since this check is mainly to determine the received protocol - return false; - } - - // Check header - if (!checkHeader(&ShuzuProtocolConstants)) { - return false; - } - - // Decode - if (!decodePulseDistanceData(&ShuzuProtocolConstants, SHUZU_BITS)) { - IR_DEBUG_PRINT(F("Shuzu: ")); - IR_DEBUG_PRINTLN(F("Decode failed")); - return false; - } - - // Success, interpret raw data -// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value - decodedIRData.command = decodedIRData.decodedRawData >> SHUZU_ADDRESS_BITS; // upper 8 bits of LSB first value - decodedIRData.address = decodedIRData.decodedRawData & 0xFFFF; // lowest 16 bit of LSB first value - decodedIRData.numberOfBits = SHUZU_BITS; - decodedIRData.protocol = BOSEWAVE; // we have no SHUZU code - - //Check for repeat - checkForRepeatSpaceAndSetFlag(SHUZU_REPEAT_SPACE / MICROS_IN_ONE_MILLI); - - return true; -} -#endif // _IR_SHUZU_HPP diff --git a/IRremote/src/private/IRTimer.hpp b/IRremote/src/private/IRTimer.hpp deleted file mode 100644 index 872b9fb0a32c3d70503539933c04d45bae14d005..0000000000000000000000000000000000000000 --- a/IRremote/src/private/IRTimer.hpp +++ /dev/null @@ -1,1995 +0,0 @@ -/** - * @file IRTimer.hpp - * - * @brief All timer specific definitions are contained in this file. - * Sets IR_SEND_PIN if required, e.g. if SEND_PWM_BY_TIMER for AVR is defined, which restricts the output to a dedicated pin number - * - * timerConfigForSend(aFrequencyKHz) must set output pin mode and disable receive interrupt if it uses the same resource - * - * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. - * - ************************************************************************************* - * MIT License - * - * Copyright (c) 2021-2023 Armin Joachimsmeyer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ************************************************************************************ - */ -#ifndef _IR_TIMER_HPP -#define _IR_TIMER_HPP - -/** \addtogroup HardwareDependencies CPU / board dependent definitions - * @{ - */ -/** \addtogroup Timer Usage of timers for the different CPU / boards - * @{ - */ -/* - * Functions declared here - */ -void timerResetInterruptPending(); -void timerEnableReceiveInterrupt(); -void timerDisableReceiveInterrupt(); -void timerConfigForReceive(); -void enableSendPWMByTimer(); -void disableSendPWMByTimer(); -void timerConfigForSend(uint16_t aFrequencyKHz); - -#if defined(SEND_PWM_BY_TIMER) && ( (defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE)) || defined(ARDUINO_ARCH_MBED) ) -#define SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER // Receive timer and send generation are independent, so it is recommended to always define SEND_PWM_BY_TIMER -#endif - -#if defined(IR_SEND_PIN) && defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER) // For e.g ESP32 IR_SEND_PIN definition is useful -#undef IR_SEND_PIN // avoid warning below, user warning is done at IRremote.hpp -#endif - -// Macros for enabling timers for development -//#define SEND_PWM_BY_TIMER -//#define IR_USE_AVR_TIMER1 -//#define IR_USE_AVR_TIMER2 -//#define IR_USE_AVR_TIMER3 -//#define IR_USE_AVR_TIMER4 -//#define IR_USE_AVR_TIMER4_HS -//#define IR_USE_AVR_TIMER5 -//#define IR_USE_AVR_TIMER_TINY0 -//#define IR_USE_AVR_TIMER_TINY1 -//#define IR_USE_AVR_TIMER_A -//#define IR_USE_AVR_TIMER_B -//#define IR_USE_AVR_TIMER_D -//#define __MK20DX128__ -//#define __MKL26Z64__ -//#define __IMXRT1062__ -//#define ESP8266 -//#define ESP32 -//#define ARDUINO_ARCH_SAMD -//#define ARDUINO_ARCH_MBED -//#define ARDUINO_ARCH_RP2040 -//#define NRF5 -//#define __STM32F1__ -//#define STM32F1xx -//#define PARTICLE -//#define ARDUINO_ARCH_RENESAS - -#if defined (DOXYGEN) -/** - * Hardware / timer dependent pin number for sending IR if SEND_PWM_BY_TIMER is defined. Otherwise used as default for IrSender.sendPin. - */ -#define IR_SEND_PIN - -/** - * Configures the timer to be able to generate the receive sample interrupt, - * which consumes a small amount of CPU every 50 (MICROS_PER_TICK) us. - * The actual interrupt generation is controlled by timerEnableReceiveInterrupt() and timerDisableReceiveInterrupt(). - * timerConfigForReceive() is used exclusively by IRrecv::start() - */ -void timerConfigForReceive() { -} -/** - * Enables the receive sample timer interrupt, which consumes a small amount of CPU every 50 us. - */ -void timerEnableReceiveInterrupt() { -} - -/** - * Disables the receive sample timer interrupt. This must be done before using the timer for e.g. tone(). - * Is a synonym for calling end() or stop(). - */ -void timerDisableReceiveInterrupt() { -} - -/** - * IF PWM should be generated not by software, but by a timer, this function sets output pin mode, - * configures the timer for generating a PWM with duty cycle of IR_SEND_DUTY_CYCLE_PERCENT - * and disables the receive interrupt if it uses the same resource. - * For most architectures, the pin number(s) which can be used for output is determined by the timer used! - * The output of the PWM signal is controlled by enableSendPWMByTimer() and disableSendPWMByTimer(). - * timerConfigForSend() is used exclusively by IRsend::enableIROut(). - * @param aFrequencyKHz Frequency of the sent PWM signal in kHz. There is no practical reason to have a sub kHz resolution for sending frequency :-). - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { -} - -/** - * Enables output of the PWM signal of the timer at the timer pin. - */ -void enableSendPWMByTimer() { -} -/** - * Disables output of the PWM signal of the timer at the timer pin and set it to inactive. - */ -void disableSendPWMByTimer() { -} - -#elif defined(__AVR__) -/********************************************************************************************************************** - * Mapping of AVR boards to AVR timers - * For some CPU's you have the option to switch the timer and the hardware send pin - **********************************************************************************************************************/ -/*************************************** - * Plain AVR CPU's, no boards - ***************************************/ -// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc -#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) || defined(__AVR_ATmega168__) \ - || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) -//#define IR_USE_AVR_TIMER1 // send pin = pin 9 -#define IR_USE_AVR_TIMER2 // send pin = pin 3 -# endif - -// Arduino Mega -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4) && !defined(IR_USE_AVR_TIMER5) -//#define IR_USE_AVR_TIMER1 // send pin = pin 11 -#define IR_USE_AVR_TIMER2 // send pin = pin 9 -//#define IR_USE_AVR_TIMER3 // send pin = pin 5 -//#define IR_USE_AVR_TIMER4 // send pin = pin 6 -//#define IR_USE_AVR_TIMER5 // send pin = pin 46 -# endif - -// Leonardo -#elif defined(__AVR_ATmega32U4__) && ! defined(TEENSYDUINO) && ! defined(ARDUINO_AVR_PROMICRO) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS) -//#define IR_USE_AVR_TIMER1 // send pin = pin 9 -#define IR_USE_AVR_TIMER3 // send pin = pin 5 -//#define IR_USE_AVR_TIMER4_HS // send pin = pin 13 -# endif - -// Nano Every, Uno WiFi Rev2 and similar -#elif defined(__AVR_ATmega808__) || defined(__AVR_ATmega809__) || defined(__AVR_ATmega3208__) || defined(__AVR_ATmega3209__) \ - || defined(__AVR_ATmega1608__) || defined(__AVR_ATmega1609__) || defined(__AVR_ATmega4808__) || defined(__AVR_ATmega4809__) || defined(__AVR_ATtiny1604__) -# if !defined(IR_USE_AVR_TIMER_B) -#define IR_USE_AVR_TIMER_B // send pin = pin 6 on ATmega4809 1 on ATmega4809 -# endif - -#elif defined(__AVR_ATtiny816__) || defined(__AVR_ATtiny1614__) || defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // e.g. TinyCore boards -# if !defined(IR_USE_AVR_TIMER_A) && !defined(IR_USE_AVR_TIMER_D) -#define IR_USE_AVR_TIMER_A // use this if you use MegaTinyCore, Tone is on TCB and millis() on TCD -//#define IR_USE_AVR_TIMER_D // use this if you use TinyCore -# endif - -// ATmega8u2, ATmega16U2, ATmega32U2, ATmega8 - Timer 2 does not work with existing code below -#elif defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega8__) -# if !defined(IR_USE_AVR_TIMER1) -#define IR_USE_AVR_TIMER1 // send pin = pin C6 -# endif - -// ATtiny84 -#elif defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny88__) -# if !defined(IR_USE_AVR_TIMER1) -#define IR_USE_AVR_TIMER1 // send pin = pin 6 -# endif - -#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -# if !defined(IR_USE_AVR_TIMER1) -#define IR_USE_AVR_TIMER1 // send pin = pin PB1 / 8 -# endif -#define USE_TIMER_CHANNEL_B - -//ATtiny85, 45, 25 -#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) -# if !defined(IR_USE_AVR_TIMER_TINY0) && !defined(IR_USE_AVR_TIMER_TINY1) -# if defined(ARDUINO_AVR_DIGISPARK) // tested with 16 and 8 MHz -#define IR_USE_AVR_TIMER_TINY0 // send pin = pin 1 -// standard Digispark settings use timer 1 for millis() and micros() -# else -// standard ATTinyCore settings use timer 0 for millis() and micros() -#define IR_USE_AVR_TIMER_TINY1 // send pin = pin 4 -# endif -# endif - -/*************************************** - * SPARKFUN Pro Micro board - ***************************************/ -#elif defined(ARDUINO_AVR_PROMICRO) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS) -//#define IR_USE_AVR_TIMER1 // send pin = pin 9 -#define IR_USE_AVR_TIMER3 // send pin = pin 5 -//#define IR_USE_AVR_TIMER4_HS // send pin = pin 13 -# endif - -/*************************************** - * TEENSY Boards - ***************************************/ -// Teensy 1.0 -#elif defined(__AVR_AT90USB162__) -# if !defined(IR_USE_AVR_TIMER1) -#define IR_USE_AVR_TIMER1 // send pin = pin 17 -# endif - -// Teensy++ 1.0 & 2.0 -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3) -//#define IR_USE_AVR_TIMER1 // send pin = pin 25 -#define IR_USE_AVR_TIMER2 // send pin = pin 1 -//#define IR_USE_AVR_TIMER3 // send pin = pin 16 -# endif - -// Teensy 2.0 -#elif defined(__AVR_ATmega32U4__) && defined(TEENSYDUINO) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS) -//#define IR_USE_AVR_TIMER1 // send pin = pin 14 (Teensy 2.0 - physical pin: B5) -//#define IR_USE_AVR_TIMER3 // send pin = pin 9 (Teensy 2.0 - physical pin: C6) -#define IR_USE_AVR_TIMER4_HS // send pin = pin 10 (Teensy 2.0 - physical pin: C7) -# endif - -/*************************************** - * CPU's with MegaCore - ***************************************/ -// MegaCore - ATmega64, ATmega128 -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) -# if !defined(IR_USE_AVR_TIMER1) -#define IR_USE_AVR_TIMER1 // send pin = pin 13 -# endif - -/*************************************** - * CPU's with MajorCore - ***************************************/ -#elif defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) -#define IR_USE_AVR_TIMER1 // send pin = pin 13 -//#define IR_USE_AVR_TIMER3 // send pin = pin 12 - ATmega162 only -# endif - -/*************************************** - * CPU's with MightyCore - ***************************************/ -// MightyCore - ATmega1284 -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3) -//#define IR_USE_AVR_TIMER1 // send pin = pin 13 -#define IR_USE_AVR_TIMER2 // send pin = pin 14 -//#define IR_USE_AVR_TIMER3 // send pin = pin 6 -# endif - -// MightyCore - ATmega164, ATmega324, ATmega644 -#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) -# if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) -//#define IR_USE_AVR_TIMER1 // send pin = pin 13 -#define IR_USE_AVR_TIMER2 // send pin = pin 14 -# endif - -// MightyCore - ATmega8535, ATmega16, ATmega32 -#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) -# if !defined(IR_USE_AVR_TIMER1) -#define IR_USE_AVR_TIMER1 // send pin = pin 13 -# endif - -#endif // AVR CPU's -/********************************************************************************************************************** - * End of AVR mapping, start of AVR timers - **********************************************************************************************************************/ -/* - * AVR Timer1 (16 bits) - */ -#if defined(IR_USE_AVR_TIMER1) - -# if defined(TIMSK1) -#define TIMSK TIMSK1 // use the value of TIMSK1 for the statements below -# endif - -void timerEnableReceiveInterrupt() { - TIMSK |= _BV(OCIE1A); -} -void timerDisableReceiveInterrupt() { - TIMSK &= ~_BV(OCIE1A); -} - -# if defined(USE_TIMER_CHANNEL_B) -# if defined(TIMER1_COMPB_vect) -#define TIMER_INTR_NAME TIMER1_COMPB_vect -# elif defined(TIM1_COMPB_vect) -#define TIMER_INTR_NAME TIM1_COMPB_vect -# endif -#else -# if defined(TIMER1_COMPA_vect) -#define TIMER_INTR_NAME TIMER1_COMPA_vect -# elif defined(TIM1_COMPA_vect) -#define TIMER_INTR_NAME TIM1_COMPA_vect -# endif -# endif - -void timerConfigForReceive() { - TCCR1A = 0; - TCCR1B = _BV(WGM12) | _BV(CS10); // CTC mode, no prescaling - OCR1A = (F_CPU * MICROS_PER_TICK) / MICROS_IN_ONE_SECOND; // 16 * 50 = 800 - TCNT1 = 0; -} - -# if defined(SEND_PWM_BY_TIMER) -# if defined(CORE_OC1A_PIN) -#define IR_SEND_PIN CORE_OC1A_PIN // Teensy - -# elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define IR_SEND_PIN 11 // Arduino Mega - -// MightyCore, MegaCore, MajorCore -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \ -|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \ -|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__) -#define IR_SEND_PIN 13 - -# elif defined(__AVR_ATtiny84__) -#define IR_SEND_PIN 6 - -# elif defined(__AVR_ATtiny88__) -#define IR_SEND_PIN 8 - -# elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -/* - * !!! IR_SEND_PIN value must correspond to ENABLE_SEND_PWM_BY_TIMER below !!! - */ -# if defined(USE_TIMER_CHANNEL_B) -#define IR_SEND_PIN PIN_PB1 // OC1BU / PB1 / Pin9 at ATTinyCore -//#define IR_SEND_PIN PIN_PB3 // OC1BV / PB3 / Pin11 at ATTinyCore -//#define IR_SEND_PIN PIN_PB5 // OC1BW / PB5 / Pin13 at ATTinyCore -//#define IR_SEND_PIN PIN_PB7 // OC1BX / PB7 / Pin15 at ATTinyCore -# else -#define IR_SEND_PIN PIN_PB0 // OC1AU / PB1 / Pin8 at ATTinyCore -//#define IR_SEND_PIN PIN_PB2 // OC1AV / PB3 / Pin10 at ATTinyCore -//#define IR_SEND_PIN PIN_PB4 // OC1AW / PB5 / Pin12 at ATTinyCore -//#define IR_SEND_PIN PIN_PB6 // OC1AX / PB6 / Pin14 at ATTinyCore -# endif - -# else -#define IR_SEND_PIN 9 // OC1A Arduino Duemilanove, Diecimila, LilyPad, Sparkfun Pro Micro, Leonardo, MH-ET Tiny88 etc. -# endif // defined(CORE_OC1A_PIN) - -# if defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) -// Clear OC1A/OC1B on Compare Match when up-counting. Set OC1A/OC1B on Compare Match when down counting. -# if defined(USE_TIMER_CHANNEL_B) -void enableSendPWMByTimer() { - TCNT1 = 0; - TCCR1A |= _BV(COM1B1); - TCCR1D |= _BV(OC1BU); // + enable OC1BU as output - //TCNT1 = 0; TCCR1A |= _BV(COM1B1); TCCR1D |= _BV(OC1BV); // + enable OC1BV as output - //TCNT1 = 0; TCCR1A |= _BV(COM1B1); TCCR1D |= _BV(OC1BW); // + enable OC1BW as output - //TCNT1 = 0; TCCR1A |= _BV(COM1B1); TCCR1D |= _BV(OC1BX); // + enable OC1BX as output -} -# else -void disableSendPWMByTimer() { - TCNT1 = 0; - TCCR1A |= _BV(COM1A1); - TCCR1D |= _BV(OC1AU); // + enable OC1BU as output - //TCNT1 = 0; TCCR1A |= _BV(COM1A1); TCCR1D |= _BV(OC1AV); // + enable OC1BV as output - //TCNT1 = 0; TCCR1A |= _BV(COM1A1); TCCR1D |= _BV(OC1AW); // + enable OC1BW as output - //TCNT1 = 0; TCCR1A |= _BV(COM1A1); TCCR1D |= _BV(OC1AX); // + enable OC1BX as output -} - -# endif -void disableSendPWMByTimer() { - TCCR1D = 0; -} -# else -# if defined(USE_TIMER_CHANNEL_B) -void enableSendPWMByTimer() { - TCNT1 = 0; - TCCR1A |= _BV(COM1B1); // Clear OC1A/OC1B on Compare Match when up-counting. Set OC1A/OC1B on Compare Match when counting down. -} -void disableSendPWMByTimer() { - TCCR1A &= ~(_BV(COM1B1)); -} -# else -void enableSendPWMByTimer() { - TCNT1 = 0; - TCCR1A |= _BV(COM1A1); // Clear OC1A/OC1B on Compare Match when up-counting. Set OC1A/OC1B on Compare Match when downcounting. -} -void disableSendPWMByTimer() { - TCCR1A &= ~(_BV(COM1A1)); -} -# endif -# endif - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); - -# if (((F_CPU / 2000) / 38) < 256) - const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz); // 210,52 for 38 kHz @16 MHz clock, 2000 instead of 1000 because of Phase Correct PWM - TCCR1A = _BV(WGM11); // PWM, Phase Correct, Top is ICR1 - TCCR1B = _BV(WGM13) | _BV(CS10); // CS10 -> no prescaling - ICR1 = tPWMWrapValue - 1; -# if defined(USE_TIMER_CHANNEL_B) - OCR1B = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; -# else - OCR1A = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; -# endif - TCNT1 = 0; // not really required, since we have an 8 bit counter, but makes the signal more reproducible -# else - const uint16_t tPWMWrapValue = ((F_CPU / 8) / 2000) / (aFrequencyKHz); // 2000 instead of 1000 because of Phase Correct PWM - TCCR1A = _BV(WGM11);// PWM, Phase Correct, Top is ICR1 - TCCR1B = _BV(WGM13) | _BV(CS11);// CS11 -> Prescaling by 8 - ICR1 = tPWMWrapValue - 1; -# if defined(USE_TIMER_CHANNEL_B) - OCR1A = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; -# else - OCR1A = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; -# endif - TCNT1 = 0; // not really required, since we have an 8 bit counter, but makes the signal more reproducible -# endif -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR Timer2 (8 bits) // Tone timer on Uno - */ -#elif defined(IR_USE_AVR_TIMER2) - -void timerEnableReceiveInterrupt() { - TIMSK2 = _BV(OCIE2B); // Output Compare Match A Interrupt Enable -} -void timerDisableReceiveInterrupt() { - TIMSK2 = 0; -} -#define TIMER_INTR_NAME TIMER2_COMPB_vect // We use TIMER2_COMPB_vect to be compatible with tone() library - -#define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND) - -void timerConfigForReceive() { -# if (TIMER_COUNT_TOP < 256) - TCCR2A = _BV(WGM21); - TCCR2B = _BV(CS20); - OCR2A = TIMER_COUNT_TOP; - OCR2B = TIMER_COUNT_TOP; - TCNT2 = 0; -# else - TCCR2A = _BV(WGM21); - TCCR2B = _BV(CS21); - OCR2A = TIMER_COUNT_TOP / 8; - OCR2B = TIMER_COUNT_TOP / 8; - TCNT2 = 0; -# endif -} - -# if defined(SEND_PWM_BY_TIMER) -# if defined(CORE_OC2B_PIN) -#define IR_SEND_PIN CORE_OC2B_PIN // Teensy - -# elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define IR_SEND_PIN 9 // Arduino Mega - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) -#define IR_SEND_PIN 14 // MightyCore, MegaCore - -# else -#define IR_SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc -# endif // defined(CORE_OC2B_PIN) - -void enableSendPWMByTimer() { - TCNT2 = 0; - TCCR2A |= _BV(COM2B1); // Clear OC2B on Compare Match -} -void disableSendPWMByTimer() { - TCCR2A &= ~(_BV(COM2B1)); // Normal port operation, OC2B disconnected. -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); - -# if (((F_CPU / 2000) / 38) < 256) - /* - * tPWMWrapValue is 210.52 for 38 kHz, 17.58 for 455 kHz @16 MHz clock. - * 210 -> 38.095 kHz, 17 -> 470.588 kHz @16 MHz clock. - * We use 2000 instead of 1000 in the formula, because of Phase Correct PWM. - */ - const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz); - TCCR2A = _BV(WGM20); // PWM, Phase Correct, Top is OCR2A - TCCR2B = _BV(WGM22) | _BV(CS20); // CS20 -> no prescaling - OCR2A = tPWMWrapValue - 1; // The top value for the timer. The modulation frequency will be F_CPU / 2 / (OCR2A + 1). - OCR2B = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; - TCNT2 = 0; // not really required, since we have an 8 bit counter, but makes the signal more reproducible -# else - const uint16_t tPWMWrapValue = ((F_CPU / 8) / 2000) / (aFrequencyKHz); // 2000 instead of 1000 because of Phase Correct PWM - TCCR2A = _BV(WGM20);// PWM, Phase Correct, Top is OCR2A - TCCR2B = _BV(WGM22) | _BV(CS21);// CS21 -> Prescaling by 8 - OCR2A = tPWMWrapValue - 1; - OCR2B = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; - TCNT2 = 0;// not really required, since we have an 8 bit counter, but makes the signal more reproducible -# endif -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR Timer3 (16 bits) - */ -#elif defined(IR_USE_AVR_TIMER3) - -void timerEnableReceiveInterrupt() { - TIMSK3 = _BV(OCIE3B); -} -void timerDisableReceiveInterrupt() { - TIMSK3 = 0; -} -#define TIMER_INTR_NAME TIMER3_COMPB_vect - -void timerConfigForReceive() { - TCCR3A = 0; - TCCR3B = _BV(WGM32) | _BV(CS30); - OCR3A = F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND; - OCR3B = F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND; - TCNT3 = 0; -} - -# if defined(SEND_PWM_BY_TIMER) -# if defined(CORE_OC3A_PIN) -#define IR_SEND_PIN CORE_OC3A_PIN // Teensy - -# elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) \ -|| defined(__AVR_ATmega32U4__) || defined(ARDUINO_AVR_PROMICRO) -#define IR_SEND_PIN 5 // Arduino Mega, Arduino Leonardo, Sparkfun Pro Micro - -# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) -#define IR_SEND_PIN 6 // MightyCore, MegaCore - -# else -#error Please add OC3A pin number here -# endif - -void enableSendPWMByTimer() { - TCNT3 = 0; - TCCR3A |= _BV(COM3A1); -} -void disableSendPWMByTimer() { - TCCR3A &= ~(_BV(COM3A1)); -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { -#if F_CPU > 16000000 -#error "Creating timer PWM with timer 3 is not supported for F_CPU > 16 MHz" -#endif - timerDisableReceiveInterrupt(); - - const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz); // 210,52 for 38 kHz @16 MHz clock, 2000 instead of 1000 because of Phase Correct PWM - TCCR3A = _BV(WGM31); - TCCR3B = _BV(WGM33) | _BV(CS30); // PWM, Phase Correct, ICRn as TOP, complete period is double of tPWMWrapValue - ICR3 = tPWMWrapValue - 1; - OCR3A = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; - TCNT3 = 0; // required, since we have an 16 bit counter -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR Timer4 (16 bits) - */ -#elif defined(IR_USE_AVR_TIMER4) -void timerEnableReceiveInterrupt() { - TIMSK4 = _BV(OCIE4A); -} -void timerDisableReceiveInterrupt() { - TIMSK4 = 0; -} -#define TIMER_INTR_NAME TIMER4_COMPA_vect - -void timerConfigForReceive() { - TCCR4A = 0; - TCCR4B = _BV(WGM42) | _BV(CS40); - OCR4A = F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND; - TCNT4 = 0; -} - -# if defined(SEND_PWM_BY_TIMER) -# if defined(CORE_OC4A_PIN) -#define IR_SEND_PIN CORE_OC4A_PIN -# elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define IR_SEND_PIN 6 // Arduino Mega -# else -#error Please add OC4A pin number here -# endif - -void enableSendPWMByTimer() { - TCNT4 = 0; - TCCR4A |= _BV(COM4A1); -} -void disableSendPWMByTimer() { - TCCR4A &= ~(_BV(COM4A1)); -} - -void timerConfigForSend(uint16_t aFrequencyKHz) { -#if F_CPU > 16000000 -#error "Creating timer PWM with timer 4 is not supported for F_CPU > 16 MHz" -#endif - timerDisableReceiveInterrupt(); - const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz); // 210,52 for 38 kHz @16 MHz clock, 2000 instead of 1000 because of Phase Correct PWM - TCCR4A = _BV(WGM41); - TCCR4B = _BV(WGM43) | _BV(CS40); - ICR4 = tPWMWrapValue - 1; - OCR4A = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; - TCNT4 = 0; // required, since we have an 16 bit counter -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR Timer4 (10 bits, high speed option) - */ -#elif defined(IR_USE_AVR_TIMER4_HS) - -void timerEnableReceiveInterrupt() { - TIMSK4 = _BV(TOIE4); -} -void timerDisableReceiveInterrupt() { - TIMSK4 = 0; -} -#define TIMER_INTR_NAME TIMER4_OVF_vect - -void timerConfigForReceive() { - TCCR4A = 0; - TCCR4B = _BV(CS40); - TCCR4C = 0; - TCCR4D = 0; - TCCR4E = 0; - TC4H = (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND) >> 8; - OCR4C = (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND) & 255; - TC4H = 0; - TCNT4 = 0; -} - -# if defined(SEND_PWM_BY_TIMER) -# if defined(CORE_OC4A_PIN) -#define IR_SEND_PIN CORE_OC4A_PIN // Teensy 2.0 -# elif defined(ARDUINO_AVR_PROMICRO) -#define IR_SEND_PIN 5 // Sparkfun Pro Micro -# elif defined(__AVR_ATmega32U4__) -#define IR_SEND_PIN 13 // Leonardo -# else -#error Please add OC4A pin number here -# endif - -# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro -void enableSendPWMByTimer() { - TCNT4 = 0; - TCCR4A |= _BV(COM4A0); // Use complementary OC4A output on pin 5 -} -void disableSendPWMByTimer() { - TCCR4A &= ~(_BV(COM4A0)); // (Pro Micro does not map PC7 (32/ICP3/CLK0/OC4A) -} -// of ATmega32U4 ) -# else -void enableSendPWMByTimer() { - TCNT4 = 0; - TCCR4A |= _BV(COM4A1); - DDRC |= 1 << 7; -} -void disableSendPWMByTimer() { - TCCR4A &= ~(_BV(COM4A1)); -} -# endif - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { -#if F_CPU > 16000000 -#error "Creating timer PWM with timer 4 HS is not supported for F_CPU > 16 MHz" -#endif - timerDisableReceiveInterrupt(); - - const uint16_t tPWMWrapValue = ((F_CPU / 2000) / (aFrequencyKHz)) - 1; // 210,52 for 38 kHz @16 MHz clock, 2000 instead of 1000 because of Phase Correct PWM - TCCR4A = (1 << PWM4A); - TCCR4B = _BV(CS40); - TCCR4C = 0; - TCCR4D = (1 << WGM40); - TCCR4E = 0; - TC4H = tPWMWrapValue >> 8; - OCR4C = tPWMWrapValue; - TC4H = (tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT / 100) >> 8; - OCR4A = (tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT / 100) & 255; - TCNT4 = 0; // not really required, since we have an 8 bit counter, but makes the signal more reproducible -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR Timer5 (16 bits) - */ -#elif defined(IR_USE_AVR_TIMER5) - -void timerEnableReceiveInterrupt() { - TIMSK5 = _BV(OCIE5A); -} -void timerDisableReceiveInterrupt() { - TIMSK5 = 0; -} -#define TIMER_INTR_NAME TIMER5_COMPA_vect - -void timerConfigForReceive() { - TCCR5A = 0; - TCCR5B = _BV(WGM52) | _BV(CS50); - OCR5A = F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND; - TCNT5 = 0; -} - -# if defined(SEND_PWM_BY_TIMER) -# if defined(CORE_OC5A_PIN) -#define IR_SEND_PIN CORE_OC5A_PIN -# elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define IR_SEND_PIN 46 // Arduino Mega -# else -#error Please add OC5A pin number here -# endif - -void enableSendPWMByTimer() { - TCNT5 = 0; - TCCR5A |= _BV(COM5A1); -} -void disableSendPWMByTimer() { - TCCR5A &= ~(_BV(COM5A1)); -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { -#if F_CPU > 16000000 -#error "Creating timer PWM with timer 5 is not supported for F_CPU > 16 MHz" -#endif - timerDisableReceiveInterrupt(); - - const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz); // 210,52 for 38 kHz @16 MHz clock, 2000 instead of 1000 because of Phase Correct PWM - TCCR5A = _BV(WGM51); - TCCR5B = _BV(WGM53) | _BV(CS50); - ICR5 = tPWMWrapValue - 1; - OCR5A = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; - TCNT5 = 0; // required, since we have an 16 bit counter -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR Timer0 for ATtinies (8 bits) - */ -#elif defined(IR_USE_AVR_TIMER_TINY0) - -void timerEnableReceiveInterrupt() { - TIMSK |= _BV(OCIE0A); -} -void timerDisableReceiveInterrupt() { - TIMSK &= ~(_BV(OCIE0A)); -} -#define TIMER_INTR_NAME TIMER0_COMPA_vect - -#define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND) - -void timerConfigForReceive() { -# if (TIMER_COUNT_TOP < 256) - TCCR0A = _BV(WGM01); // CTC, Top is OCR0A - TCCR0B = _BV(CS00);// No prescaling - OCR0A = TIMER_COUNT_TOP; - TCNT0 = 0; -# else - TCCR0A = _BV(WGM01); - TCCR0B = _BV(CS01); // prescaling by 8 - OCR0A = TIMER_COUNT_TOP / 8; - TCNT0 = 0; -# endif -} - -# if defined(SEND_PWM_BY_TIMER) -#define IR_SEND_PIN 1 - -void enableSendPWMByTimer() { - TCNT0 = 0; - TCCR0A |= _BV(COM0B1); -} -void disableSendPWMByTimer() { - TCCR0A &= ~(_BV(COM0B1)); -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { -#if F_CPU > 16000000 -#error "Creating timer PWM with timer TINY0 is not supported for F_CPU > 16 MHz" -#endif - timerDisableReceiveInterrupt(); - - const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz); // 210,52 for 38 kHz @16 MHz clock, 2000 instead of 1000 because of Phase Correct PWM - TCCR0A = _BV(WGM00); // PWM, Phase Correct, Top is OCR0A - TCCR0B = _BV(WGM02) | _BV(CS00); // CS00 -> no prescaling - OCR0A = tPWMWrapValue - 1; - OCR0B = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; - TCNT0 = 0; // not really required, since we have an 8 bit counter, but makes the signal more reproducible -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR Timer1 for ATtinies (8 bits) - */ -#elif defined(IR_USE_AVR_TIMER_TINY1) - -void timerEnableReceiveInterrupt() { - TIMSK |= _BV(OCIE1B); -} -void timerDisableReceiveInterrupt() { - TIMSK &= ~(_BV(OCIE1B)); -} -#define TIMER_INTR_NAME TIMER1_COMPB_vect - -#define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND) - -void timerConfigForReceive() { -# if (TIMER_COUNT_TOP < 256) - TCCR1 = _BV(CTC1) | _BV(CS10); // Clear Timer/Counter on Compare Match, Top is OCR1C, No prescaling - GTCCR = 0;// normal, non-PWM mode - OCR1C = TIMER_COUNT_TOP; - TCNT1 = 0; -# else - TCCR1 = _BV(CTC1) | _BV(CS12); // Clear Timer/Counter on Compare Match, Top is OCR1C, prescaling by 8 - GTCCR = 0; // normal, non-PWM mode - OCR1C = TIMER_COUNT_TOP / 8; - TCNT1 = 0; -# endif -} - -# if defined(SEND_PWM_BY_TIMER) -#define IR_SEND_PIN 4 - -void enableSendPWMByTimer() { - TCNT1 = 0; - GTCCR |= _BV(PWM1B) | _BV(COM1B0); // Enable pin 4 PWM output (PB4 - Arduino D4) -} -void disableSendPWMByTimer() { - GTCCR &= ~(_BV(PWM1B) | _BV(COM1B0)); -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); - -# if (((F_CPU / 1000) / 38) < 256) - const uint16_t tPWMWrapValue = (F_CPU / 1000) / (aFrequencyKHz); // 421 @16 MHz, 26 @1 MHz and 38 kHz - TCCR1 = _BV(CTC1) | _BV(CS10);// CTC1 = 1: TOP value set to OCR1C, CS10 No Prescaling - OCR1C = tPWMWrapValue - 1; - OCR1B = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; - TCNT1 = 0;// not really required, since we have an 8 bit counter, but makes the signal more reproducible - GTCCR = _BV(PWM1B) | _BV(COM1B0);// PWM1B = 1: Enable PWM for OCR1B, COM1B0 Clear on compare match -# else - const uint16_t tPWMWrapValue = ((F_CPU / 2) / 1000) / (aFrequencyKHz); // 210 for 16 MHz and 38 kHz - TCCR1 = _BV(CTC1) | _BV(CS11); // CTC1 = 1: TOP value set to OCR1C, CS11 Prescaling by 2 - OCR1C = tPWMWrapValue - 1; - OCR1B = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; - TCNT1 = 0; // not really required, since we have an 8 bit counter, but makes the signal more reproducible - GTCCR = _BV(PWM1B) | _BV(COM1B0); // PWM1B = 1: Enable PWM for OCR1B, COM1B0 Clear on compare match -# endif -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR TimerA for TinyCore 32 (16 bits) - */ -#elif defined(IR_USE_AVR_TIMER_A) -#define TIMER_REQUIRES_RESET_INTR_PENDING -void timerResetInterruptPending() { - TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; -} -void timerEnableReceiveInterrupt() { - TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm; -} -void timerDisableReceiveInterrupt() { - TCA0.SINGLE.INTCTRL &= ~(TCA_SINGLE_OVF_bm); -} -#define TIMER_INTR_NAME TCA0_OVF_vect -// For MegaTinyCore: -// TCB1 is used by Tone() -// TCB2 is used by Servo, but we cannot hijack the ISR, so we must use a dedicated timer for the 20 ms interrupt -// TCB3 is used by millis() -// Must use TCA0, since TCBx have only prescaler %2. Use single (16bit) mode, because it seems to be easier :-) -void timerConfigForReceive() { - TCA0.SINGLE.CTRLD = 0; // Single mode - required at least for MegaTinyCore - TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc; // Normal mode, top = PER - TCA0.SINGLE.PER = (F_CPU / MICROS_IN_ONE_SECOND) * MICROS_PER_TICK; // 800 at 16 MHz - TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm; // set prescaler to 1 and enable timer -} - -# if defined(SEND_PWM_BY_TIMER) -#error "No support for hardware PWM generation for ATtiny3216/17 etc." -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR TimerB (8 bits) for ATmega4809 (Nano Every, Uno WiFi Rev2) - */ -#elif defined(IR_USE_AVR_TIMER_B) - -// ATmega4809 TCB0 -#define TIMER_REQUIRES_RESET_INTR_PENDING -void timerResetInterruptPending() { - TCB0.INTFLAGS = TCB_CAPT_bm; -} -void timerEnableReceiveInterrupt() { - TCB0.INTCTRL = TCB_CAPT_bm; -} -void timerDisableReceiveInterrupt() { - TCB0.INTCTRL &= ~(TCB_CAPT_bm); -} -#define TIMER_INTR_NAME TCB0_INT_vect - -void timerConfigForReceive() { - TCB0.CTRLB = (TCB_CNTMODE_INT_gc); // Periodic interrupt mode - TCB0.CCMP = ((F_CPU * MICROS_PER_TICK) / MICROS_IN_ONE_SECOND); - TCB0.INTFLAGS = TCB_CAPT_bm; // reset interrupt flags - TCB0.CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm); -} - -# if defined(SEND_PWM_BY_TIMER) -# if defined(__AVR_ATmega4808__) || defined(__AVR_ATmega4809__) -#define IR_SEND_PIN 6 // PF4 on ATmega4809 / Nano Every (see pins_arduino.h digital_pin_to_timer) -# else -#error SEND_PWM_BY_TIMER not yet supported for this CPU -# endif - -void enableSendPWMByTimer() { - TCB0.CNT = 0; - TCB0.CTRLB |= TCB_CCMPEN_bm; // set Compare/Capture Output Enable -} -void disableSendPWMByTimer() { - TCB0.CTRLB &= ~(TCB_CCMPEN_bm); -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { -#if F_CPU > 16000000 - // we have only prescaler 2 or must take clock of timer A (which is non deterministic) -#error "Creating timer PWM with timer TCB0 is not possible for F_CPU > 16 MHz" -#endif - timerDisableReceiveInterrupt(); - - const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz); // 210,52 for 38 kHz @16 MHz clock, 2000 instead of 1000 because of using CLK / 2 - TCB0.CTRLB = TCB_CNTMODE_PWM8_gc; // 8 bit PWM mode - TCB0.CCMPL = tPWMWrapValue - 1; // Period of 8 bit PWM - TCB0.CCMPH = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; // Duty cycle of waveform of 8 bit PWM - TCB0.CTRLA = (TCB_CLKSEL_CLKDIV2_gc) | (TCB_ENABLE_bm); // use CLK / 2 - TCB0.CNT = 0; // not really required, since we have an 8 bit counter, but makes the signal more reproducible -} -# endif // defined(SEND_PWM_BY_TIMER) - -/* - * AVR TimerD for TinyCore 32 (16 bits) - */ -#elif defined(IR_USE_AVR_TIMER_D) - -#define TIMER_REQUIRES_RESET_INTR_PENDING -void timerResetInterruptPending() { - TCD0.INTFLAGS = TCD_OVF_bm; -} -void timerEnableReceiveInterrupt() { - TCD0.INTCTRL = TCD_OVF_bm; -} -void timerDisableReceiveInterrupt() { - TCD0.INTCTRL = 0; -} -#define TIMER_INTR_NAME TCD0_OVF_vect - -void timerConfigForReceive() { - TCD0.CTRLA = 0; // reset enable bit in order to unprotect the other bits - TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc; // must be set since it is used by PWM -// TCD0.CMPBSET = 80; - TCD0.CMPBCLR = ((F_CPU * MICROS_PER_TICK) / MICROS_IN_ONE_SECOND) - 1; - - _PROTECTED_WRITE(TCD0.FAULTCTRL, 0); // must disable WOA output at pin 13/PA4 - - TCD0.INTFLAGS = TCD_OVF_bm; // reset interrupt flags - // check enable ready -// while ((TCD0.STATUS & TCD_ENRDY_bm) == 0); // Wait for Enable Ready to be high - I guess it is not required - // enable timer - this locks the other bits and static registers and activates values in double buffered registers - TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV1_gc; // System clock, no prescale, no synchronization prescaler -} - -# if defined(SEND_PWM_BY_TIMER) -#define IR_SEND_PIN 13 - -void timerEnableSendPWM() { - TCD0.CTRLA = 0; // reset enable bit in order to unprotect the other bits - _PROTECTED_WRITE(TCD0.FAULTCTRL, FUSE_CMPAEN_bm); // enable WOA output at pin 13/PA4 -// _PROTECTED_WRITE(TCD0.FAULTCTRL, FUSE_CMPAEN_bm | FUSE_CMPBEN_bm); // enable WOA + WOB output pins at 13/PA4 + 14/PA5 - TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV1_gc; // System clock, no prescale, no synchronization prescaler -} - -void enableSendPWMByTimer() { - timerEnableSendPWM(); -} -void disableSendPWMByTimer() { - TCD0.CTRLA = 0; // do not disable output, disable complete timer -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); - - const uint16_t tPWMWrapValue = (F_CPU / 1000) / (aFrequencyKHz); // 526,31 for 38 kHz @20 MHz clock - // use one ramp mode and overflow interrupt - TCD0.CTRLA = 0; // reset enable bit in order to unprotect the other bits -// while ((TCD0.STATUS & TCD_ENRDY_bm) == 0); // Wait for Enable Ready to be high - I guess it is not required - TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc; // must be set since it is used by PWM - TCD0.CTRLC = 0; // reset WOx output settings -// TCD0.CMPBSET = 80; - TCD0.CMPBCLR = tPWMWrapValue - 1; - - // Generate duty cycle signal for debugging etc. - TCD0.CMPASET = 0; - TCD0.CMPACLR = (tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT / 100) - 1; // duty cycle for WOA - - TCD0.INTFLAGS = TCD_OVF_bm; // reset interrupt flags - TCD0.INTCTRL = TCD_OVF_bm; // overflow interrupt - // Do not enable timer, this is done at timerEnablSendPWM() -} -# endif // defined(SEND_PWM_BY_TIMER) - -#else -#error Internal code configuration error, no timer functions implemented for this AVR CPU / board -#endif //defined(IR_USE_AVR_TIMER*) -/********************************************************************************************************************** - * End of AVR timers - **********************************************************************************************************************/ - -/********************************************** - * Uno R4 boards - * The FspTimer uses undocumented - **********************************************/ -#elif defined(ARDUINO_ARCH_RENESAS) -#include "FspTimer.h" -FspTimer s50usTimer; - -// Undefine ISR, because we register/call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -// callback method used by timer -void IRTimerInterruptHandlerHelper(timer_callback_args_t __attribute((unused)) *p_args) { - IRReceiveTimerInterruptHandler(); -} -void timerEnableReceiveInterrupt() { -// s50usTimer.enable_overflow_irq(); - s50usTimer.start(); -} -void timerDisableReceiveInterrupt() { -// s50usTimer.disable_overflow_irq(); - s50usTimer.stop(); // May save power -} - -void timerConfigForReceive() { - uint8_t tTimerType = GPT_TIMER; - int8_t tIndex = FspTimer::get_available_timer(tTimerType); // Get first unused channel. Here we need the address of tTimerType - if (tIndex < 0 || tTimerType != GPT_TIMER) { - // here we found no unused GPT channel - tIndex = FspTimer::get_available_timer(tTimerType, true); // true to force use of already used PWM channel. Sets "force_pwm_reserved" if timer found - if (tIndex < 0) { - // If we already get an tIndex < 0 we have an error, but do not know how to handle :-( - return; - } - } - s50usTimer.begin(TIMER_MODE_PERIODIC, tTimerType, tIndex, MICROS_IN_ONE_SECOND / MICROS_PER_TICK, 0.0, - IRTimerInterruptHandlerHelper); - s50usTimer.setup_overflow_irq(); - s50usTimer.open(); // In turn calls R_GPT_Enable() - s50usTimer.stop(); // May save power -} - -# if defined(SEND_PWM_BY_TIMER) -#error PWM generation by hardware not yet implemented for Arduino Uno R4 -// Not yet implemented -void enableSendPWMByTimer() { -} -void disableSendPWMByTimer() { -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { -# if defined(IR_SEND_PIN) -# else -# endif -} -# endif - -/********************************************** - * Teensy 3.0 / Teensy 3.1 / Teensy 3.2 boards - **********************************************/ -#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) - -// Special carrier modulator timer for Teensy 3.0 / Teensy 3.1 / Teensy 3.2 -#define TIMER_REQUIRES_RESET_INTR_PENDING -void timerResetInterruptPending() { - uint8_t tmp __attribute__((unused)) = CMT_MSC; - CMT_CMD2 = 30; -} -void timerEnableReceiveInterrupt() { - NVIC_ENABLE_IRQ(IRQ_CMT); - NVIC_SET_PRIORITY(IRQ_CMT, 48); -} -void timerDisableReceiveInterrupt() { - NVIC_DISABLE_IRQ(IRQ_CMT); -} - -#define TIMER_INTR_NAME cmt_isr -# if defined(ISR) -#undef ISR -# endif -#define ISR(f) void f(void) - -#define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000) -# if F_BUS < 8000000 -#error IRremote requires at least 8 MHz on Teensy 3.x -# endif - -void timerConfigForReceive() { - SIM_SCGC4 |= SIM_SCGC4_CMT; - CMT_PPS = CMT_PPS_DIV - 1; - CMT_CGH1 = 1; - CMT_CGL1 = 1; - CMT_CMD1 = 0; - CMT_CMD2 = 30; - CMT_CMD3 = 0; - CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; - CMT_OC = 0; - CMT_MSC = 0x03; -} - -# if defined(SEND_PWM_BY_TIMER) -#define IR_SEND_PIN 5 - -void enableSendPWMByTimer() { - do { - CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; - } while (0); -} -void disableSendPWMByTimer() { - do { - CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; - } while (0); -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); // TODO really required here? Do we have a common resource for Teensy3.0, 3.1 -# if defined(IR_SEND_PIN) - pinMode(IR_SEND_PIN, OUTPUT); -# else - pinMode(IrSender.sendPin, OUTPUT); -# endif - - SIM_SCGC4 |= SIM_SCGC4_CMT; - SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; - CMT_PPS = CMT_PPS_DIV - 1; - CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((aFrequencyKHz) / 2)) / (aFrequencyKHz); - CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((aFrequencyKHz) / 2)) / (aFrequencyKHz); - CMT_CMD1 = 0; - CMT_CMD2 = 30; - CMT_CMD3 = 0; - CMT_CMD4 = 0; - CMT_OC = 0x60; - CMT_MSC = 0x01; -} -# endif // defined(SEND_PWM_BY_TIMER) - -/*************************************** - * Teensy-LC board - ***************************************/ -#elif defined(__MKL26Z64__) - -// defines for TPM1 timer on Teensy-LC -#define TIMER_REQUIRES_RESET_INTR_PENDING -void timerResetInterruptPending() { - FTM1_SC |= FTM_SC_TOF; -} -void timerEnableReceiveInterrupt() { - NVIC_ENABLE_IRQ(IRQ_FTM1); - NVIC_SET_PRIORITY(IRQ_FTM1, 0); -} -void timerDisableReceiveInterrupt() { - NVIC_DISABLE_IRQ(IRQ_FTM1); -} -#define TIMER_INTR_NAME ftm1_isr -# if defined(ISR) -#undef ISR -# endif -#define ISR(f) void f(void) - -void timerConfigForReceive() { - SIM_SCGC6 |= SIM_SCGC6_TPM1; - FTM1_SC = 0; - FTM1_CNT = 0; - FTM1_MOD = (F_PLL / 40000) - 1; - FTM1_C0V = 0; - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; -} - -# if defined(SEND_PWM_BY_TIMER) -#define IR_SEND_PIN 16 - -void enableSendPWMByTimer() { - FTM1_CNT = 0; - CORE_PIN16_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE; -} -void disableSendPWMByTimer() { - CORE_PIN16_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_SRE; -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); -# if defined(IR_SEND_PIN) - pinMode(IR_SEND_PIN, OUTPUT); -# else - pinMode(IrSender.sendPin, OUTPUT); -# endif - - SIM_SCGC6 |= SIM_SCGC6_TPM1; - FTM1_SC = 0; - FTM1_CNT = 0; - FTM1_MOD = ((F_PLL / 2000) / aFrequencyKHz) - 1; - FTM1_C0V = ((F_PLL / 6000) / aFrequencyKHz) - 1; - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); -} -# endif // defined(SEND_PWM_BY_TIMER) - -/*************************************** - * Teensy 4.0, 4.1, MicroMod boards - ***************************************/ -#elif defined(__IMXRT1062__) -// forward declare ISR function (will be implemented by IRReceive.hpp) -void pwm1_3_isr(); - -// defines for FlexPWM1 timer on Teensy 4 -#define TIMER_REQUIRES_RESET_INTR_PENDING -void timerResetInterruptPending() { - FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF; -} -void timerEnableReceiveInterrupt() { - attachInterruptVector(IRQ_FLEXPWM1_3, pwm1_3_isr); - FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF; - FLEXPWM1_SM3INTEN = FLEXPWM_SMINTEN_RIE; - NVIC_ENABLE_IRQ (IRQ_FLEXPWM1_3), NVIC_SET_PRIORITY(IRQ_FLEXPWM1_3, 48); -} -void timerDisableReceiveInterrupt() { - NVIC_DISABLE_IRQ (IRQ_FLEXPWM1_3); -} -#define TIMER_INTR_NAME pwm1_3_isr -# if defined(ISR) -#undef ISR -# endif -#define ISR(f) void (f)(void) - -void timerConfigForReceive() { - uint32_t period = (float) F_BUS_ACTUAL * (float) (MICROS_PER_TICK) * 0.0000005f; - uint32_t prescale = 0; - while (period > 32767) { - period = period >> 1; - if (prescale < 7) - prescale++; - } - FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8); - FLEXPWM1_FSTS0 = 0x0008; - FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8); - FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP; - FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale); - FLEXPWM1_SM3INIT = -period; - FLEXPWM1_SM3VAL0 = 0; - FLEXPWM1_SM3VAL1 = period; - FLEXPWM1_SM3VAL2 = 0; - FLEXPWM1_SM3VAL3 = 0; - FLEXPWM1_SM3VAL4 = 0; - FLEXPWM1_SM3VAL5 = 0; - FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8); -} - -# if defined(SEND_PWM_BY_TIMER) -#define IR_SEND_PIN 7 -void enableSendPWMByTimer() { - FLEXPWM1_OUTEN |= FLEXPWM_OUTEN_PWMA_EN(8); - IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 6; -} - -void disableSendPWMByTimer() { - IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 5; - FLEXPWM1_OUTEN &= ~FLEXPWM_OUTEN_PWMA_EN(8); -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); -# if defined(IR_SEND_PIN) - pinMode(IR_SEND_PIN, OUTPUT); -# else - pinMode(IrSender.sendPin, OUTPUT); -# endif - - uint32_t period = (float) F_BUS_ACTUAL / (float) ((aFrequencyKHz) * 2000); - uint32_t prescale = 0; - while (period > 32767) { - period = period >> 1; - if (prescale < 7) - prescale++; - } - FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8); - FLEXPWM1_FSTS0 = 0x0008; - FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8); - FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP; - FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale); - FLEXPWM1_SM3INIT = -period; - FLEXPWM1_SM3VAL0 = 0; - FLEXPWM1_SM3VAL1 = period; - FLEXPWM1_SM3VAL2 = -(period / 3); - FLEXPWM1_SM3VAL3 = period / 3; - FLEXPWM1_SM3VAL4 = 0; - FLEXPWM1_SM3VAL5 = 0; - FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8); -} -# endif // defined(SEND_PWM_BY_TIMER) - -#elif defined(ESP8266) -# if defined(SEND_PWM_BY_TIMER) -#error "No support for hardware PWM generation for ESP8266" -# endif // defined(SEND_PWM_BY_TIMER) - -// Undefine ISR, because we register/call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -void timerEnableReceiveInterrupt() { - timer1_attachInterrupt(&IRReceiveTimerInterruptHandler); // enables interrupt too -} -void timerDisableReceiveInterrupt() { - timer1_detachInterrupt(); // disables interrupt too } -} - -void timerConfigForReceive() { - timer1_isr_init(); - /* - * TIM_DIV1 = 0, //80MHz (80 ticks/us - 104857.588 us max) - * TIM_DIV16 = 1, //5MHz (5 ticks/us - 1677721.4 us max) - * TIM_DIV256 = 3 //312.5Khz (1 tick = 3.2us - 26843542.4 us max) - */ - timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP); - timer1_write((80 / 16) * MICROS_PER_TICK); // 80 for 80 and 160! MHz clock, 16 for TIM_DIV16 above -} - -/********************************************************** - * ESP32 boards - can use any pin for send PWM - * Receive timer and send generation are independent, - * so it is recommended to always define SEND_PWM_BY_TIMER - **********************************************************/ -#elif defined(ESP32) -// Variables specific to the ESP32. -// the ledc functions behave like hardware timers for us :-), so we do not require our own soft PWM generation code. -hw_timer_t *s50usTimer = NULL; // set by timerConfigForReceive() - - -# if !defined(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL) -#define SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL 0 // The channel used for PWM 0 to 7 are high speed PWM channels -# endif - -void timerEnableReceiveInterrupt() { - timerAlarmEnable(s50usTimer); -} - -#if !defined(ESP_ARDUINO_VERSION) -#define ESP_ARDUINO_VERSION 0 -#endif -#if !defined(ESP_ARDUINO_VERSION_VAL) -#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 202 -#endif -#if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(2, 0, 2) -void timerDisableReceiveInterrupt() { - if (s50usTimer != NULL) { - timerDetachInterrupt(s50usTimer); - timerEnd(s50usTimer); - } -} -#else -void timerDisableReceiveInterrupt() { - if (s50usTimer != NULL) { - timerAlarmDisable(s50usTimer); - } -} -#endif - -// Undefine ISR, because we register/call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -void timerConfigForReceive() { - // ESP32 has a proper API to setup timers, no weird chip macros needed - // simply call the readable API versions :) - // 3 timers, choose #1, 80 divider for microsecond precision @80MHz clock, count_up = true - if(s50usTimer == NULL) { - s50usTimer = timerBegin(1, 80, true); - timerAttachInterrupt(s50usTimer, &IRReceiveTimerInterruptHandler, false); // false -> level interrupt, true -> edge interrupt, but this is not supported :-( - timerAlarmWrite(s50usTimer, MICROS_PER_TICK, true); - } - // every 50 us, autoreload = true -} - -# if defined(SEND_PWM_BY_TIMER) -void enableSendPWMByTimer() { - ledcWrite(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL, (IR_SEND_DUTY_CYCLE_PERCENT * 256) / 100); // * 256 since we have 8 bit resolution -} -void disableSendPWMByTimer() { - ledcWrite(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL, 0); -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * ledcWrite since ESP 2.0.2 does not work if pin mode is set. Disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - ledcSetup(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL, aFrequencyKHz * 1000, 8); // 8 bit PWM resolution -# if defined(IR_SEND_PIN) - ledcAttachPin(IR_SEND_PIN, SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL); // bind pin to channel -# else - ledcAttachPin(IrSender.sendPin, SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL); // bind pin to channel -# endif -} -# endif // defined(SEND_PWM_BY_TIMER) - -/*************************************** - * SAMD boards like DUE and Zero - ***************************************/ -#elif defined(ARDUINO_ARCH_SAMD) -# if defined(SEND_PWM_BY_TIMER) -#error PWM generation by hardware is not yet implemented for SAMD -# endif - -# if !defined(IR_SAMD_TIMER) -# if defined(__SAMD51__) -#define IR_SAMD_TIMER TC5 -#define IR_SAMD_TIMER_IRQ TC5_IRQn -# else -// SAMD21 -#define IR_SAMD_TIMER TC3 -#define IR_SAMD_TIMER_ID GCLK_CLKCTRL_ID_TCC2_TC3 -#define IR_SAMD_TIMER_IRQ TC3_IRQn -# endif -# endif - -void timerEnableReceiveInterrupt() { - NVIC_EnableIRQ (IR_SAMD_TIMER_IRQ); -} -void timerDisableReceiveInterrupt() { - NVIC_DisableIRQ (IR_SAMD_TIMER_IRQ); // or TC5->INTENCLR.bit.MC0 = 1; or TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE; - -} -// Undefine ISR, because we call the plain function IRReceiveTimerInterruptHandler() -// The ISR is now TC3_Handler() or TC5_Handler() below -# if defined(ISR) -#undef ISR -# endif - -/** - * Adafruit M4 code (cores/arduino/startup.c) configures these clock generators: - * GCLK0 = F_CPU - * GCLK2 = 100 MHz - * GCLK1 = 48 MHz // This Clock is present in SAMD21 and SAMD51 - * GCLK4 = 12 MHz - * GCLK3 = XOSC32K - */ -void timerConfigForReceive() { - TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER; - -# if defined(__SAMD51__) - // Enable the TC5 clock, use generic clock generator 0 (F_CPU) for TC5 - GCLK->PCHCTRL[TC5_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); - - // The TC should be disabled before the TC is reset in order to avoid undefined behavior. - TC->CTRLA.reg &= ~TC_CTRLA_ENABLE; // Disable the Timer - while (TC->SYNCBUSY.bit.ENABLE) - ; // Wait for disabled - // Reset TCx - TC->CTRLA.reg = TC_CTRLA_SWRST; - // When writing a '1' to the CTRLA.SWRST bit it will immediately read as '1'. - while (TC->SYNCBUSY.bit.SWRST) - ; // CTRL.SWRST will be cleared by hardware when the peripheral has been reset. - - // SAMD51 has F_CPU = 120 MHz - TC->CC[0].reg = ((MICROS_PER_TICK * (F_CPU / MICROS_IN_ONE_SECOND)) / 16) - 1; // (375 - 1); - - /* - * Set timer counter mode to 16 bits, set mode as match frequency, prescaler is DIV16 => 7.5 MHz clock, start counter - */ - TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_WAVE_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE; -// while (TC5->COUNT16.STATUS.bit.SYNCBUSY == 1); // The next commands do an implicit wait :-) -# else - // Enable GCLK and select GCLK0 (F_CPU) as clock for TC4 and TC5 - REG_GCLK_CLKCTRL = (uint16_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | IR_SAMD_TIMER_ID); - while (GCLK->STATUS.bit.SYNCBUSY == 1) - ; - - // The TC should be disabled before the TC is reset in order to avoid undefined behavior. - TC->CTRLA.reg &= ~TC_CTRLA_ENABLE; - // When write-synchronization is ongoing for a register, any subsequent write attempts to this register will be discarded, and an error will be reported. - while (TC->STATUS.bit.SYNCBUSY == 1) - ; // wait for sync to ensure that we can write again to COUNT16.CTRLA.reg - // Reset TCx - TC->CTRLA.reg = TC_CTRLA_SWRST; - // When writing a 1 to the CTRLA.SWRST bit it will immediately read as 1. - while (TC->CTRLA.bit.SWRST) - ; // CTRL.SWRST will be cleared by hardware when the peripheral has been reset. - - // SAMD51 has F_CPU = 48 MHz - TC->CC[0].reg = ((MICROS_PER_TICK * (F_CPU / MICROS_IN_ONE_SECOND)) / 16) - 1; // (150 - 1); - - /* - * Set timer counter mode to 16 bits, set mode as match frequency, prescaler is DIV16 => 3 MHz clock, start counter - */ - TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE; - -# endif - // Configure interrupt request - NVIC_DisableIRQ (IR_SAMD_TIMER_IRQ); - NVIC_ClearPendingIRQ(IR_SAMD_TIMER_IRQ); - NVIC_SetPriority(IR_SAMD_TIMER_IRQ, 0); - NVIC_EnableIRQ(IR_SAMD_TIMER_IRQ); - - // Enable the compare interrupt - TC->INTENSET.bit.MC0 = 1; -} - -# if !defined(DISABLE_CODE_FOR_RECEIVER) -# if defined(__SAMD51__) -void TC5_Handler(void) { - TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER; - // Check for right interrupt bit - if (TC->INTFLAG.bit.MC0 == 1) { - // reset bit for next turn - TC->INTFLAG.bit.MC0 = 1; - IRReceiveTimerInterruptHandler(); - } -} -# else -void TC3_Handler(void) { - TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER; - // Check for right interrupt bit - if (TC->INTFLAG.bit.MC0 == 1) { - // reset bit for next turn - TC->INTFLAG.bit.MC0 = 1; - IRReceiveTimerInterruptHandler(); - } -} -# endif // defined(__SAMD51__) -# endif // !defined(DISABLE_CODE_FOR_RECEIVER) - -/*************************************** - * Mbed based boards - ***************************************/ -#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE + Sparkfun Apollo3 + Nano RP2040 Connect -#include "mbed.h" -mbed::Ticker s50usTimer; - -// Undefine ISR, because we register/call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -void timerEnableReceiveInterrupt() { - s50usTimer.attach(IRReceiveTimerInterruptHandler, std::chrono::microseconds(MICROS_PER_TICK)); -} -void timerDisableReceiveInterrupt() { - s50usTimer.detach(); -} - -void timerConfigForReceive() { - s50usTimer.attach(IRReceiveTimerInterruptHandler, std::chrono::microseconds(MICROS_PER_TICK)); -} - -# if defined(SEND_PWM_BY_TIMER) -#include "pins_arduino.h" // for digitalPinToPinName() - -# if defined(IR_SEND_PIN) -mbed::PwmOut sPwmOutForSendPWM(digitalPinToPinName(IR_SEND_PIN)); -# else -mbed::PwmOut sPwmOutForSendPWM(digitalPinToPinName(IrSender.sendPin)); -# endif -uint8_t sIROutPuseWidth; - -void enableSendPWMByTimer() { - sPwmOutForSendPWM.pulsewidth_us(sIROutPuseWidth); -} -//void enableSendPWMByTimer() { sPwmOutForSendPWM.resume(); sPwmOutForSendPWM.pulsewidth_us(sIROutPuseWidth);} -//void disableSendPWMByTimer() { sPwmOutForSendPWM.suspend();} // this kills pulsewidth_us value and does not set output level to LOW - -void disableSendPWMByTimer() { - sPwmOutForSendPWM.pulsewidth_us(0); // this also sets output level to LOW :-) -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - sPwmOutForSendPWM.period_us(1000 / aFrequencyKHz); // 26.315 for 38 kHz - sIROutPuseWidth = (1000 * IR_SEND_DUTY_CYCLE_PERCENT) / (aFrequencyKHz * 100); -} -# endif // defined(SEND_PWM_BY_TIMER) - -/************************************************************************************************************************************* - * RP2040 based boards for pico core - * https://github.com/earlephilhower/arduino-pico - * https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json - * Can use any pin for PWM, no timer restrictions - *************************************************************************************************************************************/ -#elif defined(ARDUINO_ARCH_RP2040) // Raspberry Pi Pico, Adafruit Feather RP2040, etc. -#include "pico/time.h" - -repeating_timer_t s50usTimer; - -// Undefine ISR, because we register/call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -// The timer callback has a parameter and a return value -bool IRTimerInterruptHandlerHelper(repeating_timer_t*) { - IRReceiveTimerInterruptHandler(); - return true; -} - -void timerEnableReceiveInterrupt() { - add_repeating_timer_us(-(MICROS_PER_TICK), IRTimerInterruptHandlerHelper, NULL, &s50usTimer); -} -void timerDisableReceiveInterrupt() { - cancel_repeating_timer(&s50usTimer); -} - -void timerConfigForReceive() { - // no need for initializing timer at setup() -} - -# if defined(SEND_PWM_BY_TIMER) -#include "hardware/pwm.h" - -uint sSliceNumberForSendPWM; -uint sChannelNumberForSendPWM; -uint sIROutPuseWidth; - -/* - * If we just disable the PWM, the counter stops and the output stays at the state is currently has - */ -void enableSendPWMByTimer() { - pwm_set_counter(sSliceNumberForSendPWM, 0); - pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, sIROutPuseWidth); -} -void disableSendPWMByTimer() { - pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, 0); // this sets output also to LOW -} - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { -# if defined(IR_SEND_PIN) - gpio_set_function(IR_SEND_PIN, GPIO_FUNC_PWM); - // Find out which PWM slice is connected to IR_SEND_PIN - sSliceNumberForSendPWM = pwm_gpio_to_slice_num(IR_SEND_PIN); - sChannelNumberForSendPWM = pwm_gpio_to_channel(IR_SEND_PIN); -# else - gpio_set_function(IrSender.sendPin, GPIO_FUNC_PWM); - // Find out which PWM slice is connected to IR_SEND_PIN - sSliceNumberForSendPWM = pwm_gpio_to_slice_num(IrSender.sendPin); - sChannelNumberForSendPWM = pwm_gpio_to_channel(IrSender.sendPin); -# endif - uint16_t tPWMWrapValue = (clock_get_hz(clk_sys)) / (aFrequencyKHz * 1000); // 3289.473 for 38 kHz @125 MHz clock. We have a 16 bit counter and use system clock (125 MHz) - - pwm_config tPWMConfig = pwm_get_default_config(); - pwm_config_set_wrap(&tPWMConfig, tPWMWrapValue - 1); - pwm_init(sSliceNumberForSendPWM, &tPWMConfig, false); // we do not want to send now - sIROutPuseWidth = ((tPWMWrapValue * IR_SEND_DUTY_CYCLE_PERCENT) / 100) - 1; // 985.84 for 38 kHz - pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, 0); - pwm_set_enabled(sSliceNumberForSendPWM, true); -} -# endif // defined(SEND_PWM_BY_TIMER) - -/*************************************** - * NRF5 boards like the BBC:Micro - ***************************************/ -#elif defined(NRF5) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52) -# if defined(SEND_PWM_BY_TIMER) -#error PWM generation by hardware not implemented for NRF5 -# endif - -void timerEnableReceiveInterrupt() { - NVIC_EnableIRQ (TIMER2_IRQn); -} -void timerDisableReceiveInterrupt() { - NVIC_DisableIRQ (TIMER2_IRQn); -} - -// Undefine ISR, because we call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -void timerConfigForReceive() { - NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; // Set the timer in Timer Mode - NRF_TIMER2->TASKS_CLEAR = 1; // clear the task first to be usable for later - NRF_TIMER2->PRESCALER = 4; // f TIMER = 16 MHz / (2 ^ PRESCALER ) : 4 -> 1 MHz, 1 uS - NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //Set counter to 16 bit resolution - NRF_TIMER2->CC[0] = MICROS_PER_TICK; //Set value for TIMER2 compare register 0, to trigger every 50 uS - NRF_TIMER2->CC[1] = 0; //Set value for TIMER2 compare register 1 - - // Enable interrupt on Timer 2, for CC[0] compare match events - NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos); - NRF_TIMER2->TASKS_START = 1; // Start TIMER2 - - // timerAttachInterrupt(timer, &IRTimerInterruptHandler, 1); -} - -#if !defined(DISABLE_CODE_FOR_RECEIVER) -/** TIMTER2 peripheral interrupt handler. This interrupt handler is called whenever there it a TIMER2 interrupt - * Don't mess with this line. really. - */ -extern "C" { -void TIMER2_IRQHandler(void) { - // Interrupt Service Routine - Fires every 50uS - if ((NRF_TIMER2->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0)) { - NRF_TIMER2->EVENTS_COMPARE[0] = 0; //Clear compare register 0 event - IRReceiveTimerInterruptHandler(); // call the IR-receive function - NRF_TIMER2->CC[0] += 50; - } -} -} -#endif - -/********************************************************************************************************************** - * BluePill in 2 flavors see https://samuelpinches.com.au/3d-printer/cutting-through-some-confusion-on-stm32-and-arduino/ - * - * Recommended original Arduino_STM32 by Roger Clark. - * http://dan.drown.org/stm32duino/package_STM32duino_index.json - * STM32F1 architecture for "Generic STM32F103C series" from "STM32F1 Boards (Arduino_STM32)" of Arduino Board manager - **********************************************************************************************************************/ -#elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1) -#include <HardwareTimer.h> // 4 timers and 4. timer (4.channel) is used for tone() -# if defined(SEND_PWM_BY_TIMER) -#error PWM generation by hardware not implemented for STM32 -# endif - -/* - * Use timer 3 as IR timer. - * Timer 3 blocks PA6, PA7, PB0, PB1, so if you require one of them as tone() or Servo output, you must choose another timer. - */ -HardwareTimer s50usTimer(3); - -void timerEnableReceiveInterrupt() { - s50usTimer.resume(); -} -void timerDisableReceiveInterrupt() { - s50usTimer.pause(); -} - -// Undefine ISR, because we register/call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -void timerConfigForReceive() { - s50usTimer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); - s50usTimer.setPrescaleFactor(1); - s50usTimer.setOverflow((F_CPU / MICROS_IN_ONE_SECOND) * MICROS_PER_TICK); - s50usTimer.attachInterrupt(TIMER_CH1, IRReceiveTimerInterruptHandler); - s50usTimer.refresh(); -} - -/********************************************************************************************************************** - * STM32duino by ST Microsystems. - * https://github.com/stm32duino/Arduino_Core_STM32 - * https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json - * stm32 architecture for "Generic STM32F1 series" from "STM32 Boards (selected from submenu)" of Arduino Board manager - **********************************************************************************************************************/ -#elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32) -#include <HardwareTimer.h> // 4 timers and 3. timer is used for tone(), 2. for Servo -# if defined(SEND_PWM_BY_TIMER) -#error PWM generation by hardware not implemented for STM32 -# endif - -/* - * Use timer 4 as IR timer. - * Timer 4 blocks PB6, PB7, PB8, PB9, so if you need one them as tone() or Servo output, you must choose another timer. - */ -# if defined(TIM4) -HardwareTimer s50usTimer(TIM4); -# else -HardwareTimer s50usTimer(TIM2); -# endif - -void timerEnableReceiveInterrupt() { - s50usTimer.resume(); -} -void timerDisableReceiveInterrupt() { - s50usTimer.pause(); -} - -// Undefine ISR, because we register/call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -void timerConfigForReceive() { - s50usTimer.setOverflow(MICROS_PER_TICK, MICROSEC_FORMAT); // 50 uS - s50usTimer.attachInterrupt(IRReceiveTimerInterruptHandler); - s50usTimer.resume(); -} - -/*************************************** - * Particle special IntervalTimer - * !!!UNTESTED!!! - ***************************************/ -#elif defined(PARTICLE) -# ifndef __INTERVALTIMER_H__ -#include "SparkIntervalTimer.h" // SparkIntervalTimer.h is required if PARTICLE is defined. -# endif - -extern IntervalTimer timer; -extern int ir_out_kHz; - -void timerEnableReceiveInterrupt() { - timer.begin(IRReceiveTimerInterruptHandler, MICROS_PER_TICK, uSec); -} -void timerDisableReceiveInterrupt() { - timer.end(); -} - -// Undefine ISR, because we register/call the plain function IRReceiveTimerInterruptHandler() -# if defined(ISR) -#undef ISR -# endif - -void timerConfigForReceive() { -} - -# if defined(SEND_PWM_BY_TIMER) -# if defined(IR_SEND_PIN) -void enableSendPWMByTimer() { - analogWrite(IR_SEND_PIN, ((256L * 100) / IR_SEND_DUTY_CYCLE_PERCENT)), ir_out_kHz*1000); -} -void disableSendPWMByTimer() { - analogWrite(IR_SEND_PIN, 0, ir_out_kHz*1000); -} -# else -void enableSendPWMByTimer() { - analogWrite(IrSender.sendPin, ((256L * 100) / IR_SEND_DUTY_CYCLE_PERCENT), ir_out_kHz * 1000); -} -void disableSendPWMByTimer() { - analogWrite(IrSender.sendPin, 0, ir_out_kHz * 1000); -} -# endif - - -/* - * timerConfigForSend() is used exclusively by IRsend::enableIROut() - * Set output pin mode and disable receive interrupt if it uses the same resource - */ -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); -# if defined(IR_SEND_PIN) - pinMode(IR_SEND_PIN, OUTPUT); -# else - pinMode(IrSender.sendPin, OUTPUT); -# endif - ir_out_kHz = aFrequencyKHz; -} -# endif // defined(SEND_PWM_BY_TIMER) - -/*************************************** - * Unknown CPU board - ***************************************/ -#else -#error Internal code configuration error, no timer functions implemented for this CPU / board -/* - * Dummy definitions to avoid more irritating compile errors - */ - -void timerEnableReceiveInterrupt() {}; -void timerDisableReceiveInterrupt() {}; - -# if defined(ISR) -#undef ISR -# endif -#define ISR() void notImplemented(void) - -void timerConfigForReceive() { -} - -# if defined(SEND_PWM_BY_TIMER) -void enableSendPWMByTimer() { -} -void disableSendPWMByTimer() { -} - -void timerConfigForSend(uint16_t aFrequencyKHz) { - timerDisableReceiveInterrupt(); -# if defined(IR_SEND_PIN) - pinMode(IR_SEND_PIN, OUTPUT); -# else - pinMode(IrSender.sendPin, OUTPUT); -# endif - (void) aFrequencyKHz; -} -# endif // defined(SEND_PWM_BY_TIMER) - -#endif // defined(DOXYGEN / CPU_TYPES) - -/** @}*/ -/** @}*/ -#endif // _IR_TIMER_HPP diff --git a/PinChangeInt/.DS_Store b/PinChangeInt/.DS_Store deleted file mode 100644 index f361e35edc3e5c814c76195d7f342bc27b42bb5f..0000000000000000000000000000000000000000 Binary files a/PinChangeInt/.DS_Store and /dev/null differ diff --git a/PinChangeInt/PinChangeInt.h b/PinChangeInt/PinChangeInt.h deleted file mode 100644 index 3ca05a5cd09ad010bb40a2f319e5dc18ea81875d..0000000000000000000000000000000000000000 --- a/PinChangeInt/PinChangeInt.h +++ /dev/null @@ -1,439 +0,0 @@ -#define PCINT_VERSION 2402 -#define detachPinChangeInterrupt(pin) PCintPort::detachInterrupt(pin) -#define attachPinChangeInterrupt(pin,userFunc,mode) PCintPort::attachInterrupt(pin, &userFunc,mode) -#define getInterruptedPin() PCintPort::getArduinoPin() -#ifndef PinChangeInt_h -#define PinChangeInt_h -#include "stddef.h" -#include <Arduino.h> -#include <new.h> -#include <wiring_private.h> -#undef DEBUG -#undef INLINE_PCINT -#define INLINE_PCINT -#if defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || defined __AVR_ATmega1281__ || defined __AVR_ATmega2561__ || defined __AVR_ATmega640__ - #define __USE_PORT_JK - #define NO_PORTA_PINCHANGES - #define NO_PORTC_PINCHANGES - #define NO_PORTD_PINCHANGES - #if ((defined(NO_PORTB_PINCHANGES) && defined(NO_PORTJ_PINCHANGES)) || \ - (defined(NO_PORTJ_PINCHANGES) && defined(NO_PORTK_PINCHANGES)) || \ - (defined(NO_PORTK_PINCHANGES) && defined(NO_PORTB_PINCHANGES))) - #define INLINE_PCINT inline - #endif -#else - #define NO_PORTJ_PINCHANGES - #define NO_PORTK_PINCHANGES - #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) - #ifndef NO_PORTA_PINCHANGES - #define __USE_PORT_A - #endif - #else - #define NO_PORTA_PINCHANGES - #endif - #if ( (defined(NO_PORTA_PINCHANGES) && defined(NO_PORTB_PINCHANGES) && defined(NO_PORTC_PINCHANGES)) || \ - (defined(NO_PORTA_PINCHANGES) && defined(NO_PORTB_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) || \ - (defined(NO_PORTA_PINCHANGES) && defined(NO_PORTC_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) || \ - (defined(NO_PORTB_PINCHANGES) && defined(NO_PORTC_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) ) - #define INLINE_PCINT inline - #endif -#endif -#define PCdetachInterrupt(pin) PCintPort::detachInterrupt(pin) -#define PCattachInterrupt(pin,userFunc,mode) PCintPort::attachInterrupt(pin, userFunc,mode) -#define PCgetArduinoPin() PCintPort::getArduinoPin() -typedef void (*PCIntvoidFuncPtr)(void); -class PCintPort { -public: - PCintPort(int index,int pcindex, volatile uint8_t& maskReg) : - portInputReg(*portInputRegister(index)), - portPCMask(maskReg), - PCICRbit(1 << pcindex), - portRisingPins(0), - portFallingPins(0), - firstPin(NULL) -#ifdef PINMODE - ,intrCount(0) -#endif - { - #ifdef FLASH - ledsetup(); - #endif - } - volatile uint8_t& portInputReg; - static int8_t attachInterrupt(uint8_t pin, PCIntvoidFuncPtr userFunc, int mode); - static void detachInterrupt(uint8_t pin); - INLINE_PCINT void PCint(); - static volatile uint8_t curr; - #ifndef NO_PIN_NUMBER - static volatile uint8_t arduinoPin; - #endif - #ifndef NO_PIN_STATE - static volatile uint8_t pinState; - #endif - #ifdef PINMODE - static volatile uint8_t pinmode; - static volatile uint8_t s_portRisingPins; - static volatile uint8_t s_portFallingPins; - static volatile uint8_t s_lastPinView; - static volatile uint8_t s_pmask; - static volatile char s_PORT; - static volatile uint8_t s_changedPins; - static volatile uint8_t s_portRisingPins_nCurr; - static volatile uint8_t s_portFallingPins_nNCurr; - static volatile uint8_t s_currXORlastPinView; - volatile uint8_t intrCount; - static volatile uint8_t s_count; - static volatile uint8_t pcint_multi; - static volatile uint8_t PCIFRbug; - #endif - #ifdef FLASH - static void ledsetup(void); - #endif -protected: - class PCintPin { - public: - PCintPin() : - PCintFunc((PCIntvoidFuncPtr)NULL), - mode(0) {} - PCIntvoidFuncPtr PCintFunc; - uint8_t mode; - uint8_t mask; - uint8_t arduinoPin; - PCintPin* next; - }; - void enable(PCintPin* pin, PCIntvoidFuncPtr userFunc, uint8_t mode); - int8_t addPin(uint8_t arduinoPin,PCIntvoidFuncPtr userFunc, uint8_t mode); - volatile uint8_t& portPCMask; - const uint8_t PCICRbit; - volatile uint8_t portRisingPins; - volatile uint8_t portFallingPins; - volatile uint8_t lastPinView; - PCintPin* firstPin; -}; -#ifndef LIBCALL_PINCHANGEINT -volatile uint8_t PCintPort::curr=0; -#ifndef NO_PIN_NUMBER -volatile uint8_t PCintPort::arduinoPin=0; -#endif -#ifndef NO_PIN_STATE -volatile uint8_t PCintPort::pinState=0; -#endif -#ifdef PINMODE -volatile uint8_t PCintPort::pinmode=0; -volatile uint8_t PCintPort::s_portRisingPins=0; -volatile uint8_t PCintPort::s_portFallingPins=0; -volatile uint8_t PCintPort::s_lastPinView=0; -volatile uint8_t PCintPort::s_pmask=0; -volatile char PCintPort::s_PORT='x'; -volatile uint8_t PCintPort::s_changedPins=0; -volatile uint8_t PCintPort::s_portRisingPins_nCurr=0; -volatile uint8_t PCintPort::s_portFallingPins_nNCurr=0; -volatile uint8_t PCintPort::s_currXORlastPinView=0; -volatile uint8_t PCintPort::s_count=0; -volatile uint8_t PCintPort::pcint_multi=0; -volatile uint8_t PCintPort::PCIFRbug=0; -#endif -#ifdef FLASH -#define PINLED 13 -volatile uint8_t *led_port; -uint8_t led_mask; -uint8_t not_led_mask; -boolean ledsetup_run=false; -void PCintPort::ledsetup(void) { - if (! ledsetup_run) { - led_port=portOutputRegister(digitalPinToPort(PINLED)); - led_mask=digitalPinToBitMask(PINLED); - not_led_mask=led_mask^0xFF; - pinMode(PINLED, OUTPUT); digitalWrite(PINLED, LOW); - ledsetup_run=true; - } -}; -#endif -#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -#ifndef NO_PORTA_PINCHANGES -PCintPort portA=PCintPort(1, 0,PCMSK0); -#endif -#ifndef NO_PORTB_PINCHANGES -PCintPort portB=PCintPort(2, 1,PCMSK1); -#endif -#ifndef NO_PORTC_PINCHANGES -PCintPort portC=PCintPort(3, 2,PCMSK2); -#endif -#ifndef NO_PORTD_PINCHANGES -PCintPort portD=PCintPort(4, 3,PCMSK3); -#endif -#else -#ifndef NO_PORTB_PINCHANGES -PCintPort portB=PCintPort(2, 0,PCMSK0); -#endif -#ifndef NO_PORTC_PINCHANGES -PCintPort portC=PCintPort(3, 1,PCMSK1); -#endif -#ifndef NO_PORTD_PINCHANGES -PCintPort portD=PCintPort(4, 2,PCMSK2); -#endif -#endif -#ifdef __USE_PORT_JK -#ifndef NO_PORTJ_PINCHANGES -PCintPort portJ=PCintPort(10,1,PCMSK1); -#endif -#ifndef NO_PORTK_PINCHANGES -PCintPort portK=PCintPort(11,2,PCMSK2); -#endif -#endif -static PCintPort *lookupPortNumToPort( int portNum ) { - PCintPort *port = NULL; - switch (portNum) { -#ifndef NO_PORTA_PINCHANGES - case 1: - port=&portA; - break; -#endif -#ifndef NO_PORTB_PINCHANGES - case 2: - port=&portB; - break; -#endif -#ifndef NO_PORTC_PINCHANGES - case 3: - port=&portC; - break; -#endif -#ifndef NO_PORTD_PINCHANGES - case 4: - port=&portD; - break; -#endif -#ifdef __USE_PORT_JK -#ifndef NO_PORTJ_PINCHANGES - case 10: - port=&portJ; - break; -#endif -#ifndef NO_PORTK_PINCHANGES - case 11: - port=&portK; - break; -#endif -#endif - } - return port; -} -void PCintPort::enable(PCintPin* p, PCIntvoidFuncPtr userFunc, uint8_t mode) { - p->mode=mode; - p->PCintFunc=userFunc; -#ifndef NO_PORTJ_PINCHANGES - if ((p->arduinoPin == 14) || (p->arduinoPin == 15)) { - portPCMask |= (p->mask << 1); - } - else { - portPCMask |= p->mask; - } -#else - portPCMask |= p->mask; -#endif - if ((p->mode == RISING) || (p->mode == CHANGE)) portRisingPins |= p->mask; - if ((p->mode == FALLING) || (p->mode == CHANGE)) portFallingPins |= p->mask; - PCICR |= PCICRbit; -} -int8_t PCintPort::addPin(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, uint8_t mode) -{ - PCintPin* tmp; - tmp=firstPin; - if (firstPin != NULL) { - do { - if (tmp->arduinoPin == arduinoPin) { enable(tmp, userFunc, mode); return(0); } - if (tmp->next == NULL) break; - tmp=tmp->next; - } while (true); - } - PCintPin* p=new PCintPin; - if (p == NULL) return(-1); - p->arduinoPin=arduinoPin; - p->mode = mode; - p->next=NULL; - p->mask = digitalPinToBitMask(arduinoPin); - if (firstPin == NULL) firstPin=p; - else tmp->next=p; -#ifdef DEBUG - Serial.print("addPin. pin given: "); Serial.print(arduinoPin, DEC); - int addr = (int) p; - Serial.print(" instance addr: "); Serial.println(addr, HEX); - Serial.print("userFunc addr: "); Serial.println((int)p->PCintFunc, HEX); -#endif - enable(p, userFunc, mode); -#ifdef DEBUG - Serial.print("addPin. pin given: "); Serial.print(arduinoPin, DEC), Serial.print (" pin stored: "); - int addr = (int) p; - Serial.print(" instance addr: "); Serial.println(addr, HEX); -#endif - return(1); -} -int8_t PCintPort::attachInterrupt(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, int mode) -{ - PCintPort *port; - uint8_t portNum = digitalPinToPort(arduinoPin); - if ((portNum == NOT_A_PORT) || (userFunc == NULL)) return(-1); - port=lookupPortNumToPort(portNum); - port->lastPinView=port->portInputReg; -#ifdef DEBUG - Serial.print("attachInterrupt- pin: "); Serial.println(arduinoPin, DEC); -#endif - return(port->addPin(arduinoPin,userFunc,mode)); -} -void PCintPort::detachInterrupt(uint8_t arduinoPin) -{ - PCintPort *port; - PCintPin* current; - uint8_t mask; - uint8_t portNum = digitalPinToPort(arduinoPin); - if (portNum == NOT_A_PORT) return; - port=lookupPortNumToPort(portNum); - mask=digitalPinToBitMask(arduinoPin); - current=port->firstPin; - while (current) { - if (current->mask == mask) { - uint8_t oldSREG = SREG; - cli(); -#ifndef NO_PORTJ_PINCHANGES - if ((arduinoPin == 14) || (arduinoPin == 15)) { - port->portPCMask &= ~(mask << 1); - } - else { - port->portPCMask &= ~mask; - } -#else - port->portPCMask &= ~mask; -#endif - if (port->portPCMask == 0) PCICR &= ~(port->PCICRbit); - port->portRisingPins &= ~current->mask; port->portFallingPins &= ~current->mask; - SREG = oldSREG; - return; - } - current=current->next; - } -} -void PCintPort::PCint() { - #ifdef FLASH - if (*led_port & led_mask) *led_port&=not_led_mask; - else *led_port|=led_mask; - #endif - #ifndef DISABLE_PCINT_MULTI_SERVICE - uint8_t pcifr; - while (true) { - #endif - #ifdef PINMODE - PCintPort::s_lastPinView=lastPinView; - intrCount++; - PCintPort::s_count=intrCount; - #endif - uint8_t changedPins = (PCintPort::curr ^ lastPinView) & - ((portRisingPins & PCintPort::curr ) | ( portFallingPins & ~PCintPort::curr )); - #ifdef PINMODE - PCintPort::s_currXORlastPinView=PCintPort::curr ^ lastPinView; - PCintPort::s_portRisingPins_nCurr=portRisingPins & PCintPort::curr; - PCintPort::s_portFallingPins_nNCurr=portFallingPins & ~PCintPort::curr; - #endif - lastPinView = PCintPort::curr; - PCintPin* p = firstPin; - while (p) { - if (p->mask & changedPins) { - #ifndef NO_PIN_STATE - PCintPort::pinState=PCintPort::curr & p->mask ? HIGH : LOW; - #endif - #ifndef NO_PIN_NUMBER - PCintPort::arduinoPin=p->arduinoPin; - #endif - #ifdef PINMODE - PCintPort::pinmode=p->mode; - PCintPort::s_portRisingPins=portRisingPins; - PCintPort::s_portFallingPins=portFallingPins; - PCintPort::s_pmask=p->mask; - PCintPort::s_changedPins=changedPins; - #endif - p->PCintFunc(); - } - p=p->next; - } - #ifndef DISABLE_PCINT_MULTI_SERVICE - pcifr = PCIFR & PCICRbit; - if (pcifr == 0) break; - PCIFR |= PCICRbit; - #ifdef PINMODE - PCintPort::pcint_multi++; - if (PCIFR & PCICRbit) PCintPort::PCIFRbug=1; - #endif - PCintPort::curr=portInputReg; - } - #endif -} -#ifndef NO_PORTA_PINCHANGES -ISR(PCINT0_vect) { - #ifdef PINMODE - PCintPort::s_PORT='A'; - #endif - PCintPort::curr = portA.portInputReg; - portA.PCint(); -} -#define PORTBVECT PCINT1_vect -#define PORTCVECT PCINT2_vect -#define PORTDVECT PCINT3_vect -#else -#define PORTBVECT PCINT0_vect -#define PORTCVECT PCINT1_vect -#define PORTDVECT PCINT2_vect -#endif -#ifndef NO_PORTB_PINCHANGES -ISR(PORTBVECT) { - #ifdef PINMODE - PCintPort::s_PORT='B'; - #endif - PCintPort::curr = portB.portInputReg; - portB.PCint(); -} -#endif -#ifndef NO_PORTC_PINCHANGES -ISR(PORTCVECT) { - #ifdef PINMODE - PCintPort::s_PORT='C'; - #endif - PCintPort::curr = portC.portInputReg; - portC.PCint(); -} -#endif -#ifndef NO_PORTD_PINCHANGES -ISR(PORTDVECT){ - #ifdef PINMODE - PCintPort::s_PORT='D'; - #endif - PCintPort::curr = portD.portInputReg; - portD.PCint(); -} -#endif -#ifdef __USE_PORT_JK -#ifndef NO_PORTJ_PINCHANGES -ISR(PCINT1_vect) { - #ifdef PINMODE - PCintPort::s_PORT='J'; - #endif - PCintPort::curr = portJ.portInputReg; - portJ.PCint(); -} -#endif -#ifndef NO_PORTK_PINCHANGES -ISR(PCINT2_vect){ - #ifdef PINMODE - PCintPort::s_PORT='K'; - #endif - PCintPort::curr = portK.portInputReg; - portK.PCint(); -} -#endif -#endif -#ifdef GET_PCINT_VERSION -uint16_t getPCIntVersion () { - return ((uint16_t) PCINT_VERSION); -} -#endif -#endif -#endif diff --git a/RF24/CMakeLists.txt b/RF24/CMakeLists.txt deleted file mode 100644 index 6bbb5ebc669a86dce552cd5e88f51c45d3d65735..0000000000000000000000000000000000000000 --- a/RF24/CMakeLists.txt +++ /dev/null @@ -1,172 +0,0 @@ -# Check if we are building a pico-sdk based project -# (or more exactly: if we just got included in a pico-sdk based project) -if (PICO_SDK_PATH) - # If so, load the relevant CMakeLists-file but don't do anything else - include(${CMAKE_CURRENT_LIST_DIR}/utility/rp2/CMakeLists.txt) - return() -endif() - -cmake_minimum_required(VERSION 3.15) - -# Set the project name to your project name -project(RF24 C CXX) -include(${CMAKE_CURRENT_LIST_DIR}/cmake/StandardProjectSettings.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/cmake/PreventInSourceBuilds.cmake) - -# get library info from Arduino IDE's required library.properties file -include(${CMAKE_CURRENT_LIST_DIR}/cmake/GetLibInfo.cmake) - -# allow CMake CLI options to configure RF24_config.h macros -option(SERIAL_DEBUG "enable/disable debugging output" OFF) -option(MINIMAL "exclude optional source code to keep compile size compact" OFF) - -# Link this 'library' to set the c++ standard / compile-time options requested -add_library(${LibTargetName}_project_options INTERFACE) -target_compile_features(${LibTargetName}_project_options INTERFACE cxx_std_17) -add_compile_options(-Ofast -Wall -pthread) - -if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - option(ENABLE_BUILD_WITH_TIME_TRACE "Enable -ftime-trace to generate time tracing .json files on clang" OFF) - if(ENABLE_BUILD_WITH_TIME_TRACE) - add_compile_definitions(${LibTargetName}_project_options INTERFACE -ftime-trace) - endif() -endif() - -# Link this 'library' to use the warnings specified in CompilerWarnings.cmake -add_library(${LibTargetName}_project_warnings INTERFACE) - -# enable cache system -include(${CMAKE_CURRENT_LIST_DIR}/cmake/Cache.cmake) - -# standard compiler warnings -include(${CMAKE_CURRENT_LIST_DIR}/cmake/CompilerWarnings.cmake) -set_project_warnings(${LibTargetName}_project_warnings) - -# sanitizer options if supported by compiler -include(${CMAKE_CURRENT_LIST_DIR}/cmake/Sanitizers.cmake) -enable_sanitizers(${LibTargetName}_project_options) - -# allow for static analysis options -include(${CMAKE_CURRENT_LIST_DIR}/cmake/StaticAnalyzers.cmake) - -option(BUILD_SHARED_LIBS "Enable compilation of shared libraries" OFF) -option(ENABLE_TESTING "Enable Test Builds" OFF) # for end-user projects -option(ENABLE_FUZZING "Enable Fuzzing Builds" OFF) # for end-user projects - -if(ENABLE_TESTING) - enable_testing() - message("Building Tests.") - add_subdirectory(test) # directory doesn't exist, so this does nothing. -endif() - -if(ENABLE_FUZZING) - message("Building Fuzz Tests, using fuzzing sanitizer https://www.llvm.org/docs/LibFuzzer.html") - add_subdirectory(fuzz_test) # directory doesn't exist, so this does nothing. -endif() - -##################################### -### Now we actually build the library -##################################### - -# detect the CPU make and type -include(${CMAKE_CURRENT_LIST_DIR}/cmake/detectCPU.cmake) # sets the variable SOC accordingly - -# auto-detect what driver to use -# auto-detect can be overriden using `cmake .. -D RF24_DRIVER=<supported driver>` -include(${CMAKE_CURRENT_LIST_DIR}/cmake/AutoConfig_RF24_DRIVER.cmake) - -#[[ adding the utility sub-directory will - 1. set variables RF24_DRIVER, RF24_LINKED_DRIVER, and RF24_DRIVER_SOURCES - 2. copy the approriate /utility/*/includes.h file to the /utility folder - 3. set additional install rules according to the RF24_DRIVER specified -]] -add_subdirectory(utility) - -# setup CPack options -# package dependencies are resolved correctly only after utility subdirectory is added -include(${CMAKE_CURRENT_LIST_DIR}/cmake/CPackInfo.cmake) - -add_library(${LibTargetName} SHARED - RF24.cpp - ${RF24_DRIVER_SOURCES} -) - -target_include_directories(${LibTargetName} PUBLIC utility) - -set_target_properties( - ${LibTargetName} - PROPERTIES - SOVERSION ${${LibName}_VERSION_MAJOR} - VERSION ${${LibName}_VERSION_STRING} -) - -if(NOT "${RF24_LINKED_DRIVER}" STREQUAL "") # linking to a pre-compiled utility driver - message(STATUS "Using utility library: ${RF24_LINKED_DRIVER}") - target_link_libraries(${LibTargetName} INTERFACE - ${LibTargetName}_project_options - ${LibTargetName}_project_warnings - STATIC RF24_LINKED_DRIVER - ) -else() # utility driver is compiled with the library - not linking to a pre-compiled utility driver - target_link_libraries(${LibTargetName} INTERFACE - ${LibTargetName}_project_options - ${LibTargetName}_project_warnings - ) -endif() - -# assert the appropriate preprocessor macros for RF24_config.h -if(SERIAL_DEBUG) - message(STATUS "SERIAL_DEBUG asserted") - target_compile_definitions(${LibTargetName} PUBLIC SERIAL_DEBUG) -endif() -if(MINIMAL) - message(STATUS "MINIMAL asserted") - target_compile_definitions(${LibTargetName} PUBLIC MINIMAL) -endif() -# for RF24_POWERUP_DELAY & RF24_SPI_SPEED, let the default be configured in source code -if(DEFINED RF24_POWERUP_DELAY) - message(STATUS "RF24_POWERUP_DELAY set to ${RF24_POWERUP_DELAY}") - target_compile_definitions(${LibTargetName} PUBLIC - RF24_POWERUP_DELAY=${RF24_POWERUP_DELAY} - ) -endif() -if(DEFINED RF24_SPI_SPEED) - message(STATUS "RF24_SPI_SPEED set to ${RF24_SPI_SPEED}") - target_compile_definitions(${LibTargetName} PUBLIC - RF24_SPI_SPEED=${RF24_SPI_SPEED} - ) -endif() -# conditionally disable interruot support (a pigpio specific feature) -if("${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND" OR DEFINED RF24_NO_INTERRUPT) - message(STATUS "Disabling IRQ pin support") - target_compile_definitions(${LibTargetName} PUBLIC RF24_NO_INTERRUPT) -endif() - - -##################################### -### Install rules for root source dir -### There are separate install rules defined for each utility driver -### Installing the library requires sudo privileges -##################################### -install(TARGETS ${LibTargetName} - DESTINATION lib -) - -install(FILES - RF24.h - nRF24L01.h - printf.h - RF24_config.h - DESTINATION include/RF24 -) - -install(FILES - utility/includes.h - DESTINATION include/RF24/utility -) - -# CMAKE_CROSSCOMPILING is only TRUE when CMAKE_TOOLCHAIN_FILE is specified via CLI -if("${CMAKE_CROSSCOMPILING}" STREQUAL "FALSE") - install(CODE "message(STATUS \"Updating ldconfig\")") - install(CODE "execute_process(COMMAND ldconfig)") -endif() diff --git a/RF24/COMMON_ISSUES.md b/RF24/COMMON_ISSUES.md deleted file mode 100644 index 8f455639ca42fbb7b6772c1d7502e377336c7563..0000000000000000000000000000000000000000 --- a/RF24/COMMON_ISSUES.md +++ /dev/null @@ -1,106 +0,0 @@ -# Common Issues - -<!-- markdownlint-disable MD031 --> - -## Settings that must match - -Before you report undesirable behavior, please make sure that the -following RF24 configurations match on both receiving and transmitting -nRF24L01 transceivers: - -1. `RF24::setAddressWidth()` -2. `RF24::setChannel()` -3. `RF24::setDataRate()` -4. `RF24::setAutoAck()` -5. `RF24::enableDynamicPayloads()` or `RF24::disableDynamicPayloads()` -6. `RF24::enableAckPayload()` or `RF24::disableAckPayload()` (requires auto-ack and - dynamic payloads features) -7. `RF24::setPayloadSize()` (only if the dynamic payloads feature is disabled -- it is disabled by default) -8. `RF24::setCRCLength()` or `RF24::disableCRC()` (the auto-ack feature - automatically enables CRC because it is required) - -Also, it helps to think of an address as a path (a commonly shared route) -instead of an identifying device destination. This means that addresses -have to match for a payload to travel from one transceiver to another. -However, the pipe numbers assigned with the matching address do not have -to match. You can think of pipes as parking spots for the packets, while -all packets' payloads live in a TX or RX FIFO buffer. Remember that the -TX FIFO buffers and the RX FIFO buffers both have a maximum occupancy of -3 payloads (regardless of the maximum 32-byte payload size). - -## Prohibited usage of write*() in Interrupt Service Routine callbacks - -Because the RF24 library uses `millis()` to implement a timeout and `delay()` for mandatory wait times, the following functions cannot be used within an ISR callback method: - -- `RF24::write()` -- `RF24::writeBlocking()` -- `RF24::writeFast()` -- `RF24::startWrite()` -- `RF24::txStandBy()` & `RF24::txStandBy(uint32_t, bool)` -- `RF24::powerUp()` -- `RF24::startListening()` -- `RF24::stopListening()` - -@see The note in the documentation for `RF24::available()`. - -More info about why you can't call `millis()` (or `delay()`) from an ISR callback function is available at [the Arduino docs](https://www.google.com/url?sa=t&source=web&rct=j&url=https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/&ved=2ahUKEwjMhtSRl5jzAhVUsp4KHWIPCrIQFnoECAoQAQ&usg=AOvVaw1X9H0058Nz7Hck91VIC3bD). - -## Here are the most common issues and their solutions - -### write() always returns true after setAutoAck(false) - -Don't disabled the auto-ack feature. RF24::write() has no reason to doubt -that the payload was delivered if the auto-ack feature is disabled. We -recommend you read the docs about RF24::setAutoAck() before disabling the -auto-ack feature. - -### write() returns false when the payload was received - -If the settings match on both endpoint transceivers, then this can only -mean that the receiving nRF24L01 failed to send an acknowledgement (ACK) -packet back to the transmitting nRF24L01. Usually this is due to -instability (electric noise) in the power lines (VCC and GND) going to -the receiving nRF24L01. - -If you're not receiving ACK packets correctly/reliably on data rates -lower than 2MBPS, try adding a big capacitor close to the module/chip. -Example issues: [#264](https://github.com/nRF24/RF24/issues/264) -[#211](https://github.com/nRF24/RF24/issues/211). - -For reliability, please use Electrolytic or Tantalum capacitors. Ceramic -capacitors may not be good enough (depending on the manufacturing source). - -### Payloads received/sent are inaccurate or printDetails() outputs the unexpected value(s) - -This is likely due to the SPI speed being set up to 10MHz by default. We recommend: - -1. Make sure the wires are not loose, and try to avoid using long wires. -2. If the previous point does not help, then try lowering the SPI speed like so - ```cpp - RF24 radio(7, 8, 4000000); // set SPI speed to 4MHz instead of default 10MHz - ``` - -In the RF24 library's beginnings, the default value was (prior to 2014) set to 4MHz. - -### My PA/LNA module fails to transmit - -You may find variants of the nRF24L01 transceiver that are marketed as “nRF24L01+PA+LNA”. These modules are distinct in the fact that they come with a detachable (SMA-type) antenna. They employ separate RFX24C01 IC with the antenna for enhanced Power Amplification (PA) and Low Noise Amplification (LNA) features. While they boast greater range with the same functionality, they are subject to a couple lesser known (and lesser advertised) drawbacks: - -1. Stronger power source. Below is a chart of advertised current requirements that many MCU boards’ 3V regulators may not be able to provide (after supplying power to internal components). - | Specification | Value | - |:-------------:|:-----:| - | Emission mode current(peak) | 115 mA | - | Receive Mode current(peak) | 45 mA | - | Power-down mode current | 4.2 µA | - -2. Needs shielding from electromagnetic interference. Shielding usually works best when it has a path to ground (GND pin), but this connection to the GND pin is not required. It is important that the shielding does not touch any current carrying parts. - - Professionals tend to use a faraday cage/mesh to implement electromagnetic shielding, but it can be pricey for this scenario. - - A quick do-it-yourself solution (as proof-of-concept) would be to wrap the PA/LNA module with electrical tape and then wrap foil around the electrical tape (for shielding) while being very careful to not let the foil touch any current carrying parts (like the GPIO pins, the antenna mount, and the soldier joints for the antenna mount). Observe - [](https://github.com/nRF24/RF24/blob/master/images/ghetto_sheilding_1.png) - [](https://github.com/nRF24/RF24/blob/master/images/ghetto_sheilding_2.png) - -### My PA/LNA module doesn't perform as well as I'd hoped or the NRF radio works better on touching it - -As described above, the radio modules (notably the PA+LNA versions) are reliant on a stable power source. While these modules may work with a poor power supply, they often lose packets or fail to receive as many as a module with a better power source. Moreover, this can sometimes be seen in odd ways such as the radio module working better when touched. This again is likely a power stability issue because the radio module is missing a capacitor (a commonly neglected expense on behalf of the module's manufacturer). - -Add capacitor(s) close to the VCC and GND pins of the radio. Typically, 10uF is enough. Depending upon your circuit's layout, differences in capacitors' electrolytic properties can be seen, such that a low ESR (Equivalent Series Resistance) rated capacitor is desirable. diff --git a/RF24/CONTRIBUTING.md b/RF24/CONTRIBUTING.md deleted file mode 100644 index 41f9605802bfeb8b4a1ebaed3fc88915fa3ec283..0000000000000000000000000000000000000000 --- a/RF24/CONTRIBUTING.md +++ /dev/null @@ -1,16 +0,0 @@ -# Contributing guidelines - -These are the current requirements for getting your code included in RF24: - -- Try your best to follow the rest of the code, if you're unsure then [the NASA C style guide](https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19950022400.pdf) can help as it's closest to the current style. - -- Definetly follow [PEP-8](https://www.python.org/dev/peps/pep-0008/) if it's Python code. - -- Follow the [Arduino example formatting style](https://docs.arduino.cc/learn/contributions/arduino-writing-style-guide) for Arduino examples - -- Add [doxygen-compatible documentation](https://www.doxygen.nl/manual/docblocks.html) to any new functions you add, or update existing documentation if you change behaviour - -- CMake modules and CMakeLists.txt files should also have a uniform syntax. - - Indentation is a mandatory 4 spaces (not a `\t` character). - - Closing parenthesis for multi-line commands should have the same indentation as the line that opened the parenthesis. - - For other useful CMake syntax convention, please see [CMake docs for developers](https://cmake.org/cmake/help/v3.20/manual/cmake-developer.7.html) and [this useful best CMake practices article](https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1). The qiBuild project has some [well-reasoned "Dos & Don'ts" guideline](http://doc.aldebaran.com/qibuild/hacking/contrib/cmake/coding_guide.html), but beware that the nRF24 organization is not related to the qiBuild project in any way. diff --git a/RF24/Doxyfile b/RF24/Doxyfile deleted file mode 100644 index 216e7bee09807b1b595c550eb667ec915ec01d3b..0000000000000000000000000000000000000000 --- a/RF24/Doxyfile +++ /dev/null @@ -1,374 +0,0 @@ -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = "Optimized high speed nRF24L01+ driver class documentation" - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = "TMRh20 2020 - Optimized fork of the nRF24L01+ driver" - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = ./docs - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: -# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser -# tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files -# as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = ino=c \ - pde=c - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = YES - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# (including Cygwin) ands Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = YES - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = NO - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = ./ \ - ./utility/Template \ - ./docs - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), -# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen -# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.idl \ - *.ddl \ - *.odl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.cs \ - *.d \ - *.php \ - *.php4 \ - *.php5 \ - *.phtml \ - *.inc \ - *.m \ - *.markdown \ - *.md \ - *.mm \ - *.dox \ - *.py \ - *.f90 \ - *.f \ - *.for \ - *.tcl \ - *.vhd \ - *.vhdl \ - *.ucf \ - *.qsf \ - *.as \ - *.js - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = Makefile \ - configure - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = bcm2835* \ - readme* \ - runtest* \ - tests* \ - README* - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = _ - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = examples \ - examples_linux - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = YES - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = images - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = ./docs/main_page.md - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = doxygen-custom.css - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML -# documentation will contain a main index with vertical navigation menus that -# are dynamically created via JavaScript. If disabled, the navigation index will -# consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have JavaScript, -# like the Qt help browser. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_MENUS = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. -# The default value is: YES. - -GENERATE_LATEX = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that -# captures the structure of the code including all documentation. -# The default value is: NO. - -GENERATE_XML = YES - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: xml. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_OUTPUT = sphinx/xml - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# The PREDEFINED tag can be used to specify one or more macro names that are -# defined before the preprocessor is started (similar to the -D option of e.g. -# gcc). The argument of the tag is a list of macros of the form: name or -# name=definition (no spaces). If the definition and the "=" are omitted, "=1" -# is assumed. To prevent a macro definition from being undefined via #undef or -# recursively expanded use the := operator instead of the = operator. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -PREDEFINED = DOXYGEN_FORCED diff --git a/RF24/LICENSE b/RF24/LICENSE deleted file mode 100644 index 23cb790338e191e29205d6f4123882c0583ef8eb..0000000000000000000000000000000000000000 --- a/RF24/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/> - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {description} - Copyright (C) {year} {fullname} - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - {signature of Ty Coon}, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/RF24/Makefile b/RF24/Makefile deleted file mode 100644 index ada2ffecbdb32e0e3b4ac3fd591948a91946fafb..0000000000000000000000000000000000000000 --- a/RF24/Makefile +++ /dev/null @@ -1,134 +0,0 @@ -############################################################################# -# -# Makefile for librf24 -# -# License: GPL (General Public License) -# Author: Charles-Henri Hallard -# Date: 2013/03/13 -# -# Description: -# ------------ -# use make all and make install to install the library -# - -CONFIG_FILE=Makefile.inc -REMOTE_ERROR="[ERROR] Remote machine not configured. Run configure with respective arguments." - -include $(CONFIG_FILE) - -# Objects to compile -OBJECTS=RF24.o -ifeq ($(DRIVER), MRAA) -OBJECTS+=spi.o gpio.o compatibility.o -else ifeq ($(DRIVER), RPi) -OBJECTS+=spi.o bcm2835.o compatibility.o -ifneq (,$(findstring -lpigpio,$(SHARED_LINKER_LIBS))) -OBJECTS+=interrupt.o -endif -else ifeq ($(DRIVER), SPIDEV) -OBJECTS+=spi.o gpio.o compatibility.o -ifneq (,$(findstring -lpigpio,$(SHARED_LINKER_LIBS))) -OBJECTS+=interrupt.o -endif -else ifeq ($(DRIVER), wiringPi) -OBJECTS+=spi.o -else ifeq ($(DRIVER), pigpio) -OBJECTS+=spi.o gpio.o interrupt.o compatibility.o -endif - -# make all -# reinstall the library after each recompilation -all: $(LIBNAME) - -# Make the library -$(LIBNAME): $(OBJECTS) - @echo "[Linking]" - $(CC) $(SHARED_LINKER_FLAGS) $(CFLAGS) -o $(LIBNAME) $^ $(SHARED_LINKER_LIBS) - -# Library parts -RF24.o: RF24.cpp - $(CXX) -fPIC $(CFLAGS) -c $^ - -bcm2835.o: $(DRIVER_DIR)/bcm2835.c - $(CC) -fPIC $(CFLAGS) -c $^ - -spi.o: $(DRIVER_DIR)/spi.cpp - $(CXX) -fPIC $(CFLAGS) -c $^ - -compatibility.o: $(DRIVER_DIR)/compatibility.cpp - $(CC) -fPIC $(CFLAGS) -c $(DRIVER_DIR)/compatibility.cpp - -gpio.o: $(DRIVER_DIR)/gpio.cpp - $(CXX) -fPIC $(CFLAGS) -c $(DRIVER_DIR)/gpio.cpp - -interrupt.o: $(DRIVER_DIR)/interrupt.cpp - $(CXX) -fPIC $(CFLAGS) -c $(DRIVER_DIR)/interrupt.cpp - -# clear configuration files -cleanconfig: - @echo "[Cleaning configuration]" - rm -rf $(CONFIG_FILE) utility/includes.h - -# clear build files -clean: - @echo "[Cleaning]" - rm -rf *.o $(LIBNAME) - -$(CONFIG_FILE): - @echo "[Running configure]" - @./configure --no-clean - -install: all install-libs install-headers -upload: all upload-libs upload-headers - -# Install the library to LIBPATH -install-libs: - @echo "[Installing Libs to $(LIB_DIR)]" - @if ( test ! -d $(LIB_DIR) ); then mkdir -p $(LIB_DIR); fi - @install -m 0755 $(LIBNAME) $(LIB_DIR) - @orig=$(LIBNAME) && \ - for sl in $(LIBSYMLINKS); do \ - ln -sf $(LIB_DIR)/$${orig} $(LIB_DIR)/$${sl}; \ - orig=$${sl}; \ - done && \ - if [ "$(LIBDEPRECATE)" ]; then ln -sf $(LIB_DIR)/$${orig} $(LIB_DIR)/$(LIBDEPRECATE); fi -ifneq ($(LDCONFIG),) - @$(LDCONFIG) -endif - -upload-libs: - @echo "[Uploading Libs to $(REMOTE):$(REMOTE_LIB_DIR)]" -ifeq ($(REMOTE),) - @echo "$(REMOTE_ERROR)" - @exit 1 -endif - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "mkdir -p $(REMOTE_LIB_DIR)" - @scp -q -P $(REMOTE_PORT) $(LIBNAME) $(REMOTE):/tmp - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "sudo install -m 0755 /tmp/$(LIBNAME) $(REMOTE_LIB_DIR) &&" \ - " orig=$(LIBNAME) && for sl in $(LIBSYMLINKS); do sudo ln -sf $(REMOTE_LIB_DIR)/\$${orig} $(REMOTE_LIB_DIR)/\$${sl}; orig=\$${sl}; done &&" \ - " if [ "$(LIBDEPRECATE)" ]; then sudo ln -sf $(REMOTE_LIB_DIR)/\$${orig} $(REMOTE_LIB_DIR)/$(LIBDEPRECATE); fi &&" \ - " rm /tmp/$(LIBNAME)" -ifneq ($(REMOTE_LDCONFIG),) - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "sudo $(REMOTE_LDCONFIG)" -endif - -install-headers: - @echo "[Installing Headers to $(HEADER_DIR)]" - @mkdir -p $(HEADER_DIR)/$(DRIVER_DIR) - @install -m 0644 *.h $(HEADER_DIR) - @install -m 0644 $(DRIVER_DIR)/*.h $(HEADER_DIR)/$(DRIVER_DIR) - @install -m 0644 $(ARCH_DIR)/*.h $(HEADER_DIR)/$(ARCH_DIR) - -upload-headers: - @echo "[Uploading Headers to $(REMOTE):$(REMOTE_HEADER_DIR)]" -ifeq ($(REMOTE),) - @echo "$(REMOTE_ERROR)" - @exit 1 -endif - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "sudo mkdir -p $(REMOTE_HEADER_DIR)/$(DRIVER_DIR)" - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "mkdir -p /tmp/RF24 && rm -rf /tmp/RF24/*" - @rsync -a --include="*.h" --include="*/" --exclude="*" -e "ssh -p $(REMOTE_PORT)" . $(REMOTE):/tmp/RF24 - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "sudo install -m 0644 /tmp/RF24/*.h $(REMOTE_HEADER_DIR)" - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "sudo install -m 0644 /tmp/RF24/$(DRIVER_DIR)/*.h $(REMOTE_HEADER_DIR)/$(DRIVER_DIR)" - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "sudo install -m 0644 /tmp/RF24/$(ARCH_DIR)/*.h $(REMOTE_HEADER_DIR)/$(ARCH_DIR)" - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "rm -rf /tmp/RF24" diff --git a/RF24/README.md b/RF24/README.md deleted file mode 100644 index aaf657a924a739e20d200a2f43d04559960e8939..0000000000000000000000000000000000000000 --- a/RF24/README.md +++ /dev/null @@ -1,16 +0,0 @@ -<!-- markdownlint-disable MD041 MD034 --> -[](https://github.com/nRF24/RF24/actions?query=workflow%3A%22Arduino+CLI+build%22) -[](https://github.com/nRF24/RF24/actions?query=workflow%3A%22Linux+build%22) -[](https://github.com/nRF24/RF24/actions/workflows/build_platformIO.yml) -[](https://github.com/nRF24/RF24/actions/workflows/build_rp2xxx.yml) -[](https://rf24.readthedocs.io/en/latest/?badge=latest) - -# See http://nRF24.github.io/RF24 for all documentation - -## Having problems? - -Please read our **[solutions to common problems](COMMON_ISSUES.md)**. If that doesn't help, then open an issue describing your problem with as much detail as possible. - -### Want to contribute? - -Awesome! However, please check our [contributing guidelines](CONTRIBUTING.md) before opening a pull request. diff --git a/RF24/RF24.cpp b/RF24/RF24.cpp deleted file mode 100644 index c0ceef8a2dc267dd94de5eeb69646a69ca315a91..0000000000000000000000000000000000000000 --- a/RF24/RF24.cpp +++ /dev/null @@ -1,2073 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - */ - -#include "nRF24L01.h" -#include "RF24_config.h" -#include "RF24.h" - -/****************************************************************************/ - -void RF24::csn(bool mode) -{ -#if defined(RF24_TINY) - if (ce_pin != csn_pin) { - digitalWrite(csn_pin, mode); - } - else { - if (mode == HIGH) { - PORTB |= (1 << PINB2); // SCK->CSN HIGH - delayMicroseconds(RF24_CSN_SETTLE_HIGH_DELAY); // allow csn to settle. - } - else { - PORTB &= ~(1 << PINB2); // SCK->CSN LOW - delayMicroseconds(RF24_CSN_SETTLE_LOW_DELAY); // allow csn to settle - } - } - // Return, CSN toggle complete - return; - -#elif defined(ARDUINO) && !defined(RF24_SPI_TRANSACTIONS) - // Minimum ideal SPI bus speed is 2x data rate - // If we assume 2Mbs data rate and 16Mhz clock, a - // divider of 4 is the minimum we want. - // CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz - - #if !defined(SOFTSPI) - // applies to SPI_UART and inherent hardware SPI - #if defined(RF24_SPI_PTR) - _spi->setBitOrder(MSBFIRST); - _spi->setDataMode(SPI_MODE0); - - #if !defined(F_CPU) || F_CPU < 20000000 - _spi->setClockDivider(SPI_CLOCK_DIV2); - #elif F_CPU < 40000000 - _spi->setClockDivider(SPI_CLOCK_DIV4); - #elif F_CPU < 80000000 - _spi->setClockDivider(SPI_CLOCK_DIV8); - #elif F_CPU < 160000000 - _spi->setClockDivider(SPI_CLOCK_DIV16); - #elif F_CPU < 320000000 - _spi->setClockDivider(SPI_CLOCK_DIV32); - #elif F_CPU < 640000000 - _spi->setClockDivider(SPI_CLOCK_DIV64); - #elif F_CPU < 1280000000 - _spi->setClockDivider(SPI_CLOCK_DIV128); - #else // F_CPU >= 1280000000 - #error "Unsupported CPU frequency. Please set correct SPI divider." - #endif // F_CPU to SPI_CLOCK_DIV translation - - #else // !defined(RF24_SPI_PTR) - _SPI.setBitOrder(MSBFIRST); - _SPI.setDataMode(SPI_MODE0); - - #if !defined(F_CPU) || F_CPU < 20000000 - _SPI.setClockDivider(SPI_CLOCK_DIV2); - #elif F_CPU < 40000000 - _SPI.setClockDivider(SPI_CLOCK_DIV4); - #elif F_CPU < 80000000 - _SPI.setClockDivider(SPI_CLOCK_DIV8); - #elif F_CPU < 160000000 - _SPI.setClockDivider(SPI_CLOCK_DIV16); - #elif F_CPU < 320000000 - _SPI.setClockDivider(SPI_CLOCK_DIV32); - #elif F_CPU < 640000000 - _SPI.setClockDivider(SPI_CLOCK_DIV64); - #elif F_CPU < 1280000000 - _SPI.setClockDivider(SPI_CLOCK_DIV128); - #else // F_CPU >= 1280000000 - #error "Unsupported CPU frequency. Please set correct SPI divider." - #endif // F_CPU to SPI_CLOCK_DIV translation - #endif // !defined(RF24_SPI_PTR) - #endif // !defined(SOFTSPI) - -#elif defined(RF24_RPi) - if (!mode) - _SPI.chipSelect(csn_pin); -#endif // defined(RF24_RPi) - -#if !defined(RF24_LINUX) - digitalWrite(csn_pin, mode); - delayMicroseconds(csDelay); -#else - static_cast<void>(mode); // ignore -Wunused-parameter -#endif // !defined(RF24_LINUX) -} - -/****************************************************************************/ - -void RF24::ce(bool level) -{ - //Allow for 3-pin use on ATTiny - if (ce_pin != csn_pin) { - digitalWrite(ce_pin, level); - } -} - -/****************************************************************************/ - -inline void RF24::beginTransaction() -{ -#if defined(RF24_SPI_TRANSACTIONS) - #if defined(RF24_SPI_PTR) - #if defined(RF24_RP2) - _spi->beginTransaction(spi_speed); - #else // ! defined (RF24_RP2) - _spi->beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE0)); - #endif // ! defined (RF24_RP2) - #else // !defined(RF24_SPI_PTR) - _SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE0)); - #endif // !defined(RF24_SPI_PTR) -#endif // defined (RF24_SPI_TRANSACTIONS) - csn(LOW); -} - -/****************************************************************************/ - -inline void RF24::endTransaction() -{ - csn(HIGH); -#if defined(RF24_SPI_TRANSACTIONS) - #if defined(RF24_SPI_PTR) - _spi->endTransaction(); - #else // !defined(RF24_SPI_PTR) - _SPI.endTransaction(); - #endif // !defined(RF24_SPI_PTR) -#endif // defined (RF24_SPI_TRANSACTIONS) -} - -/****************************************************************************/ - -void RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) -{ -#if defined(RF24_LINUX) || defined(RF24_RP2) - beginTransaction(); //configures the spi settings for RPi, locks mutex and setting csn low - uint8_t* prx = spi_rxbuff; - uint8_t* ptx = spi_txbuff; - uint8_t size = static_cast<uint8_t>(len + 1); // Add register value to transmit buffer - - *ptx++ = (R_REGISTER | reg); - - while (len--) { - *ptx++ = RF24_NOP; // Dummy operation, just for reading - } - - #if defined(RF24_RP2) - _spi->transfernb((const uint8_t*)spi_txbuff, spi_rxbuff, size); - #else // !defined (RF24_RP2) - _SPI.transfernb(reinterpret_cast<char*>(spi_txbuff), reinterpret_cast<char*>(spi_rxbuff), size); - #endif // !defined (RF24_RP2) - - status = *prx++; // status is 1st byte of receive buffer - - // decrement before to skip status byte - while (--size) { - *buf++ = *prx++; - } - - endTransaction(); // unlocks mutex and setting csn high - -#else // !defined(RF24_LINUX) && !defined(RF24_RP2) - - beginTransaction(); - #if defined(RF24_SPI_PTR) - status = _spi->transfer(R_REGISTER | reg); - while (len--) { - *buf++ = _spi->transfer(0xFF); - } - - #else // !defined(RF24_SPI_PTR) - status = _SPI.transfer(R_REGISTER | reg); - while (len--) { - *buf++ = _SPI.transfer(0xFF); - } - - #endif // !defined(RF24_SPI_PTR) - endTransaction(); -#endif // !defined(RF24_LINUX) && !defined(RF24_RP2) -} - -/****************************************************************************/ - -uint8_t RF24::read_register(uint8_t reg) -{ - uint8_t result; - -#if defined(RF24_LINUX) || defined(RF24_RP2) - beginTransaction(); - - uint8_t* prx = spi_rxbuff; - uint8_t* ptx = spi_txbuff; - *ptx++ = (R_REGISTER | reg); - *ptx++ = RF24_NOP; // Dummy operation, just for reading - - #if defined(RF24_RP2) - _spi->transfernb((const uint8_t*)spi_txbuff, spi_rxbuff, 2); - #else // !defined(RF24_RP2) - _SPI.transfernb(reinterpret_cast<char*>(spi_txbuff), reinterpret_cast<char*>(spi_rxbuff), 2); - #endif // !defined(RF24_RP2) - - status = *prx; // status is 1st byte of receive buffer - result = *++prx; // result is 2nd byte of receive buffer - - endTransaction(); -#else // !defined(RF24_LINUX) && !defined(RF24_RP2) - - beginTransaction(); - #if defined(RF24_SPI_PTR) - status = _spi->transfer(R_REGISTER | reg); - result = _spi->transfer(0xff); - - #else // !defined(RF24_SPI_PTR) - status = _SPI.transfer(R_REGISTER | reg); - result = _SPI.transfer(0xff); - - #endif // !defined(RF24_SPI_PTR) - endTransaction(); -#endif // !defined(RF24_LINUX) && !defined(RF24_RP2) - - return result; -} - -/****************************************************************************/ - -void RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) -{ -#if defined(RF24_LINUX) || defined(RF24_RP2) - beginTransaction(); - uint8_t* prx = spi_rxbuff; - uint8_t* ptx = spi_txbuff; - uint8_t size = static_cast<uint8_t>(len + 1); // Add register value to transmit buffer - - *ptx++ = (W_REGISTER | (REGISTER_MASK & reg)); - while (len--) { - *ptx++ = *buf++; - } - - #if defined(RF24_RP2) - _spi->transfernb((const uint8_t*)spi_txbuff, spi_rxbuff, size); - #else // !defined(RF24_RP2) - _SPI.transfernb(reinterpret_cast<char*>(spi_txbuff), reinterpret_cast<char*>(spi_rxbuff), size); - #endif // !defined(RF24_RP2) - - status = *prx; // status is 1st byte of receive buffer - endTransaction(); -#else // !defined(RF24_LINUX) && !defined(RF24_RP2) - - beginTransaction(); - #if defined(RF24_SPI_PTR) - status = _spi->transfer(W_REGISTER | reg); - while (len--) { - _spi->transfer(*buf++); - } - - #else // !defined(RF24_SPI_PTR) - status = _SPI.transfer(W_REGISTER | reg); - while (len--) { - _SPI.transfer(*buf++); - } - - #endif // !defined(RF24_SPI_PTR) - endTransaction(); -#endif // !defined(RF24_LINUX) && !defined(RF24_RP2) -} - -/****************************************************************************/ - -void RF24::write_register(uint8_t reg, uint8_t value, bool is_cmd_only) -{ - if (is_cmd_only) { - if (reg != RF24_NOP) { // don't print the get_status() operation - IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x)\r\n"), reg)); - } - beginTransaction(); -#if defined(RF24_LINUX) - status = _SPI.transfer(W_REGISTER | reg); -#else // !defined(RF24_LINUX) || defined (RF24_RP2) - #if defined(RF24_SPI_PTR) - status = _spi->transfer(W_REGISTER | reg); - #else // !defined (RF24_SPI_PTR) - status = _SPI.transfer(W_REGISTER | reg); - #endif // !defined (RF24_SPI_PTR) -#endif // !defined(RF24_LINUX) || defined(RF24_RP2) - endTransaction(); - } - else { - IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"), reg, value)); -#if defined(RF24_LINUX) || defined(RF24_RP2) - beginTransaction(); - uint8_t* prx = spi_rxbuff; - uint8_t* ptx = spi_txbuff; - *ptx++ = (W_REGISTER | reg); - *ptx = value; - - #if defined(RF24_RP2) - _spi->transfernb((const uint8_t*)spi_txbuff, spi_rxbuff, 2); - #else // !defined(RF24_RP2) - _SPI.transfernb(reinterpret_cast<char*>(spi_txbuff), reinterpret_cast<char*>(spi_rxbuff), 2); - #endif // !defined(RF24_RP2) - - status = *prx++; // status is 1st byte of receive buffer - endTransaction(); -#else // !defined(RF24_LINUX) && !defined(RF24_RP2) - - beginTransaction(); - #if defined(RF24_SPI_PTR) - status = _spi->transfer(W_REGISTER | reg); - _spi->transfer(value); - #else // !defined(RF24_SPI_PTR) - status = _SPI.transfer(W_REGISTER | reg); - _SPI.transfer(value); - #endif // !defined(RF24_SPI_PTR) - endTransaction(); -#endif // !defined(RF24_LINUX) && !defined(RF24_RP2) - } -} - -/****************************************************************************/ - -void RF24::write_payload(const void* buf, uint8_t data_len, const uint8_t writeType) -{ - const uint8_t* current = reinterpret_cast<const uint8_t*>(buf); - - uint8_t blank_len = !data_len ? 1 : 0; - if (!dynamic_payloads_enabled) { - data_len = rf24_min(data_len, payload_size); - blank_len = static_cast<uint8_t>(payload_size - data_len); - } - else { - data_len = rf24_min(data_len, static_cast<uint8_t>(32)); - } - - //printf("[Writing %u bytes %u blanks]",data_len,blank_len); - IF_SERIAL_DEBUG(printf("[Writing %u bytes %u blanks]\n", data_len, blank_len);); - -#if defined(RF24_LINUX) || defined(RF24_RP2) - beginTransaction(); - uint8_t* prx = spi_rxbuff; - uint8_t* ptx = spi_txbuff; - uint8_t size; - size = static_cast<uint8_t>(data_len + blank_len + 1); // Add register value to transmit buffer - - *ptx++ = writeType; - while (data_len--) { - *ptx++ = *current++; - } - - while (blank_len--) { - *ptx++ = 0; - } - - #if defined(RF24_RP2) - _spi->transfernb((const uint8_t*)spi_txbuff, spi_rxbuff, size); - #else // !defined(RF24_RP2) - _SPI.transfernb(reinterpret_cast<char*>(spi_txbuff), reinterpret_cast<char*>(spi_rxbuff), size); - #endif // !defined(RF24_RP2) - - status = *prx; // status is 1st byte of receive buffer - endTransaction(); - -#else // !defined(RF24_LINUX) && !defined(RF24_RP2) - - beginTransaction(); - #if defined(RF24_SPI_PTR) - status = _spi->transfer(writeType); - while (data_len--) { - _spi->transfer(*current++); - } - - while (blank_len--) { - _spi->transfer(0); - } - - #else // !defined(RF24_SPI_PTR) - status = _SPI.transfer(writeType); - while (data_len--) { - _SPI.transfer(*current++); - } - - while (blank_len--) { - _SPI.transfer(0); - } - - #endif // !defined(RF24_SPI_PTR) - endTransaction(); -#endif // !defined(RF24_LINUX) && !defined(RF24_RP2) -} - -/****************************************************************************/ - -void RF24::read_payload(void* buf, uint8_t data_len) -{ - uint8_t* current = reinterpret_cast<uint8_t*>(buf); - - uint8_t blank_len = 0; - if (!dynamic_payloads_enabled) { - data_len = rf24_min(data_len, payload_size); - blank_len = static_cast<uint8_t>(payload_size - data_len); - } - else { - data_len = rf24_min(data_len, static_cast<uint8_t>(32)); - } - - //printf("[Reading %u bytes %u blanks]",data_len,blank_len); - - IF_SERIAL_DEBUG(printf("[Reading %u bytes %u blanks]\n", data_len, blank_len);); - -#if defined(RF24_LINUX) || defined(RF24_RP2) - beginTransaction(); - uint8_t* prx = spi_rxbuff; - uint8_t* ptx = spi_txbuff; - uint8_t size; - size = static_cast<uint8_t>(data_len + blank_len + 1); // Add register value to transmit buffer - - *ptx++ = R_RX_PAYLOAD; - while (--size) { - *ptx++ = RF24_NOP; - } - - size = static_cast<uint8_t>(data_len + blank_len + 1); // Size has been lost during while, re affect - - #if defined(RF24_RP2) - _spi->transfernb((const uint8_t*)spi_txbuff, spi_rxbuff, size); - #else // !defined(RF24_RP2) - _SPI.transfernb(reinterpret_cast<char*>(spi_txbuff), reinterpret_cast<char*>(spi_rxbuff), size); - #endif // !defined(RF24_RP2) - - status = *prx++; // 1st byte is status - - if (data_len > 0) { - // Decrement before to skip 1st status byte - while (--data_len) { - *current++ = *prx++; - } - - *current = *prx; - } - endTransaction(); -#else // !defined(RF24_LINUX) && !defined(RF24_RP2) - - beginTransaction(); - #if defined(RF24_SPI_PTR) - status = _spi->transfer(R_RX_PAYLOAD); - while (data_len--) { - *current++ = _spi->transfer(0xFF); - } - - while (blank_len--) { - _spi->transfer(0xFF); - } - - #else // !defined(RF24_SPI_PTR) - status = _SPI.transfer(R_RX_PAYLOAD); - while (data_len--) { - *current++ = _SPI.transfer(0xFF); - } - - while (blank_len--) { - _SPI.transfer(0xff); - } - - #endif // !defined(RF24_SPI_PTR) - endTransaction(); - -#endif // !defined(RF24_LINUX) && !defined(RF24_RP2) -} - -/****************************************************************************/ - -uint8_t RF24::flush_rx(void) -{ - write_register(FLUSH_RX, RF24_NOP, true); - return status; -} - -/****************************************************************************/ - -uint8_t RF24::flush_tx(void) -{ - write_register(FLUSH_TX, RF24_NOP, true); - return status; -} - -/****************************************************************************/ - -uint8_t RF24::get_status(void) -{ - write_register(RF24_NOP, RF24_NOP, true); - return status; -} - -/****************************************************************************/ -#if !defined(MINIMAL) - -void RF24::print_status(uint8_t _status) -{ - printf_P(PSTR("STATUS\t\t= 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n"), _status, (_status & _BV(RX_DR)) ? 1 : 0, - (_status & _BV(TX_DS)) ? 1 : 0, (_status & _BV(MAX_RT)) ? 1 : 0, ((_status >> RX_P_NO) & 0x07), (_status & _BV(TX_FULL)) ? 1 : 0); -} - -/****************************************************************************/ - -void RF24::print_observe_tx(uint8_t value) -{ - printf_P(PSTR("OBSERVE_TX=%02x: PLOS_CNT=%x ARC_CNT=%x\r\n"), value, (value >> PLOS_CNT) & 0x0F, (value >> ARC_CNT) & 0x0F); -} - -/****************************************************************************/ - -void RF24::print_byte_register(const char* name, uint8_t reg, uint8_t qty) -{ - printf_P(PSTR(PRIPSTR - "\t="), - name); - while (qty--) { - printf_P(PSTR(" 0x%02x"), read_register(reg++)); - } - printf_P(PSTR("\r\n")); -} - -/****************************************************************************/ - -void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty) -{ - - printf_P(PSTR(PRIPSTR - "\t="), - name); - while (qty--) { - uint8_t* buffer = new uint8_t[addr_width]; - read_register(reg++ & REGISTER_MASK, buffer, addr_width); - - printf_P(PSTR(" 0x")); - uint8_t* bufptr = buffer + addr_width; - while (--bufptr >= buffer) { - printf_P(PSTR("%02x"), *bufptr); // NOLINT: clang-tidy seems to emit a false positive about zero-allocated memory here (*bufptr) - } - delete[] buffer; - } - printf_P(PSTR("\r\n")); -} - -/****************************************************************************/ - -uint8_t RF24::sprintf_address_register(char* out_buffer, uint8_t reg, uint8_t qty) -{ - uint8_t offset = 0; - uint8_t* read_buffer = new uint8_t[addr_width]; - while (qty--) { - read_register(reg++ & REGISTER_MASK, read_buffer, addr_width); - uint8_t* bufptr = read_buffer + addr_width; - while (--bufptr >= read_buffer) { - offset += sprintf_P(out_buffer + offset, PSTR("%02X"), *bufptr); - } - } - delete[] read_buffer; - return offset; -} -#endif // !defined(MINIMAL) - -/****************************************************************************/ - -RF24::RF24(uint16_t _cepin, uint16_t _cspin, uint32_t _spi_speed) - : ce_pin(_cepin), csn_pin(_cspin), spi_speed(_spi_speed), payload_size(32), _is_p_variant(false), _is_p0_rx(false), addr_width(5), dynamic_payloads_enabled(true), csDelay(5) -{ - _init_obj(); -} - -/****************************************************************************/ - -RF24::RF24(uint32_t _spi_speed) - : ce_pin(0xFFFF), csn_pin(0xFFFF), spi_speed(_spi_speed), payload_size(32), _is_p_variant(false), _is_p0_rx(false), addr_width(5), dynamic_payloads_enabled(true), csDelay(5) -{ - _init_obj(); -} - -/****************************************************************************/ - -void RF24::_init_obj() -{ - // Use a pointer on the Arduino platform - -#if defined(RF24_SPI_PTR) && !defined(RF24_RP2) - _spi = &SPI; -#endif // defined (RF24_SPI_PTR) - - pipe0_reading_address[0] = 0; - if (spi_speed <= 35000) { //Handle old BCM2835 speed constants, default to RF24_SPI_SPEED - spi_speed = RF24_SPI_SPEED; - } -} - -/****************************************************************************/ - -void RF24::setChannel(uint8_t channel) -{ - const uint8_t max_channel = 125; - write_register(RF_CH, rf24_min(channel, max_channel)); -} - -uint8_t RF24::getChannel() -{ - return read_register(RF_CH); -} - -/****************************************************************************/ - -void RF24::setPayloadSize(uint8_t size) -{ - // payload size must be in range [1, 32] - payload_size = static_cast<uint8_t>(rf24_max(1, rf24_min(32, size))); - - // write static payload size setting for all pipes - for (uint8_t i = 0; i < 6; ++i) { - write_register(static_cast<uint8_t>(RX_PW_P0 + i), payload_size); - } -} - -/****************************************************************************/ - -uint8_t RF24::getPayloadSize(void) -{ - return payload_size; -} - -/****************************************************************************/ - -#if !defined(MINIMAL) - -static const PROGMEM char rf24_datarate_e_str_0[] = "= 1 MBPS"; -static const PROGMEM char rf24_datarate_e_str_1[] = "= 2 MBPS"; -static const PROGMEM char rf24_datarate_e_str_2[] = "= 250 KBPS"; -static const PROGMEM char* const rf24_datarate_e_str_P[] = { - rf24_datarate_e_str_0, - rf24_datarate_e_str_1, - rf24_datarate_e_str_2, -}; -static const PROGMEM char rf24_model_e_str_0[] = "nRF24L01"; -static const PROGMEM char rf24_model_e_str_1[] = "nRF24L01+"; -static const PROGMEM char* const rf24_model_e_str_P[] = { - rf24_model_e_str_0, - rf24_model_e_str_1, -}; -static const PROGMEM char rf24_crclength_e_str_0[] = "= Disabled"; -static const PROGMEM char rf24_crclength_e_str_1[] = "= 8 bits"; -static const PROGMEM char rf24_crclength_e_str_2[] = "= 16 bits"; -static const PROGMEM char* const rf24_crclength_e_str_P[] = { - rf24_crclength_e_str_0, - rf24_crclength_e_str_1, - rf24_crclength_e_str_2, -}; -static const PROGMEM char rf24_pa_dbm_e_str_0[] = "= PA_MIN"; -static const PROGMEM char rf24_pa_dbm_e_str_1[] = "= PA_LOW"; -static const PROGMEM char rf24_pa_dbm_e_str_2[] = "= PA_HIGH"; -static const PROGMEM char rf24_pa_dbm_e_str_3[] = "= PA_MAX"; -static const PROGMEM char* const rf24_pa_dbm_e_str_P[] = { - rf24_pa_dbm_e_str_0, - rf24_pa_dbm_e_str_1, - rf24_pa_dbm_e_str_2, - rf24_pa_dbm_e_str_3, -}; - - #if defined(RF24_LINUX) -static const char rf24_csn_e_str_0[] = "CE0 (PI Hardware Driven)"; -static const char rf24_csn_e_str_1[] = "CE1 (PI Hardware Driven)"; -static const char rf24_csn_e_str_2[] = "CE2 (PI Hardware Driven)"; -static const char rf24_csn_e_str_3[] = "Custom GPIO Software Driven"; -static const char* const rf24_csn_e_str_P[] = { - rf24_csn_e_str_0, - rf24_csn_e_str_1, - rf24_csn_e_str_2, - rf24_csn_e_str_3, -}; - #endif // defined(RF24_LINUX) - -static const PROGMEM char rf24_feature_e_str_on[] = "= Enabled"; -static const PROGMEM char rf24_feature_e_str_allowed[] = "= Allowed"; -static const PROGMEM char rf24_feature_e_str_open[] = " open "; -static const PROGMEM char rf24_feature_e_str_closed[] = "closed"; -static const PROGMEM char* const rf24_feature_e_str_P[] = { - rf24_crclength_e_str_0, - rf24_feature_e_str_on, - rf24_feature_e_str_allowed, - rf24_feature_e_str_closed, - rf24_feature_e_str_open, -}; - -void RF24::printDetails(void) -{ - - #if defined(RF24_LINUX) - printf("================ SPI Configuration ================\n"); - uint8_t bus_ce = static_cast<uint8_t>(csn_pin % 10); - uint8_t bus_numb = static_cast<uint8_t>((csn_pin - bus_ce) / 10); - printf("CSN Pin\t\t= /dev/spidev%d.%d\n", bus_numb, bus_ce); - printf("CE Pin\t\t= Custom GPIO%d\n", ce_pin); - #endif - printf_P(PSTR("SPI Speedz\t= %d Mhz\n"), static_cast<uint8_t>(spi_speed / 1000000)); //Print the SPI speed on non-Linux devices - #if defined(RF24_LINUX) - printf("================ NRF Configuration ================\n"); - #endif // defined(RF24_LINUX) - - print_status(get_status()); - - print_address_register(PSTR("RX_ADDR_P0-1"), RX_ADDR_P0, 2); - print_byte_register(PSTR("RX_ADDR_P2-5"), RX_ADDR_P2, 4); - print_address_register(PSTR("TX_ADDR\t"), TX_ADDR); - - print_byte_register(PSTR("RX_PW_P0-6"), RX_PW_P0, 6); - print_byte_register(PSTR("EN_AA\t"), EN_AA); - print_byte_register(PSTR("EN_RXADDR"), EN_RXADDR); - print_byte_register(PSTR("RF_CH\t"), RF_CH); - print_byte_register(PSTR("RF_SETUP"), RF_SETUP); - print_byte_register(PSTR("CONFIG\t"), NRF_CONFIG); - print_byte_register(PSTR("DYNPD/FEATURE"), DYNPD, 2); - - printf_P(PSTR("Data Rate\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_datarate_e_str_P[getDataRate()]))); - printf_P(PSTR("Model\t\t= " PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_model_e_str_P[isPVariant()]))); - printf_P(PSTR("CRC Length\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_crclength_e_str_P[getCRCLength()]))); - printf_P(PSTR("PA Power\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_pa_dbm_e_str_P[getPALevel()]))); - printf_P(PSTR("ARC\t\t= %d\r\n"), getARC()); -} - -void RF24::printPrettyDetails(void) -{ - - #if defined(RF24_LINUX) - printf("================ SPI Configuration ================\n"); - uint8_t bus_ce = static_cast<uint8_t>(csn_pin % 10); - uint8_t bus_numb = static_cast<uint8_t>((csn_pin - bus_ce) / 10); - printf("CSN Pin\t\t\t= /dev/spidev%d.%d\n", bus_numb, bus_ce); - printf("CE Pin\t\t\t= Custom GPIO%d\n", ce_pin); - #endif - printf_P(PSTR("SPI Frequency\t\t= %d Mhz\n"), static_cast<uint8_t>(spi_speed / 1000000)); //Print the SPI speed on non-Linux devices - #if defined(RF24_LINUX) - printf("================ NRF Configuration ================\n"); - #endif // defined(RF24_LINUX) - - uint8_t channel = getChannel(); - uint16_t frequency = static_cast<uint16_t>(channel + 2400); - printf_P(PSTR("Channel\t\t\t= %u (~ %u MHz)\r\n"), channel, frequency); - printf_P(PSTR("Model\t\t\t= " PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_model_e_str_P[isPVariant()]))); - - printf_P(PSTR("RF Data Rate\t\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_datarate_e_str_P[getDataRate()]))); - printf_P(PSTR("RF Power Amplifier\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_pa_dbm_e_str_P[getPALevel()]))); - printf_P(PSTR("RF Low Noise Amplifier\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[(read_register(RF_SETUP) & 1) * 1]))); - printf_P(PSTR("CRC Length\t\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_crclength_e_str_P[getCRCLength()]))); - printf_P(PSTR("Address Length\t\t= %d bytes\r\n"), (read_register(SETUP_AW) & 3) + 2); - printf_P(PSTR("Static Payload Length\t= %d bytes\r\n"), getPayloadSize()); - - uint8_t setupRetry = read_register(SETUP_RETR); - printf_P(PSTR("Auto Retry Delay\t= %d microseconds\r\n"), (setupRetry >> ARD) * 250 + 250); - printf_P(PSTR("Auto Retry Attempts\t= %d maximum\r\n"), setupRetry & 0x0F); - - uint8_t observeTx = read_register(OBSERVE_TX); - printf_P(PSTR("Packets lost on\n current channel\t= %d\r\n"), observeTx >> 4); - printf_P(PSTR("Retry attempts made for\n last transmission\t= %d\r\n"), observeTx & 0x0F); - - uint8_t features = read_register(FEATURE); - printf_P(PSTR("Multicast\t\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[static_cast<bool>(features & _BV(EN_DYN_ACK)) * 2]))); - printf_P(PSTR("Custom ACK Payload\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[static_cast<bool>(features & _BV(EN_ACK_PAY)) * 1]))); - - uint8_t dynPl = read_register(DYNPD); - printf_P(PSTR("Dynamic Payloads\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[(dynPl && (features & _BV(EN_DPL))) * 1]))); - - uint8_t autoAck = read_register(EN_AA); - if (autoAck == 0x3F || autoAck == 0) { - // all pipes have the same configuration about auto-ack feature - printf_P(PSTR("Auto Acknowledgment\t" PRIPSTR - "\r\n"), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[static_cast<bool>(autoAck) * 1]))); - } - else { - // representation per pipe - printf_P(PSTR("Auto Acknowledgment\t= 0b%c%c%c%c%c%c\r\n"), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P5)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P4)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P3)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P2)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P1)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P0)) + 48)); - } - - config_reg = read_register(NRF_CONFIG); - printf_P(PSTR("Primary Mode\t\t= %cX\r\n"), config_reg & _BV(PRIM_RX) ? 'R' : 'T'); - print_address_register(PSTR("TX address\t"), TX_ADDR); - - uint8_t openPipes = read_register(EN_RXADDR); - for (uint8_t i = 0; i < 6; ++i) { - bool isOpen = openPipes & _BV(i); - printf_P(PSTR("pipe %u (" PRIPSTR - ") bound"), - i, (char*)(pgm_read_ptr(&rf24_feature_e_str_P[isOpen + 3]))); - if (i < 2) { - print_address_register(PSTR(""), static_cast<uint8_t>(RX_ADDR_P0 + i)); - } - else { - print_byte_register(PSTR(""), static_cast<uint8_t>(RX_ADDR_P0 + i)); - } - } -} - -/****************************************************************************/ - -uint16_t RF24::sprintfPrettyDetails(char* debugging_information) -{ - const char* format_string = PSTR( - "================ SPI Configuration ================\n" - "CSN Pin\t\t\t= %d\n" - "CE Pin\t\t\t= %d\n" - "SPI Frequency\t\t= %d Mhz\n" - "================ NRF Configuration ================\n" - "Channel\t\t\t= %u (~ %u MHz)\n" - "RF Data Rate\t\t" PRIPSTR "\n" - "RF Power Amplifier\t" PRIPSTR "\n" - "RF Low Noise Amplifier\t" PRIPSTR "\n" - "CRC Length\t\t" PRIPSTR "\n" - "Address Length\t\t= %d bytes\n" - "Static Payload Length\t= %d bytes\n" - "Auto Retry Delay\t= %d microseconds\n" - "Auto Retry Attempts\t= %d maximum\n" - "Packets lost on\n current channel\t= %d\r\n" - "Retry attempts made for\n last transmission\t= %d\r\n" - "Multicast\t\t" PRIPSTR "\n" - "Custom ACK Payload\t" PRIPSTR "\n" - "Dynamic Payloads\t" PRIPSTR "\n" - "Auto Acknowledgment\t"); - const char* format_str2 = PSTR("\nPrimary Mode\t\t= %cX\nTX address\t\t= 0x"); - const char* format_str3 = PSTR("\nPipe %d (" PRIPSTR ") bound\t= 0x"); - - uint16_t offset = sprintf_P( - debugging_information, format_string, csn_pin, ce_pin, - static_cast<uint8_t>(spi_speed / 1000000), getChannel(), - static_cast<uint16_t>(getChannel() + 2400), - (char*)(pgm_read_ptr(&rf24_datarate_e_str_P[getDataRate()])), - (char*)(pgm_read_ptr(&rf24_pa_dbm_e_str_P[getPALevel()])), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[(read_register(RF_SETUP) & 1) * 1])), - (char*)(pgm_read_ptr(&rf24_crclength_e_str_P[getCRCLength()])), - ((read_register(SETUP_AW) & 3) + 2), getPayloadSize(), - ((read_register(SETUP_RETR) >> ARD) * 250 + 250), - (read_register(SETUP_RETR) & 0x0F), (read_register(OBSERVE_TX) >> 4), - (read_register(OBSERVE_TX) & 0x0F), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[static_cast<bool>(read_register(FEATURE) & _BV(EN_DYN_ACK)) * 2])), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[static_cast<bool>(read_register(FEATURE) & _BV(EN_ACK_PAY)) * 1])), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[(read_register(DYNPD) && (read_register(FEATURE) & _BV(EN_DPL))) * 1]))); - uint8_t autoAck = read_register(EN_AA); - if (autoAck == 0x3F || autoAck == 0) { - // all pipes have the same configuration about auto-ack feature - offset += sprintf_P( - debugging_information + offset, PSTR("" PRIPSTR ""), - (char*)(pgm_read_ptr(&rf24_feature_e_str_P[static_cast<bool>(autoAck) * 1]))); - } - else { - // representation per pipe - offset += sprintf_P( - debugging_information + offset, PSTR("= 0b%c%c%c%c%c%c"), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P5)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P4)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P3)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P2)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P1)) + 48), - static_cast<char>(static_cast<bool>(autoAck & _BV(ENAA_P0)) + 48)); - } - offset += sprintf_P( - debugging_information + offset, format_str2, - (read_register(NRF_CONFIG) & _BV(PRIM_RX) ? 'R' : 'T')); - offset += sprintf_address_register(debugging_information + offset, TX_ADDR); - uint8_t openPipes = read_register(EN_RXADDR); - for (uint8_t i = 0; i < 6; ++i) { - offset += sprintf_P( - debugging_information + offset, format_str3, - i, ((char*)(pgm_read_ptr(&rf24_feature_e_str_P[static_cast<bool>(openPipes & _BV(i)) + 3])))); - if (i < 2) { - offset += sprintf_address_register( - debugging_information + offset, static_cast<uint8_t>(RX_ADDR_P0 + i)); - } - else { - offset += sprintf_P( - debugging_information + offset, PSTR("%02X"), - read_register(static_cast<uint8_t>(RX_ADDR_P0 + i))); - } - } - return offset; -} - -/****************************************************************************/ - -void RF24::encodeRadioDetails(uint8_t* encoded_details) -{ - uint8_t end = FEATURE + 1; - for (uint8_t i = NRF_CONFIG; i < end; ++i) { - if (i == RX_ADDR_P0 || i == RX_ADDR_P1 || i == TX_ADDR) { - // get 40-bit registers - read_register(i, encoded_details, 5); - encoded_details += 5; - } - else if (i != 0x18 && i != 0x19 && i != 0x1a && i != 0x1b) { // skip undocumented registers - // get single byte registers - *encoded_details++ = read_register(i); - } - } - *encoded_details++ = ce_pin >> 4; - *encoded_details++ = ce_pin & 0xFF; - *encoded_details++ = csn_pin >> 4; - *encoded_details++ = csn_pin & 0xFF; - *encoded_details = static_cast<uint8_t>((spi_speed / 1000000) | _BV(_is_p_variant * 4)); -} -#endif // !defined(MINIMAL) - -/****************************************************************************/ -#if defined(RF24_SPI_PTR) || defined(DOXYGEN_FORCED) -// does not apply to RF24_LINUX - -bool RF24::begin(_SPI* spiBus) -{ - _spi = spiBus; - return _init_pins() && _init_radio(); -} - -/****************************************************************************/ - -bool RF24::begin(_SPI* spiBus, uint16_t _cepin, uint16_t _cspin) -{ - ce_pin = _cepin; - csn_pin = _cspin; - return begin(spiBus); -} - -#endif // defined (RF24_SPI_PTR) || defined (DOXYGEN_FORCED) - -/****************************************************************************/ - -bool RF24::begin(uint16_t _cepin, uint16_t _cspin) -{ - ce_pin = _cepin; - csn_pin = _cspin; - return begin(); -} - -/****************************************************************************/ - -bool RF24::begin(void) -{ -#if defined(RF24_LINUX) - #if defined(RF24_RPi) - switch (csn_pin) { // Ensure valid hardware CS pin - case 0: break; - case 1: break; - // Allow BCM2835 enums for RPi - case 8: csn_pin = 0; break; - case 7: csn_pin = 1; break; - case 18: csn_pin = 10; break; // to make it work on SPI1 - case 17: csn_pin = 11; break; - case 16: csn_pin = 12; break; - default: csn_pin = 0; break; - } - #endif // RF24_RPi - - _SPI.begin(csn_pin, spi_speed); - -#elif defined(XMEGA_D3) - _spi->begin(csn_pin); - -#elif defined(RF24_RP2) - _spi->begin(PICO_DEFAULT_SPI ? spi1 : spi0); - -#else // using an Arduino platform || defined (LITTLEWIRE) - - #if defined(RF24_SPI_PTR) - _spi->begin(); - #else // !defined(RF24_SPI_PTR) - _SPI.begin(); - #endif // !defined(RF24_SPI_PTR) - -#endif // !defined(XMEGA_D3) && !defined(RF24_LINUX) - - return _init_pins() && _init_radio(); -} - -/****************************************************************************/ - -bool RF24::_init_pins() -{ - if (!isValid()) { - // didn't specify the CSN & CE pins to c'tor nor begin() - return false; - } - -#if defined(RF24_LINUX) - - #if defined(MRAA) - GPIO(); - gpio.begin(ce_pin, csn_pin); - #endif - - pinMode(ce_pin, OUTPUT); - ce(LOW); - delay(100); - -#elif defined(LITTLEWIRE) - pinMode(csn_pin, OUTPUT); - csn(HIGH); - -#elif defined(XMEGA_D3) - if (ce_pin != csn_pin) { - pinMode(ce_pin, OUTPUT); - }; - ce(LOW); - csn(HIGH); - delay(200); - -#else // using an Arduino platform - - // Initialize pins - if (ce_pin != csn_pin) { - pinMode(ce_pin, OUTPUT); - pinMode(csn_pin, OUTPUT); - } - - ce(LOW); - csn(HIGH); - - #if defined(__ARDUINO_X86__) - delay(100); - #endif -#endif // !defined(XMEGA_D3) && !defined(LITTLEWIRE) && !defined(RF24_LINUX) - - return true; // assuming pins are connected properly -} - -/****************************************************************************/ - -bool RF24::_init_radio() -{ - // Must allow the radio time to settle else configuration bits will not necessarily stick. - // This is actually only required following power up but some settling time also appears to - // be required after resets too. For full coverage, we'll always assume the worst. - // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped. - // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure. - // WARNING: Delay is based on P-variant whereby non-P *may* require different timing. - delay(5); - - // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier - // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet - // sizes must never be used. See datasheet for a more complete explanation. - setRetries(5, 15); - - // Then set the data rate to the slowest (and most reliable) speed supported by all hardware. - setDataRate(RF24_1MBPS); - - // detect if is a plus variant & use old toggle features command accordingly - uint8_t before_toggle = read_register(FEATURE); - toggle_features(); - uint8_t after_toggle = read_register(FEATURE); - _is_p_variant = before_toggle == after_toggle; - if (after_toggle) { - if (_is_p_variant) { - // module did not experience power-on-reset (#401) - toggle_features(); - } - // allow use of multicast parameter and dynamic payloads by default - write_register(FEATURE, 0); - } - ack_payloads_enabled = false; // ack payloads disabled by default - write_register(DYNPD, 0); // disable dynamic payloads by default (for all pipes) - dynamic_payloads_enabled = false; - write_register(EN_AA, 0x3F); // enable auto-ack on all pipes - write_register(EN_RXADDR, 3); // only open RX pipes 0 & 1 - setPayloadSize(32); // set static payload size to 32 (max) bytes by default - setAddressWidth(5); // set default address length to (max) 5 bytes - - // Set up default configuration. Callers can always change it later. - // This channel should be universally safe and not bleed over into adjacent - // spectrum. - setChannel(76); - - // Reset current status - // Notice reset and flush is the last thing we do - write_register(NRF_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); - - // Flush buffers - flush_rx(); - flush_tx(); - - // Clear CONFIG register: - // Reflect all IRQ events on IRQ pin - // Enable PTX - // Power Up - // 16-bit CRC (CRC required by auto-ack) - // Do not write CE high so radio will remain in standby I mode - // PTX should use only 22uA of power - write_register(NRF_CONFIG, (_BV(EN_CRC) | _BV(CRCO))); - config_reg = read_register(NRF_CONFIG); - - powerUp(); - - // if config is not set correctly then there was a bad response from module - return config_reg == (_BV(EN_CRC) | _BV(CRCO) | _BV(PWR_UP)) ? true : false; -} - -/****************************************************************************/ - -bool RF24::isChipConnected() -{ - return read_register(SETUP_AW) == (addr_width - static_cast<uint8_t>(2)); -} - -/****************************************************************************/ - -bool RF24::isValid() -{ - return ce_pin != 0xFFFF && csn_pin != 0xFFFF; -} - -/****************************************************************************/ - -void RF24::startListening(void) -{ -#if !defined(RF24_TINY) && !defined(LITTLEWIRE) - powerUp(); -#endif - config_reg |= _BV(PRIM_RX); - write_register(NRF_CONFIG, config_reg); - write_register(NRF_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); - ce(HIGH); - - // Restore the pipe0 address, if exists - if (_is_p0_rx) { - write_register(RX_ADDR_P0, pipe0_reading_address, addr_width); - } - else { - closeReadingPipe(0); - } -} - -/****************************************************************************/ - -static const PROGMEM uint8_t child_pipe_enable[] = {ERX_P0, ERX_P1, ERX_P2, - ERX_P3, ERX_P4, ERX_P5}; - -void RF24::stopListening(void) -{ - ce(LOW); - - //delayMicroseconds(100); - delayMicroseconds(static_cast<int>(txDelay)); - if (ack_payloads_enabled) { - flush_tx(); - } - - config_reg = static_cast<uint8_t>(config_reg & ~_BV(PRIM_RX)); - write_register(NRF_CONFIG, config_reg); - -#if defined(RF24_TINY) || defined(LITTLEWIRE) - // for 3 pins solution TX mode is only left with additional powerDown/powerUp cycle - if (ce_pin == csn_pin) { - powerDown(); - powerUp(); - } -#endif - write_register(EN_RXADDR, static_cast<uint8_t>(read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[0])))); // Enable RX on pipe0 -} - -/****************************************************************************/ - -void RF24::powerDown(void) -{ - ce(LOW); // Guarantee CE is low on powerDown - config_reg = static_cast<uint8_t>(config_reg & ~_BV(PWR_UP)); - write_register(NRF_CONFIG, config_reg); -} - -/****************************************************************************/ - -//Power up now. Radio will not power down unless instructed by MCU for config changes etc. -void RF24::powerUp(void) -{ - // if not powered up then power up and wait for the radio to initialize - if (!(config_reg & _BV(PWR_UP))) { - config_reg |= _BV(PWR_UP); - write_register(NRF_CONFIG, config_reg); - - // For nRF24L01+ to go from power down mode to TX or RX mode it must first pass through stand-by mode. - // There must be a delay of Tpd2stby (see Table 16.) after the nRF24L01+ leaves power down mode before - // the CEis set high. - Tpd2stby can be up to 5ms per the 1.0 datasheet - delayMicroseconds(RF24_POWERUP_DELAY); - } -} - -/******************************************************************/ -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - -void RF24::errNotify() -{ - #if defined(SERIAL_DEBUG) || defined(RF24_LINUX) - printf_P(PSTR("RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.\r\n")); - #endif - #if defined(FAILURE_HANDLING) - failureDetected = 1; - #else - delay(5000); - #endif -} - -#endif -/******************************************************************/ - -//Similar to the previous write, clears the interrupt flags -bool RF24::write(const void* buf, uint8_t len, const bool multicast) -{ - //Start Writing - startFastWrite(buf, len, multicast); - -//Wait until complete or failed -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - uint32_t timer = millis(); -#endif // defined(FAILURE_HANDLING) || defined(RF24_LINUX) - - while (!(get_status() & (_BV(TX_DS) | _BV(MAX_RT)))) { -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - if (millis() - timer > 95) { - errNotify(); - #if defined(FAILURE_HANDLING) - return 0; - #else - delay(100); - #endif - } -#endif - } - - ce(LOW); - - write_register(NRF_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); - - //Max retries exceeded - if (status & _BV(MAX_RT)) { - flush_tx(); // Only going to be 1 packet in the FIFO at a time using this method, so just flush - return 0; - } - //TX OK 1 or 0 - return 1; -} - -bool RF24::write(const void* buf, uint8_t len) -{ - return write(buf, len, 0); -} - -/****************************************************************************/ - -//For general use, the interrupt flags are not important to clear -bool RF24::writeBlocking(const void* buf, uint8_t len, uint32_t timeout) -{ - //Block until the FIFO is NOT full. - //Keep track of the MAX retries and set auto-retry if seeing failures - //This way the FIFO will fill up and allow blocking until packets go through - //The radio will auto-clear everything in the FIFO as long as CE remains high - - uint32_t timer = millis(); // Get the time that the payload transmission started - - while ((get_status() & (_BV(TX_FULL)))) { // Blocking only if FIFO is full. This will loop and block until TX is successful or timeout - - if (status & _BV(MAX_RT)) { // If MAX Retries have been reached - reUseTX(); // Set re-transmit and clear the MAX_RT interrupt flag - if (millis() - timer > timeout) { - return 0; // If this payload has exceeded the user-defined timeout, exit and return 0 - } - } -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - if (millis() - timer > (timeout + 95)) { - errNotify(); - #if defined(FAILURE_HANDLING) - return 0; - #endif - } -#endif - } - - //Start Writing - startFastWrite(buf, len, 0); // Write the payload if a buffer is clear - - return 1; // Return 1 to indicate successful transmission -} - -/****************************************************************************/ - -void RF24::reUseTX() -{ - write_register(NRF_STATUS, _BV(MAX_RT)); //Clear max retry flag - write_register(REUSE_TX_PL, RF24_NOP, true); - ce(LOW); //Re-Transfer packet - ce(HIGH); -} - -/****************************************************************************/ - -bool RF24::writeFast(const void* buf, uint8_t len, const bool multicast) -{ - //Block until the FIFO is NOT full. - //Keep track of the MAX retries and set auto-retry if seeing failures - //Return 0 so the user can control the retries and set a timer or failure counter if required - //The radio will auto-clear everything in the FIFO as long as CE remains high - -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - uint32_t timer = millis(); -#endif - - //Blocking only if FIFO is full. This will loop and block until TX is successful or fail - while ((get_status() & (_BV(TX_FULL)))) { - if (status & _BV(MAX_RT)) { - return 0; //Return 0. The previous payload has not been retransmitted - // From the user perspective, if you get a 0, call txStandBy() - } -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - if (millis() - timer > 95) { - errNotify(); - #if defined(FAILURE_HANDLING) - return 0; - #endif // defined(FAILURE_HANDLING) - } -#endif - } - startFastWrite(buf, len, multicast); // Start Writing - - return 1; -} - -bool RF24::writeFast(const void* buf, uint8_t len) -{ - return writeFast(buf, len, 0); -} - -/****************************************************************************/ - -//Per the documentation, we want to set PTX Mode when not listening. Then all we do is write data and set CE high -//In this mode, if we can keep the FIFO buffers loaded, packets will transmit immediately (no 130us delay) -//Otherwise we enter Standby-II mode, which is still faster than standby mode -//Also, we remove the need to keep writing the config register over and over and delaying for 150 us each time if sending a stream of data - -void RF24::startFastWrite(const void* buf, uint8_t len, const bool multicast, bool startTx) -{ //TMRh20 - - write_payload(buf, len, multicast ? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD); - if (startTx) { - ce(HIGH); - } -} - -/****************************************************************************/ - -//Added the original startWrite back in so users can still use interrupts, ack payloads, etc -//Allows the library to pass all tests -bool RF24::startWrite(const void* buf, uint8_t len, const bool multicast) -{ - - // Send the payload - write_payload(buf, len, multicast ? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD); - ce(HIGH); -#if !defined(F_CPU) || F_CPU > 20000000 - delayMicroseconds(10); -#endif - ce(LOW); - return !(status & _BV(TX_FULL)); -} - -/****************************************************************************/ - -bool RF24::rxFifoFull() -{ - return read_register(FIFO_STATUS) & _BV(RX_FULL); -} - -/****************************************************************************/ - -uint8_t RF24::isFifo(bool about_tx) -{ - return static_cast<uint8_t>((read_register(FIFO_STATUS) >> (4 * about_tx)) & 3); -} - -/****************************************************************************/ - -bool RF24::isFifo(bool about_tx, bool check_empty) -{ - return static_cast<bool>(isFifo(about_tx) & _BV(!check_empty)); -} - -/****************************************************************************/ - -bool RF24::txStandBy() -{ - -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - uint32_t timeout = millis(); -#endif - while (!(read_register(FIFO_STATUS) & _BV(TX_EMPTY))) { - if (status & _BV(MAX_RT)) { - write_register(NRF_STATUS, _BV(MAX_RT)); - ce(LOW); - flush_tx(); //Non blocking, flush the data - return 0; - } -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - if (millis() - timeout > 95) { - errNotify(); - #if defined(FAILURE_HANDLING) - return 0; - #endif - } -#endif - } - - ce(LOW); //Set STANDBY-I mode - return 1; -} - -/****************************************************************************/ - -bool RF24::txStandBy(uint32_t timeout, bool startTx) -{ - - if (startTx) { - stopListening(); - ce(HIGH); - } - uint32_t start = millis(); - - while (!(read_register(FIFO_STATUS) & _BV(TX_EMPTY))) { - if (status & _BV(MAX_RT)) { - write_register(NRF_STATUS, _BV(MAX_RT)); - ce(LOW); // Set re-transmit - ce(HIGH); - if (millis() - start >= timeout) { - ce(LOW); - flush_tx(); - return 0; - } - } -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - if (millis() - start > (timeout + 95)) { - errNotify(); - #if defined(FAILURE_HANDLING) - return 0; - #endif - } -#endif - } - - ce(LOW); //Set STANDBY-I mode - return 1; -} - -/****************************************************************************/ - -void RF24::maskIRQ(bool tx, bool fail, bool rx) -{ - /* clear the interrupt flags */ - config_reg = static_cast<uint8_t>(config_reg & ~(1 << MASK_MAX_RT | 1 << MASK_TX_DS | 1 << MASK_RX_DR)); - /* set the specified interrupt flags */ - config_reg = static_cast<uint8_t>(config_reg | fail << MASK_MAX_RT | tx << MASK_TX_DS | rx << MASK_RX_DR); - write_register(NRF_CONFIG, config_reg); -} - -/****************************************************************************/ - -uint8_t RF24::getDynamicPayloadSize(void) -{ - uint8_t result = read_register(R_RX_PL_WID); - - if (result > 32) { - flush_rx(); - delay(2); - return 0; - } - return result; -} - -/****************************************************************************/ - -bool RF24::available(void) -{ - return available(NULL); -} - -/****************************************************************************/ - -bool RF24::available(uint8_t* pipe_num) -{ - // get implied RX FIFO empty flag from status byte - uint8_t pipe = (get_status() >> RX_P_NO) & 0x07; - if (pipe > 5) - return 0; - - // If the caller wants the pipe number, include that - if (pipe_num) - *pipe_num = pipe; - - return 1; -} - -/****************************************************************************/ - -void RF24::read(void* buf, uint8_t len) -{ - - // Fetch the payload - read_payload(buf, len); - - //Clear the only applicable interrupt flags - write_register(NRF_STATUS, _BV(RX_DR)); -} - -/****************************************************************************/ - -void RF24::whatHappened(bool& tx_ok, bool& tx_fail, bool& rx_ready) -{ - // Read the status & reset the status in one easy call - // Or is that such a good idea? - write_register(NRF_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); - - // Report to the user what happened - tx_ok = status & _BV(TX_DS); - tx_fail = status & _BV(MAX_RT); - rx_ready = status & _BV(RX_DR); -} - -/****************************************************************************/ - -void RF24::openWritingPipe(uint64_t value) -{ - // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+) - // expects it LSB first too, so we're good. - - write_register(RX_ADDR_P0, reinterpret_cast<uint8_t*>(&value), addr_width); - write_register(TX_ADDR, reinterpret_cast<uint8_t*>(&value), addr_width); -} - -/****************************************************************************/ - -void RF24::openWritingPipe(const uint8_t* address) -{ - // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+) - // expects it LSB first too, so we're good. - write_register(RX_ADDR_P0, address, addr_width); - write_register(TX_ADDR, address, addr_width); -} - -/****************************************************************************/ - -static const PROGMEM uint8_t child_pipe[] = {RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, - RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5}; - -void RF24::openReadingPipe(uint8_t child, uint64_t address) -{ - // If this is pipe 0, cache the address. This is needed because - // openWritingPipe() will overwrite the pipe 0 address, so - // startListening() will have to restore it. - if (child == 0) { - memcpy(pipe0_reading_address, &address, addr_width); - _is_p0_rx = true; - } - - if (child <= 5) { - // For pipes 2-5, only write the LSB - if (child < 2) { - write_register(pgm_read_byte(&child_pipe[child]), reinterpret_cast<const uint8_t*>(&address), addr_width); - } - else { - write_register(pgm_read_byte(&child_pipe[child]), reinterpret_cast<const uint8_t*>(&address), 1); - } - - // Note it would be more efficient to set all of the bits for all open - // pipes at once. However, I thought it would make the calling code - // more simple to do it this way. - write_register(EN_RXADDR, static_cast<uint8_t>(read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[child])))); - } -} - -/****************************************************************************/ - -void RF24::setAddressWidth(uint8_t a_width) -{ - a_width = static_cast<uint8_t>(a_width - 2); - if (a_width) { - write_register(SETUP_AW, static_cast<uint8_t>(a_width % 4)); - addr_width = static_cast<uint8_t>((a_width % 4) + 2); - } - else { - write_register(SETUP_AW, static_cast<uint8_t>(0)); - addr_width = static_cast<uint8_t>(2); - } -} - -/****************************************************************************/ - -void RF24::openReadingPipe(uint8_t child, const uint8_t* address) -{ - // If this is pipe 0, cache the address. This is needed because - // openWritingPipe() will overwrite the pipe 0 address, so - // startListening() will have to restore it. - if (child == 0) { - memcpy(pipe0_reading_address, address, addr_width); - _is_p0_rx = true; - } - if (child <= 5) { - // For pipes 2-5, only write the LSB - if (child < 2) { - write_register(pgm_read_byte(&child_pipe[child]), address, addr_width); - } - else { - write_register(pgm_read_byte(&child_pipe[child]), address, 1); - } - - // Note it would be more efficient to set all of the bits for all open - // pipes at once. However, I thought it would make the calling code - // more simple to do it this way. - write_register(EN_RXADDR, static_cast<uint8_t>(read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[child])))); - } -} - -/****************************************************************************/ - -void RF24::closeReadingPipe(uint8_t pipe) -{ - write_register(EN_RXADDR, static_cast<uint8_t>(read_register(EN_RXADDR) & ~_BV(pgm_read_byte(&child_pipe_enable[pipe])))); - if (!pipe) { - // keep track of pipe 0's RX state to avoid null vs 0 in addr cache - _is_p0_rx = false; - } -} - -/****************************************************************************/ - -void RF24::toggle_features(void) -{ - beginTransaction(); -#if defined(RF24_SPI_PTR) - status = _spi->transfer(ACTIVATE); - _spi->transfer(0x73); -#else - status = _SPI.transfer(ACTIVATE); - _SPI.transfer(0x73); -#endif - endTransaction(); -} - -/****************************************************************************/ - -void RF24::enableDynamicPayloads(void) -{ - // Enable dynamic payload throughout the system - - //toggle_features(); - write_register(FEATURE, read_register(FEATURE) | _BV(EN_DPL)); - - IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n", read_register(FEATURE))); - - // Enable dynamic payload on all pipes - // - // Not sure the use case of only having dynamic payload on certain - // pipes, so the library does not support it. - write_register(DYNPD, read_register(DYNPD) | _BV(DPL_P5) | _BV(DPL_P4) | _BV(DPL_P3) | _BV(DPL_P2) | _BV(DPL_P1) | _BV(DPL_P0)); - - dynamic_payloads_enabled = true; -} - -/****************************************************************************/ - -void RF24::disableDynamicPayloads(void) -{ - // Disables dynamic payload throughout the system. Also disables Ack Payloads - - //toggle_features(); - write_register(FEATURE, 0); - - IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n", read_register(FEATURE))); - - // Disable dynamic payload on all pipes - // - // Not sure the use case of only having dynamic payload on certain - // pipes, so the library does not support it. - write_register(DYNPD, 0); - - dynamic_payloads_enabled = false; - ack_payloads_enabled = false; -} - -/****************************************************************************/ - -void RF24::enableAckPayload(void) -{ - // enable ack payloads and dynamic payload features - - if (!ack_payloads_enabled) { - write_register(FEATURE, read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL)); - - IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n", read_register(FEATURE))); - - // Enable dynamic payload on pipes 0 & 1 - write_register(DYNPD, read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0)); - dynamic_payloads_enabled = true; - ack_payloads_enabled = true; - } -} - -/****************************************************************************/ - -void RF24::disableAckPayload(void) -{ - // disable ack payloads (leave dynamic payload features as is) - if (ack_payloads_enabled) { - write_register(FEATURE, static_cast<uint8_t>(read_register(FEATURE) & ~_BV(EN_ACK_PAY))); - - IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n", read_register(FEATURE))); - - ack_payloads_enabled = false; - } -} - -/****************************************************************************/ - -void RF24::enableDynamicAck(void) -{ - // - // enable dynamic ack features - // - //toggle_features(); - write_register(FEATURE, read_register(FEATURE) | _BV(EN_DYN_ACK)); - - IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n", read_register(FEATURE))); -} - -/****************************************************************************/ - -bool RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) -{ - if (ack_payloads_enabled) { - const uint8_t* current = reinterpret_cast<const uint8_t*>(buf); - - write_payload(current, len, W_ACK_PAYLOAD | (pipe & 0x07)); - return !(status & _BV(TX_FULL)); - } - return 0; -} - -/****************************************************************************/ - -bool RF24::isAckPayloadAvailable(void) -{ - return available(NULL); -} - -/****************************************************************************/ - -bool RF24::isPVariant(void) -{ - return _is_p_variant; -} - -/****************************************************************************/ - -void RF24::setAutoAck(bool enable) -{ - if (enable) { - write_register(EN_AA, 0x3F); - } - else { - write_register(EN_AA, 0); - // accommodate ACK payloads feature - if (ack_payloads_enabled) { - disableAckPayload(); - } - } -} - -/****************************************************************************/ - -void RF24::setAutoAck(uint8_t pipe, bool enable) -{ - if (pipe < 6) { - uint8_t en_aa = read_register(EN_AA); - if (enable) { - en_aa |= static_cast<uint8_t>(_BV(pipe)); - } - else { - en_aa = static_cast<uint8_t>(en_aa & ~_BV(pipe)); - if (ack_payloads_enabled && !pipe) { - disableAckPayload(); - } - } - write_register(EN_AA, en_aa); - } -} - -/****************************************************************************/ - -bool RF24::testCarrier(void) -{ - return (read_register(CD) & 1); -} - -/****************************************************************************/ - -bool RF24::testRPD(void) -{ - return (read_register(RPD) & 1); -} - -/****************************************************************************/ - -void RF24::setPALevel(uint8_t level, bool lnaEnable) -{ - uint8_t setup = read_register(RF_SETUP) & static_cast<uint8_t>(0xF8); - setup |= _pa_level_reg_value(level, lnaEnable); - write_register(RF_SETUP, setup); -} - -/****************************************************************************/ - -uint8_t RF24::getPALevel(void) -{ - return (read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH))) >> 1; -} - -/****************************************************************************/ - -uint8_t RF24::getARC(void) -{ - return read_register(OBSERVE_TX) & 0x0F; -} - -/****************************************************************************/ - -bool RF24::setDataRate(rf24_datarate_e speed) -{ - bool result = false; - uint8_t setup = read_register(RF_SETUP); - - // HIGH and LOW '00' is 1Mbs - our default - setup = static_cast<uint8_t>(setup & ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH))); - setup |= _data_rate_reg_value(speed); - - write_register(RF_SETUP, setup); - - // Verify our result - if (read_register(RF_SETUP) == setup) { - result = true; - } - return result; -} - -/****************************************************************************/ - -rf24_datarate_e RF24::getDataRate(void) -{ - rf24_datarate_e result; - uint8_t dr = read_register(RF_SETUP) & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)); - - // switch uses RAM (evil!) - // Order matters in our case below - if (dr == _BV(RF_DR_LOW)) { - // '10' = 250KBPS - result = RF24_250KBPS; - } - else if (dr == _BV(RF_DR_HIGH)) { - // '01' = 2MBPS - result = RF24_2MBPS; - } - else { - // '00' = 1MBPS - result = RF24_1MBPS; - } - return result; -} - -/****************************************************************************/ - -void RF24::setCRCLength(rf24_crclength_e length) -{ - config_reg = static_cast<uint8_t>(config_reg & ~(_BV(CRCO) | _BV(EN_CRC))); - - // switch uses RAM (evil!) - if (length == RF24_CRC_DISABLED) { - // Do nothing, we turned it off above. - } - else if (length == RF24_CRC_8) { - config_reg |= _BV(EN_CRC); - } - else { - config_reg |= _BV(EN_CRC); - config_reg |= _BV(CRCO); - } - write_register(NRF_CONFIG, config_reg); -} - -/****************************************************************************/ - -rf24_crclength_e RF24::getCRCLength(void) -{ - rf24_crclength_e result = RF24_CRC_DISABLED; - uint8_t AA = read_register(EN_AA); - config_reg = read_register(NRF_CONFIG); - - if (config_reg & _BV(EN_CRC) || AA) { - if (config_reg & _BV(CRCO)) { - result = RF24_CRC_16; - } - else { - result = RF24_CRC_8; - } - } - - return result; -} - -/****************************************************************************/ - -void RF24::disableCRC(void) -{ - config_reg = static_cast<uint8_t>(config_reg & ~_BV(EN_CRC)); - write_register(NRF_CONFIG, config_reg); -} - -/****************************************************************************/ -void RF24::setRetries(uint8_t delay, uint8_t count) -{ - write_register(SETUP_RETR, static_cast<uint8_t>(rf24_min(15, delay) << ARD | rf24_min(15, count))); -} - -/****************************************************************************/ -void RF24::startConstCarrier(rf24_pa_dbm_e level, uint8_t channel) -{ - stopListening(); - write_register(RF_SETUP, read_register(RF_SETUP) | _BV(CONT_WAVE) | _BV(PLL_LOCK)); - if (isPVariant()) { - setAutoAck(0); - setRetries(0, 0); - uint8_t dummy_buf[32]; - for (uint8_t i = 0; i < 32; ++i) - dummy_buf[i] = 0xFF; - - // use write_register() instead of openWritingPipe() to bypass - // truncation of the address with the current RF24::addr_width value - write_register(TX_ADDR, reinterpret_cast<uint8_t*>(&dummy_buf), 5); - flush_tx(); // so we can write to top level - - // use write_register() instead of write_payload() to bypass - // truncation of the payload with the current RF24::payload_size value - write_register(W_TX_PAYLOAD, reinterpret_cast<const uint8_t*>(&dummy_buf), 32); - - disableCRC(); - } - setPALevel(level); - setChannel(channel); - IF_SERIAL_DEBUG(printf_P(PSTR("RF_SETUP=%02x\r\n"), read_register(RF_SETUP))); - ce(HIGH); - if (isPVariant()) { - delay(1); // datasheet says 1 ms is ok in this instance - ce(LOW); - reUseTX(); - } -} - -/****************************************************************************/ - -void RF24::stopConstCarrier() -{ - /* - * A note from the datasheet: - * Do not use REUSE_TX_PL together with CONT_WAVE=1. When both these - * registers are set the chip does not react when setting CE low. If - * however, both registers are set PWR_UP = 0 will turn TX mode off. - */ - powerDown(); // per datasheet recommendation (just to be safe) - write_register(RF_SETUP, static_cast<uint8_t>(read_register(RF_SETUP) & ~_BV(CONT_WAVE) & ~_BV(PLL_LOCK))); - ce(LOW); -} - -/****************************************************************************/ - -void RF24::toggleAllPipes(bool isEnabled) -{ - write_register(EN_RXADDR, static_cast<uint8_t>(isEnabled ? 0x3F : 0)); -} - -/****************************************************************************/ - -uint8_t RF24::_data_rate_reg_value(rf24_datarate_e speed) -{ -#if !defined(F_CPU) || F_CPU > 20000000 - txDelay = 280; -#else //16Mhz Arduino - txDelay = 85; -#endif - if (speed == RF24_250KBPS) { -#if !defined(F_CPU) || F_CPU > 20000000 - txDelay = 505; -#else //16Mhz Arduino - txDelay = 155; -#endif - // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0 - // Making it '10'. - return static_cast<uint8_t>(_BV(RF_DR_LOW)); - } - else if (speed == RF24_2MBPS) { -#if !defined(F_CPU) || F_CPU > 20000000 - txDelay = 240; -#else // 16Mhz Arduino - txDelay = 65; -#endif - // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1 - // Making it '01' - return static_cast<uint8_t>(_BV(RF_DR_HIGH)); - } - // HIGH and LOW '00' is 1Mbs - our default - return static_cast<uint8_t>(0); -} - -/****************************************************************************/ - -uint8_t RF24::_pa_level_reg_value(uint8_t level, bool lnaEnable) -{ - // If invalid level, go to max PA - // Else set level as requested - // + lnaEnable (1 or 0) to support the SI24R1 chip extra bit - return static_cast<uint8_t>(((level > RF24_PA_MAX ? static_cast<uint8_t>(RF24_PA_MAX) : level) << 1) + lnaEnable); -} - -/****************************************************************************/ - -void RF24::setRadiation(uint8_t level, rf24_datarate_e speed, bool lnaEnable) -{ - uint8_t setup = _data_rate_reg_value(speed); - setup |= _pa_level_reg_value(level, lnaEnable); - write_register(RF_SETUP, setup); -} diff --git a/RF24/RF24.h b/RF24/RF24.h deleted file mode 100644 index df939a3a4caf08bbe724509ac6c516458b888000..0000000000000000000000000000000000000000 --- a/RF24/RF24.h +++ /dev/null @@ -1,2417 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - */ - -/** - * @file RF24.h - * - * Class declaration for RF24 and helper enums - */ - -#ifndef __RF24_H__ -#define __RF24_H__ - -#include "RF24_config.h" - -#if defined(RF24_LINUX) || defined(LITTLEWIRE) - #include "utility/includes.h" -#elif defined SOFTSPI - #include <DigitalIO.h> -#endif - -/** - * @defgroup PALevel Power Amplifier level - * Power Amplifier level. The units dBm (decibel-milliwatts or dB<sub>mW</sub>) - * represents a logarithmic signal loss. - * @see - * - RF24::setPALevel() - * - RF24::getPALevel() - * @{ - */ -typedef enum -{ - /** - * (0) represents: - * nRF24L01 | Si24R1 with<br>lnaEnabled = 1 | Si24R1 with<br>lnaEnabled = 0 - * :-------:|:-----------------------------:|:----------------------------: - * -18 dBm | -6 dBm | -12 dBm - */ - RF24_PA_MIN = 0, - /** - * (1) represents: - * nRF24L01 | Si24R1 with<br>lnaEnabled = 1 | Si24R1 with<br>lnaEnabled = 0 - * :-------:|:-----------------------------:|:----------------------------: - * -12 dBm | 0 dBm | -4 dBm - */ - RF24_PA_LOW, - /** - * (2) represents: - * nRF24L01 | Si24R1 with<br>lnaEnabled = 1 | Si24R1 with<br>lnaEnabled = 0 - * :-------:|:-----------------------------:|:----------------------------: - * -6 dBm | 3 dBm | 1 dBm - */ - RF24_PA_HIGH, - /** - * (3) represents: - * nRF24L01 | Si24R1 with<br>lnaEnabled = 1 | Si24R1 with<br>lnaEnabled = 0 - * :-------:|:-----------------------------:|:----------------------------: - * 0 dBm | 7 dBm | 4 dBm - */ - RF24_PA_MAX, - /** - * (4) This should not be used and remains for backward compatibility. - */ - RF24_PA_ERROR -} rf24_pa_dbm_e; - -/** - * @} - * @defgroup Datarate datarate - * How fast data moves through the air. Units are in bits per second (bps). - * @see - * - RF24::setDataRate() - * - RF24::getDataRate() - * @{ - */ -typedef enum -{ - /** (0) represents 1 Mbps */ - RF24_1MBPS = 0, - /** (1) represents 2 Mbps */ - RF24_2MBPS, - /** (2) represents 250 kbps */ - RF24_250KBPS -} rf24_datarate_e; - -/** - * @} - * @defgroup CRCLength CRC length - * The length of a CRC checksum that is used (if any). Cyclical Redundancy - * Checking (CRC) is commonly used to ensure data integrity. - * @see - * - RF24::setCRCLength() - * - RF24::getCRCLength() - * - RF24::disableCRC() - * @{ - */ -typedef enum -{ - /** (0) represents no CRC checksum is used */ - RF24_CRC_DISABLED = 0, - /** (1) represents CRC 8 bit checksum is used */ - RF24_CRC_8, - /** (2) represents CRC 16 bit checksum is used */ - RF24_CRC_16 -} rf24_crclength_e; - -/** - * @} - * @brief Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver - */ -class RF24 -{ -private: -#ifdef SOFTSPI - SoftSPI<SOFT_SPI_MISO_PIN, SOFT_SPI_MOSI_PIN, SOFT_SPI_SCK_PIN, SPI_MODE> spi; -#elif defined(SPI_UART) - SPIUARTClass uspi; -#endif - -#if defined(RF24_LINUX) || defined(XMEGA_D3) || defined(RF24_RP2) /* XMEGA can use SPI class */ - SPI spi; -#endif // defined (RF24_LINUX) || defined (XMEGA_D3) -#if defined(RF24_SPI_PTR) - _SPI* _spi; -#endif // defined (RF24_SPI_PTR) -#if defined(MRAA) - GPIO gpio; -#endif - - uint16_t ce_pin; /* "Chip Enable" pin, activates the RX or TX role */ - uint16_t csn_pin; /* SPI Chip select */ - uint32_t spi_speed; /* SPI Bus Speed */ -#if defined(RF24_LINUX) || defined(XMEGA_D3) || defined(RF24_RP2) - uint8_t spi_rxbuff[32 + 1]; //SPI receive buffer (payload max 32 bytes) - uint8_t spi_txbuff[32 + 1]; //SPI transmit buffer (payload max 32 bytes + 1 byte for the command) -#endif - uint8_t status; /* The status byte returned from every SPI transaction */ - uint8_t payload_size; /* Fixed size of payloads */ - uint8_t pipe0_reading_address[5]; /* Last address set on pipe 0 for reading. */ - uint8_t config_reg; /* For storing the value of the NRF_CONFIG register */ - bool _is_p_variant; /* For storing the result of testing the toggleFeatures() affect */ - bool _is_p0_rx; /* For keeping track of pipe 0's usage in user-triggered RX mode. */ - -protected: - /** - * SPI transactions - * - * Common code for SPI transactions including CSN toggle - * - */ - inline void beginTransaction(); - - inline void endTransaction(); - - /** Whether ack payloads are enabled. */ - bool ack_payloads_enabled; - /** The address width to use (3, 4 or 5 bytes). */ - uint8_t addr_width; - /** Whether dynamic payloads are enabled. */ - bool dynamic_payloads_enabled; - - /** - * Read a chunk of data in from a register - * - * @param reg Which register. Use constants from nRF24L01.h - * @param[out] buf Where to put the data - * @param len How many bytes of data to transfer - * @note This returns nothing. Older versions of this function returned the status - * byte, but that it now saved to a private member on all SPI transactions. - */ - void read_register(uint8_t reg, uint8_t* buf, uint8_t len); - - /** - * Read single byte from a register - * - * @param reg Which register. Use constants from nRF24L01.h - * @return Current value of register @p reg - */ - uint8_t read_register(uint8_t reg); - -public: - /** - * @name Primary public interface - * - * These are the main methods you need to operate the chip - */ - /**@{*/ - - /** - * RF24 Constructor - * - * Creates a new instance of this driver. Before using, you create an instance - * and send in the unique pins that this chip is connected to. - * - * See [Related Pages](pages.html) for device specific information - * - * @param _cepin The pin attached to Chip Enable on the RF module - * @param _cspin The pin attached to Chip Select (often labeled CSN) on the radio module. - * - For the Arduino Due board, the [Arduino Due extended SPI feature](https://www.arduino.cc/en/Reference/DueExtendedSPI) - * is not supported. This means that the Due's pins 4, 10, or 52 are not mandated options (can use any digital output pin) for the radio's CSN pin. - * @param _spi_speed The SPI speed in Hz ie: 1000000 == 1Mhz - * - Users can specify default SPI speed by modifying @ref RF24_SPI_SPEED in @ref RF24_config.h - * - For Arduino, the default SPI speed will only be properly configured this way on devices supporting SPI TRANSACTIONS - * - Older/Unsupported Arduino devices will use a default clock divider & settings configuration - * - For Linux: The old way of setting SPI speeds using BCM2835 driver enums has been removed as of v1.3.7 - */ - RF24(uint16_t _cepin, uint16_t _cspin, uint32_t _spi_speed = RF24_SPI_SPEED); - - /** - * A constructor for initializing the radio's hardware dynamically - * @warning You MUST use begin(uint16_t, uint16_t) or begin(_SPI*, uint16_t, uint16_t) to pass both the digital output pin - * numbers connected to the radio's CE and CSN pins. - * @param _spi_speed The SPI speed in Hz ie: 1000000 == 1Mhz - * - Users can specify default SPI speed by modifying @ref RF24_SPI_SPEED in @ref RF24_config.h - * - For Arduino, the default SPI speed will only be properly configured this way on devices supporting SPI TRANSACTIONS - * - Older/Unsupported Arduino devices will use a default clock divider & settings configuration - * - For Linux: The old way of setting SPI speeds using BCM2835 driver enums has been removed as of v1.3.7 - */ - RF24(uint32_t _spi_speed = RF24_SPI_SPEED); - -#if defined(RF24_LINUX) - virtual ~RF24() {}; -#endif - - /** - * Begin operation of the chip - * - * Call this in setup(), before calling any other methods. - * @code - * if (!radio.begin()) { - * Serial.println(F("radio hardware not responding!")); - * while (1) {} // hold program in infinite loop to prevent subsequent errors - * } - * @endcode - * @return - * - `true` if the radio was successfully initialized - * - `false` if the MCU failed to communicate with the radio hardware - */ - bool begin(void); - -#if defined(RF24_SPI_PTR) || defined(DOXYGEN_FORCED) - /** - * Same as begin(), but allows specifying a non-default SPI bus to use. - * - * @note This function assumes the `SPI::begin()` method was called before to - * calling this function. - * - * @warning This function is for the Arduino platforms only - * - * @param spiBus A pointer or reference to an instantiated SPI bus object. - * The `_SPI` datatype is a "wrapped" definition that will represent - * various SPI implementations based on the specified platform. - * @see Review the [Arduino support page](md_docs_arduino.html). - * - * @return same result as begin() - */ - bool begin(_SPI* spiBus); - - /** - * Same as begin(), but allows dynamically specifying a SPI bus, CE pin, - * and CSN pin to use. - * - * @note This function assumes the `SPI::begin()` method was called before to - * calling this function. - * - * @warning This function is for the Arduino platforms only - * - * @param spiBus A pointer or reference to an instantiated SPI bus object. - * The `_SPI` datatype is a "wrapped" definition that will represent - * various SPI implementations based on the specified platform. - * @param _cepin The pin attached to Chip Enable on the RF module - * @param _cspin The pin attached to Chip Select (often labeled CSN) on the radio module. - * - For the Arduino Due board, the [Arduino Due extended SPI feature](https://www.arduino.cc/en/Reference/DueExtendedSPI) - * is not supported. This means that the Due's pins 4, 10, or 52 are not mandated options (can use any digital output pin) for the radio's CSN pin. - * - * @see Review the [Arduino support page](md_docs_arduino.html). - * - * @return same result as begin() - */ - bool begin(_SPI* spiBus, uint16_t _cepin, uint16_t _cspin); -#endif // defined (RF24_SPI_PTR) || defined (DOXYGEN_FORCED) - - /** - * Same as begin(), but allows dynamically specifying a CE pin - * and CSN pin to use. - * @param _cepin The pin attached to Chip Enable on the RF module - * @param _cspin The pin attached to Chip Select (often labeled CSN) on the radio module. - * - For the Arduino Due board, the [Arduino Due extended SPI feature](https://www.arduino.cc/en/Reference/DueExtendedSPI) - * is not supported. This means that the Due's pins 4, 10, or 52 are not mandated options (can use any digital output pin) for the radio's CSN pin. - * @return same result as begin() - */ - bool begin(uint16_t _cepin, uint16_t _cspin); - - /** - * Checks if the chip is connected to the SPI bus - */ - bool isChipConnected(); - - /** - * Start listening on the pipes opened for reading. - * - * 1. Be sure to call openReadingPipe() first. - * 2. Do not call write() while in this mode, without first calling stopListening(). - * 3. Call available() to check for incoming traffic, and read() to get it. - * - * Open reading pipe 1 using address `0xCCCECCCECC` - * @code - * byte address[] = {0xCC, 0xCE, 0xCC, 0xCE, 0xCC}; - * radio.openReadingPipe(1,address); - * radio.startListening(); - * @endcode - * - * @note If there was a call to openReadingPipe() about pipe 0 prior to - * calling this function, then this function will re-write the address - * that was last set to reading pipe 0. This is because openWritingPipe() - * will overwrite the address to reading pipe 0 for proper auto-ack - * functionality. - */ - void startListening(void); - - /** - * Stop listening for incoming messages, and switch to transmit mode. - * - * Do this before calling write(). - * @code - * radio.stopListening(); - * radio.write(&data, sizeof(data)); - * @endcode - * - * @note When the ACK payloads feature is enabled, the TX FIFO buffers are - * flushed when calling this function. This is meant to discard any ACK - * payloads that were not appended to acknowledgment packets. - */ - void stopListening(void); - - /** - * Check whether there are bytes available to be read - * @code - * if(radio.available()){ - * radio.read(&data,sizeof(data)); - * } - * @endcode - * - * @see available(uint8_t*) - * - * @return True if there is a payload available, false if none is - * - * @warning This function relies on the information about the pipe number - * that received the next available payload. According to the datasheet, - * the data about the pipe number that received the next available payload - * is "unreliable" during a FALLING transition on the IRQ pin. This means - * you should call whatHappened() before calling this function - * during an ISR (Interrupt Service Routine). For example: - * @code - * void isrCallbackFunction() { - * bool tx_ds, tx_df, rx_dr; - * radio.whatHappened(tx_ds, tx_df, rx_dr); // resets the IRQ pin to HIGH - * radio.available(); // returned data should now be reliable - * } - * - * void setup() { - * pinMode(IRQ_PIN, INPUT); - * attachInterrupt(digitalPinToInterrupt(IRQ_PIN), isrCallbackFunction, FALLING); - * } - * @endcode - */ - bool available(void); - - /** - * Read payload data from the RX FIFO buffer(s). - * - * The length of data read is usually the next available payload's length - * @see - * - getPayloadSize() - * - getDynamicPayloadSize() - * - * @note I specifically chose `void*` as a data type to make it easier - * for beginners to use. No casting needed. - * - * @param buf Pointer to a buffer where the data should be written - * @param len Maximum number of bytes to read into the buffer. This - * value should match the length of the object referenced using the - * `buf` parameter. The absolute maximum number of bytes that can be read - * in one call is 32 (for dynamic payload lengths) or whatever number was - * previously passed to setPayloadSize() (for static payload lengths). - * @remark - * @parblock - * Remember that each call to read() fetches data from the - * RX FIFO beginning with the first byte from the first available - * payload. A payload is not removed from the RX FIFO until it's - * entire length (or more) is fetched using read(). - * - * - If `len` parameter's value is less than the available payload's - * length, then the payload remains in the RX FIFO. - * - If `len` parameter's value is greater than the first of multiple - * available payloads, then the data saved to the `buf` - * parameter's object will be supplemented with data from the next - * available payload. - * - If `len` parameter's value is greater than the last available - * payload's length, then the last byte in the payload is used as - * padding for the data saved to the `buf` parameter's object. - * The nRF24L01 will repeatedly use the last byte from the last - * payload even when read() is called with an empty RX FIFO. - * @endparblock - * @note To use this function in the python wrapper, remember that - * only the `len` parameter is required because this function (in the - * python wrapper) returns the payload data as a buffer protocol object - * (bytearray object). - * @code{.py} - * # let `radio` be the instantiated RF24 object - * if radio.available(): - * length = radio.getDynamicPayloadSize() # or radio.getPayloadSize() for static payload sizes - * received_payload = radio.read(length) - * @endcode - * - * @note This function no longer returns a boolean. Use available to - * determine if packets are available. The `RX_DR` Interrupt flag is now - * cleared with this function instead of when calling available(). - * @code - * if(radio.available()) { - * radio.read(&data, sizeof(data)); - * } - * @endcode - */ - void read(void* buf, uint8_t len); - - /** - * Be sure to call openWritingPipe() first to set the destination - * of where to write to. - * - * This blocks until the message is successfully acknowledged by - * the receiver or the timeout/retransmit maxima are reached. In - * the current configuration, the max delay here is 60-70ms. - * - * The maximum size of data written is the fixed payload size, see - * getPayloadSize(). However, you can write less, and the remainder - * will just be filled with zeroes. - * - * TX/RX/RT interrupt flags will be cleared every time write is called - * - * @param buf Pointer to the data to be sent - * @param len Number of bytes to be sent - * - * @code - * radio.stopListening(); - * radio.write(&data,sizeof(data)); - * @endcode - * - * @note The `len` parameter must be omitted when using the python - * wrapper because the length of the payload is determined automatically. - * To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * buffer = b"Hello World" # a `bytes` object - * radio.write(buffer) - * @endcode - * - * @return - * - `true` if the payload was delivered successfully and an acknowledgement - * (ACK packet) was received. If auto-ack is disabled, then any attempt - * to transmit will also return true (even if the payload was not - * received). - * - `false` if the payload was sent but was not acknowledged with an ACK - * packet. This condition can only be reported if the auto-ack feature - * is on. - */ - bool write(const void* buf, uint8_t len); - - /** - * New: Open a pipe for writing via byte array. Old addressing format retained - * for compatibility. - * - * Only one writing pipe can be opened at once, but this function changes - * the address that is used to transmit (ACK payloads/packets do not apply - * here). Be sure to call stopListening() prior to calling this function. - * - * Addresses are assigned via a byte array, default is 5 byte address length - * - * @code - * uint8_t addresses[][6] = {"1Node", "2Node"}; - * radio.openWritingPipe(addresses[0]); - * @endcode - * @code - * uint8_t address[] = { 0xCC, 0xCE, 0xCC, 0xCE, 0xCC }; - * radio.openWritingPipe(address); - * address[0] = 0x33; - * radio.openReadingPipe(1, address); - * @endcode - * - * @warning This function will overwrite the address set to reading pipe 0 - * as stipulated by the datasheet for proper auto-ack functionality in TX - * mode. Use this function to ensure proper transmission acknowledgement - * when the address set to reading pipe 0 (via openReadingPipe()) does not - * match the address passed to this function. If the auto-ack feature is - * disabled, then this function will still overwrite the address for - * reading pipe 0 regardless. - * - * @see - * - setAddressWidth() - * - startListening() - * - * @param address The address to be used for outgoing transmissions (uses - * pipe 0). Coordinate this address amongst other receiving nodes (the - * pipe numbers don't need to match). - * - * @remark There is no address length parameter because this function will - * always write the number of bytes that the radio addresses are configured - * to use (set with setAddressWidth()). - */ - - void openWritingPipe(const uint8_t* address); - - /** - * Open a pipe for reading - * - * Up to 6 pipes can be open for reading at once. Open all the required - * reading pipes, and then call startListening(). - * - * @see - * - openWritingPipe() - * - setAddressWidth() - * - * @note Pipes 0 and 1 will store a full 5-byte address. Pipes 2-5 will technically - * only store a single byte, borrowing up to 4 additional bytes from pipe 1 per the - * assigned address width. - * Pipes 1-5 should share the same address, except the first byte. - * Only the first byte in the array should be unique, e.g. - * @code - * uint8_t addresses[][6] = {"Prime", "2Node", "3xxxx", "4xxxx"}; - * openReadingPipe(0, addresses[0]); // address used is "Prime" - * openReadingPipe(1, addresses[1]); // address used is "2Node" - * openReadingPipe(2, addresses[2]); // address used is "3Node" - * openReadingPipe(3, addresses[3]); // address used is "4Node" - * @endcode - * - * @warning - * @parblock - * If the reading pipe 0 is opened by this function, the address - * passed to this function (for pipe 0) will be restored at every call to - * startListening(). - * - * Read - * http://maniacalbits.blogspot.com/2013/04/rf24-addressing-nrf24l01-radios-require.html - * to understand how to avoid using malformed addresses. This address - * restoration is implemented because of the underlying necessary - * functionality of openWritingPipe(). - * @endparblock - * - * @param number Which pipe to open. Only pipe numbers 0-5 are available, - * an address assigned to any pipe number not in that range will be ignored. - * @param address The 24, 32 or 40 bit address of the pipe to open. - * - * There is no address length parameter because this function will - * always write the number of bytes (for pipes 0 and 1) that the radio - * addresses are configured to use (set with setAddressWidth()). - */ - void openReadingPipe(uint8_t number, const uint8_t* address); - - /**@}*/ - /** - * @name Advanced Operation - * - * Methods you can use to drive the chip in more advanced ways - */ - /**@{*/ - - /** - * Print a giant block of debugging information to stdout - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - * The printf.h file is included with the library for Arduino. - * @code - * #include <printf.h> - * setup(){ - * Serial.begin(115200); - * printf_begin(); - * ... - * } - * @endcode - */ - void printDetails(void); - - /** - * Print a giant block of debugging information to stdout. This function - * differs from printDetails() because it makes the information more - * understandable without having to look up the datasheet or convert - * hexadecimal to binary. Only use this function if your application can - * spare extra bytes of memory. - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - * The printf.h file is included with the library for Arduino. - * @code - * #include <printf.h> - * setup(){ - * Serial.begin(115200); - * printf_begin(); - * // ... - * } - * @endcode - * - * @note If the automatic acknowledgements feature is configured differently - * for each pipe, then a binary representation is used in which bits 0-5 - * represent pipes 0-5 respectively. A `0` means the feature is disabled, and - * a `1` means the feature is enabled. - */ - void printPrettyDetails(void); - - /** - * Put a giant block of debugging information in a char array. This function - * differs from printPrettyDetails() because it uses `sprintf()` and does not use - * a predefined output stream (like `Serial` or stdout). Only use this function if - * your application can spare extra bytes of memory. This can also be used for boards that - * do not support `printf()` (which is required for printDetails() and printPrettyDetails()). - * - * @remark - * The C standard function [sprintf()](http://www.cplusplus.com/reference/cstdio/sprintf) - * formats a C-string in the exact same way as `printf()` but outputs (by reference) - * into a char array. The formatted string literal for sprintf() is stored - * in nonvolatile program memory. - * - * @warning Use a buffer of sufficient size for the `debugging_information`. Start - * with a char array that has at least 870 elements. There is no overflow protection when using - * sprintf(), so the output buffer must be sized correctly or the resulting behavior will - * be undefined. - * @code - * char buffer[870] = {'\0'}; - * uint16_t used_chars = radio.sprintfPrettyDetails(buffer); - * Serial.println(buffer); - * Serial.print(F("strlen = ")); - * Serial.println(used_chars + 1); // +1 for c-strings' null terminating byte - * @endcode - * - * @param debugging_information The c-string buffer that the debugging - * information is stored to. This must be allocated to a minimum of 870 bytes of memory. - * @returns The number of characters altered in the given buffer. Remember that, - * like `sprintf()`, this returned number does not include the null terminating byte. - * - * This function is available in the python wrapper, but it accepts no parameters and - * returns a string. It does not return the number of characters in the string. - * @code{.py} - * debug_info = radio.sprintfPrettyDetails() - * print(debug_info) - * print("str_len =", len(debug_info)) - * @endcode - * - * @note If the automatic acknowledgements feature is configured differently - * for each pipe, then a binary representation is used in which bits 0-5 - * represent pipes 0-5 respectively. A `0` means the feature is disabled, and - * a `1` means the feature is enabled. - */ - uint16_t sprintfPrettyDetails(char* debugging_information); - - /** - * Encode radio debugging information into an array of uint8_t. This function - * differs from other debug output methods because the debug information can - * be decoded by an external program. - * - * This function is not available in the python wrapper because it is intended for - * use on processors with very limited available resources. - * - * @remark - * This function uses much less ram than other `*print*Details()` methods. - * - * @code - * uint8_t encoded_details[43] = {0}; - * radio.encodeRadioDetails(encoded_details); - * @endcode - * - * @param encoded_status The uint8_t array that RF24 radio details are - * encoded into. This array must be at least 43 bytes in length; any less would surely - * cause undefined behavior. - * - * Registers names and/or data corresponding to the index of the `encoded_details` array: - * | index | register/data | - * |------:|:--------------| - * | 0 | NRF_CONFIG | - * | 1 | EN_AA | - * | 2 | EN_RXADDR | - * | 3 | SETUP_AW | - * | 4 | SETUP_RETR | - * | 5 | RF_CH | - * | 6 | RF_SETUP | - * | 7 | NRF_STATUS | - * | 8 | OBSERVE_TX | - * | 9 | CD (aka RPD) | - * | 10-14 | RX_ADDR_P0 | - * | 15-19 | RX_ADDR_P1 | - * | 20 | RX_ADDR_P2 | - * | 21 | RX_ADDR_P3 | - * | 22 | RX_ADDR_P4 | - * | 23 | RX_ADDR_P5 | - * | 24-28 | TX_ADDR | - * | 29 | RX_PW_P0 | - * | 30 | RX_PW_P1 | - * | 31 | RX_PW_P2 | - * | 32 | RX_PW_P3 | - * | 33 | RX_PW_P4 | - * | 34 | RX_PW_P5 | - * | 35 | FIFO_STATUS | - * | 36 | DYNPD | - * | 37 | FEATURE | - * | 38-39 | ce_pin | - * | 40-41 | csn_pin | - * | 42 | SPI speed (in MHz) or'd with (isPlusVariant << 4) | - */ - void encodeRadioDetails(uint8_t* encoded_status); - - /** - * Test whether there are bytes available to be read from the - * FIFO buffers. - * - * @note This function is named `available_pipe()` in the python wrapper. - * @parblock - * Additionally, the `available_pipe()` function (which - * takes no arguments) returns a 2 item tuple containing (ordered by - * tuple's indices): - * - A boolean describing if there is a payload available to read from - * the RX FIFO buffers. - * - The pipe number that received the next available payload in the RX - * FIFO buffers. If the item at the tuple's index 0 is `False`, then - * this pipe number is invalid. - * - * To use this function in python: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * has_payload, pipe_number = radio.available_pipe() # expand the tuple to 2 variables - * if has_payload: - * print("Received a payload with pipe", pipe_number) - * @endcode - * @endparblock - * - * @param[out] pipe_num Which pipe has the payload available - * @code - * uint8_t pipeNum; - * if(radio.available(&pipeNum)){ - * radio.read(&data, sizeof(data)); - * Serial.print("Received data on pipe "); - * Serial.println(pipeNum); - * } - * @endcode - * - * @warning According to the datasheet, the data saved to `pipe_num` is - * "unreliable" during a FALLING transition on the IRQ pin. This means you - * should call whatHappened() before calling this function during - * an ISR (Interrupt Service Routine). For example: - * @code - * void isrCallbackFunction() { - * bool tx_ds, tx_df, rx_dr; - * radio.whatHappened(tx_ds, tx_df, rx_dr); // resets the IRQ pin to HIGH - * uint8_t pipe; // initialize pipe data - * radio.available(&pipe); // pipe data should now be reliable - * } - * - * void setup() { - * pinMode(IRQ_PIN, INPUT); - * attachInterrupt(digitalPinToInterrupt(IRQ_PIN), isrCallbackFunction, FALLING); - * } - * @endcode - * - * @return - * - `true` if there is a payload available in the top (first out) - * level RX FIFO. - * - `false` if there is nothing available in the RX FIFO because it is - * empty. - */ - bool available(uint8_t* pipe_num); - - /** - * Use this function to check if the radio's RX FIFO levels are all - * occupied. This can be used to prevent data loss because any incoming - * transmissions are rejected if there is no unoccupied levels in the RX - * FIFO to store the incoming payload. Remember that each level can hold - * up to a maximum of 32 bytes. - * @return - * - `true` if all three 3 levels of the RX FIFO buffers are occupied. - * - `false` if there is one or more levels available in the RX FIFO - * buffers. Remember that this does not always mean that the RX FIFO - * buffers are empty; use available() to see if the RX FIFO buffers are - * empty or not. - */ - bool rxFifoFull(); - - /** - * @param about_tx `true` focuses on the TX FIFO, `false` focuses on the RX FIFO - * @return - * - `0` if the specified FIFO is neither full nor empty. - * - `1` if the specified FIFO is empty. - * - `2` if the specified FIFO is full. - */ - uint8_t isFifo(bool about_tx); - - /** - * @param about_tx `true` focuses on the TX FIFO, `false` focuses on the RX FIFO - * @param check_empty - * - `true` checks if the specified FIFO is empty - * - `false` checks is the specified FIFO is full. - * @return A boolean answer to the question "is the [TX/RX] FIFO [empty/full]?" - */ - bool isFifo(bool about_tx, bool check_empty); - - /** - * Enter low-power mode - * - * To return to normal power mode, call powerUp(). - * - * @note After calling startListening(), a basic radio will consume about 13.5mA - * at max PA level. - * During active transmission, the radio will consume about 11.5mA, but this will - * be reduced to 26uA (.026mA) between sending. - * In full powerDown mode, the radio will consume approximately 900nA (.0009mA) - * - * @code - * radio.powerDown(); - * avr_enter_sleep_mode(); // Custom function to sleep the device - * radio.powerUp(); - * @endcode - */ - void powerDown(void); - - /** - * Leave low-power mode - required for normal radio operation after calling powerDown() - * - * To return to low power mode, call powerDown(). - * @note This will take up to 5ms for maximum compatibility - */ - void powerUp(void); - - /** - * Write for single NOACK writes. Optionally disable - * acknowledgements/auto-retries for a single payload using the - * multicast parameter set to true. - * - * Can be used with enableAckPayload() to request a response - * @see - * - setAutoAck() - * - write() - * - * @param buf Pointer to the data to be sent - * @param len Number of bytes to be sent - * @param multicast Request ACK response (false), or no ACK response - * (true). Be sure to have called enableDynamicAck() at least once before - * setting this parameter. - * @return - * - `true` if the payload was delivered successfully and an acknowledgement - * (ACK packet) was received. If auto-ack is disabled, then any attempt - * to transmit will also return true (even if the payload was not - * received). - * - `false` if the payload was sent but was not acknowledged with an ACK - * packet. This condition can only be reported if the auto-ack feature - * is on. - * - * @note The `len` parameter must be omitted when using the python - * wrapper because the length of the payload is determined automatically. - * To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * buffer = b"Hello World" # a `bytes` object - * radio.write(buffer, False) # False = the multicast parameter - * @endcode - */ - bool write(const void* buf, uint8_t len, const bool multicast); - - /** - * This will not block until the 3 FIFO buffers are filled with data. - * Once the FIFOs are full, writeFast() will simply wait for a buffer to - * become available or a transmission failure (returning `true` or `false` - * respectively). - * - * @warning - * @parblock - * It is important to never keep the nRF24L01 in TX mode and FIFO full for more than 4ms at a time. If the auto - * retransmit is enabled, the nRF24L01 is never in TX mode long enough to disobey this rule. Allow the FIFO - * to clear by issuing txStandBy() or ensure appropriate time between transmissions. - * - * Use txStandBy() when this function returns `false`. - * - * Example (Partial blocking): - * @code - * radio.writeFast(&buf,32); // Writes 1 payload to the buffers - * txStandBy(); // Returns 0 if failed. 1 if success. Blocks only until MAX_RT timeout or success. Data flushed on fail. - * - * radio.writeFast(&buf,32); // Writes 1 payload to the buffers - * txStandBy(1000); // Using extended timeouts, returns 1 if success. Retries failed payloads for 1 seconds before returning 0. - * @endcode - * @endparblock - * - * @see - * - setAutoAck() - * - txStandBy() - * - write() - * - writeBlocking() - * - * @param buf Pointer to the data to be sent - * @param len Number of bytes to be sent - * @return - * - `true` if the payload passed to `buf` was loaded in the TX FIFO. - * - `false` if the payload passed to `buf` was not loaded in the TX FIFO - * because a previous payload already in the TX FIFO failed to - * transmit. This condition can only be reported if the auto-ack feature - * is on. - * - * @note The `len` parameter must be omitted when using the python - * wrapper because the length of the payload is determined automatically. - * To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * buffer = b"Hello World" # a `bytes` object - * radio.writeFast(buffer) - * @endcode - */ - bool writeFast(const void* buf, uint8_t len); - - /** - * Similar to writeFast(const void*, uint8_t) but allows for single NOACK writes. - * Optionally disable acknowledgements/auto-retries for a single payload using the - * multicast parameter set to `true`. - * - * @warning If the auto-ack feature is enabled, then it is strongly encouraged to call - * txStandBy() when this function returns `false`. - * - * @see - * - setAutoAck() - * - txStandBy() - * - write() - * - writeBlocking() - * - * @param buf Pointer to the data to be sent - * @param len Number of bytes to be sent - * @param multicast Request ACK response (false), or no ACK response - * (true). Be sure to have called enableDynamicAck() at least once before - * setting this parameter. - * @return - * - `true` if the payload passed to `buf` was loaded in the TX FIFO. - * - `false` if the payload passed to `buf` was not loaded in the TX FIFO - * because a previous payload already in the TX FIFO failed to - * transmit. This condition can only be reported if the auto-ack feature - * is on (and the multicast parameter is set to false). - * - * @note The `len` parameter must be omitted when using the python - * wrapper because the length of the payload is determined automatically. - * To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * buffer = b"Hello World" # a `bytes` object - * radio.writeFast(buffer, False) # False = the multicast parameter - * @endcode - */ - bool writeFast(const void* buf, uint8_t len, const bool multicast); - - /** - * This function extends the auto-retry mechanism to any specified duration. - * It will not block until the 3 FIFO buffers are filled with data. - * If so the library will auto retry until a new payload is written - * or the user specified timeout period is reached. - * @warning It is important to never keep the nRF24L01 in TX mode and FIFO full for more than 4ms at a time. If the auto - * retransmit is enabled, the nRF24L01 is never in TX mode long enough to disobey this rule. Allow the FIFO - * to clear by issuing txStandBy() or ensure appropriate time between transmissions. - * - * Example (Full blocking): - * @code - * radio.writeBlocking(&buf, sizeof(buf), 1000); // Wait up to 1 second to write 1 payload to the buffers - * radio.txStandBy(1000); // Wait up to 1 second for the payload to send. Return 1 if ok, 0 if failed. - * // Blocks only until user timeout or success. Data flushed on fail. - * @endcode - * @note If used from within an interrupt, the interrupt should be disabled until completion, and sei(); called to enable millis(). - * @see - * - txStandBy() - * - write() - * - writeFast() - * - * @param buf Pointer to the data to be sent - * @param len Number of bytes to be sent - * @param timeout User defined timeout in milliseconds. - * - * @note The `len` parameter must be omitted when using the python - * wrapper because the length of the payload is determined automatically. - * To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * buffer = b"Hello World" # a `bytes` object - * radio.writeBlocking(buffer, 1000) # 1000 means wait at most 1 second - * @endcode - * - * @return - * - `true` if the payload passed to `buf` was loaded in the TX FIFO. - * - `false` if the payload passed to `buf` was not loaded in the TX FIFO - * because a previous payload already in the TX FIFO failed to - * transmit. This condition can only be reported if the auto-ack feature - * is on. - */ - bool writeBlocking(const void* buf, uint8_t len, uint32_t timeout); - - /** - * This function should be called as soon as transmission is finished to - * drop the radio back to STANDBY-I mode. If not issued, the radio will - * remain in STANDBY-II mode which, per the data sheet, is not a recommended - * operating mode. - * - * @note When transmitting data in rapid succession, it is still recommended by - * the manufacturer to drop the radio out of TX or STANDBY-II mode if there is - * time enough between sends for the FIFOs to empty. This is not required if auto-ack - * is enabled. - * - * Relies on built-in auto retry functionality. - * - * Example (Partial blocking): - * @code - * radio.writeFast(&buf, 32); - * radio.writeFast(&buf, 32); - * radio.writeFast(&buf, 32); //Fills the FIFO buffers up - * bool ok = radio.txStandBy(); //Returns 0 if failed. 1 if success. - * //Blocks only until MAX_RT timeout or success. Data flushed on fail. - * @endcode - * @see txStandBy(uint32_t timeout, bool startTx) - * @return - * - `true` if all payloads in the TX FIFO were delivered successfully and - * an acknowledgement (ACK packet) was received for each. If auto-ack is - * disabled, then any attempt to transmit will also return true (even if - * the payload was not received). - * - `false` if a payload was sent but was not acknowledged with an ACK - * packet. This condition can only be reported if the auto-ack feature - * is on. - */ - bool txStandBy(); - - /** - * This function allows extended blocking and auto-retries per a user defined timeout - * - * Fully Blocking Example: - * @code - * radio.writeFast(&buf, 32); - * radio.writeFast(&buf, 32); - * radio.writeFast(&buf, 32); //Fills the FIFO buffers up - * bool ok = radio.txStandBy(1000); //Returns 0 if failed after 1 second of retries. 1 if success. - * //Blocks only until user defined timeout or success. Data flushed on fail. - * @endcode - * @note If used from within an interrupt, the interrupt should be disabled until completion, and sei(); called to enable millis(). - * @param timeout Number of milliseconds to retry failed payloads - * @param startTx If this is set to `true`, then this function puts the nRF24L01 - * in TX Mode. `false` leaves the primary mode (TX or RX) as it is, which can - * prevent the mandatory wait time to change modes. - * @return - * - `true` if all payloads in the TX FIFO were delivered successfully and - * an acknowledgement (ACK packet) was received for each. If auto-ack is - * disabled, then any attempt to transmit will also return true (even if - * the payload was not received). - * - `false` if a payload was sent but was not acknowledged with an ACK - * packet. This condition can only be reported if the auto-ack feature - * is on. - */ - bool txStandBy(uint32_t timeout, bool startTx = 0); - - /** - * Write an acknowledgement (ACK) payload for the specified pipe - * - * The next time a message is received on a specified `pipe`, the data in - * `buf` will be sent back in the ACK payload. - * - * @see - * - enableAckPayload() - * - enableDynamicPayloads() - * - * @note ACK payloads are handled automatically by the radio chip when a - * regular payload is received. It is important to discard regular payloads - * in the TX FIFO (using flush_tx()) before loading the first ACK payload - * into the TX FIFO. This function can be called before and after calling - * startListening(). - * - * @warning Only three of these can be pending at any time as there are - * only 3 FIFO buffers. Dynamic payloads must be enabled. - * - * @note ACK payloads are dynamic payloads. Calling enableAckPayload() - * will automatically enable dynamic payloads on pipe 0 (required for TX - * mode when expecting ACK payloads) & pipe 1. To use ACK payloads on any other - * pipe in RX mode, call enableDynamicPayloads(). - * - * @param pipe Which pipe# (typically 1-5) will get this response. - * @param buf Pointer to data that is sent - * @param len Length of the data to send, up to 32 bytes max. Not affected - * by the static payload size set by setPayloadSize(). - * - * @note The `len` parameter must be omitted when using the python - * wrapper because the length of the payload is determined automatically. - * To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * buffer = b"Hello World" # a `bytes` object - * radio.writeAckPayload(1, buffer) # load an ACK payload for response on pipe 1 - * @endcode - * - * @return - * - `true` if the payload was loaded into the TX FIFO. - * - `false` if the payload wasn't loaded into the TX FIFO because it is - * already full or the ACK payload feature is not enabled using - * enableAckPayload(). - */ - bool writeAckPayload(uint8_t pipe, const void* buf, uint8_t len); - - /** - * Call this when you get an Interrupt Request (IRQ) to find out why - * - * This function describes what event triggered the IRQ pin to go active - * LOW and clears the status of all events. - * - * @see maskIRQ() - * - * @param[out] tx_ok The transmission attempt completed (TX_DS). This does - * not imply that the transmitted data was received by another radio, rather - * this only reports if the attempt to send was completed. This will - * always be `true` when the auto-ack feature is disabled. - * @param[out] tx_fail The transmission failed to be acknowledged, meaning - * too many retries (MAX_RT) were made while expecting an ACK packet. This - * event is only triggered when auto-ack feature is enabled. - * @param[out] rx_ready There is a newly received payload (RX_DR) saved to - * RX FIFO buffers. Remember that the RX FIFO can only hold up to 3 - * payloads. Once the RX FIFO is full, all further received transmissions - * are rejected until there is space to save new data in the RX FIFO - * buffers. - * - * @note This function expects no parameters in the python wrapper. - * Instead, this function returns a 3 item tuple describing the IRQ - * events' status. To use this function in the python wrapper: - * @code{.py} - * # let`radio` be the instantiated RF24 object - * tx_ds, tx_df, rx_dr = radio.whatHappened() # get IRQ status flags - * print("tx_ds: {}, tx_df: {}, rx_dr: {}".format(tx_ds, tx_df, rx_dr)) - * @endcode - */ - void whatHappened(bool& tx_ok, bool& tx_fail, bool& rx_ready); - - /** - * Non-blocking write to the open writing pipe used for buffered writes - * - * @note Optimization: This function now leaves the CE pin high, so the radio - * will remain in TX or STANDBY-II Mode until a txStandBy() command is issued. Can be used as an alternative to startWrite() - * if writing multiple payloads at once. - * @warning It is important to never keep the nRF24L01 in TX mode with FIFO full for more than 4ms at a time. If the auto - * retransmit/autoAck is enabled, the nRF24L01 is never in TX mode long enough to disobey this rule. Allow the FIFO - * to clear by issuing txStandBy() or ensure appropriate time between transmissions. - * - * @see - * - write() - * - writeFast() - * - startWrite() - * - writeBlocking() - * - setAutoAck() (for single noAck writes) - * - * @param buf Pointer to the data to be sent - * @param len Number of bytes to be sent - * @param multicast Request ACK response (false), or no ACK response - * (true). Be sure to have called enableDynamicAck() at least once before - * setting this parameter. - * @param startTx If this is set to `true`, then this function sets the - * nRF24L01's CE pin to active (enabling TX transmissions). `false` has no - * effect on the nRF24L01's CE pin and simply loads the payload into the - * TX FIFO. - * - * @note The `len` parameter must be omitted when using the python - * wrapper because the length of the payload is determined automatically. - * To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * buffer = b"Hello World" # a `bytes` object - * radio.startFastWrite(buffer, False, True) # 3rd parameter is optional - * # False means expecting ACK response (multicast parameter) - * # True means initiate transmission (startTx parameter) - * @endcode - */ - void startFastWrite(const void* buf, uint8_t len, const bool multicast, bool startTx = 1); - - /** - * Non-blocking write to the open writing pipe - * - * Just like write(), but it returns immediately. To find out what happened - * to the send, catch the IRQ and then call whatHappened(). - * - * @see - * - write() - * - writeFast() - * - startFastWrite() - * - whatHappened() - * - setAutoAck() (for single noAck writes) - * - * @param buf Pointer to the data to be sent - * @param len Number of bytes to be sent - * @param multicast Request ACK response (false), or no ACK response - * (true). Be sure to have called enableDynamicAck() at least once before - * setting this parameter. - * - * @return - * - `true` if payload was written to the TX FIFO buffers and the - * transmission was started. - * - `false` if the TX FIFO is full and the payload could not be written. In - * this condition, the transmission process is restarted. - * @note The `len` parameter must be omitted when using the python - * wrapper because the length of the payload is determined automatically. - * To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * buffer = b"Hello World" # a `bytes` object - * radio.startWrite(buffer, False) # False = the multicast parameter - * @endcode - */ - bool startWrite(const void* buf, uint8_t len, const bool multicast); - - /** - * The function will instruct the radio to re-use the payload in the - * top level (first out) of the TX FIFO buffers. This is used internally - * by writeBlocking() to initiate retries when a TX failure - * occurs. Retries are automatically initiated except with the standard - * write(). This way, data is not flushed from the buffer until calling - * flush_tx(). If the TX FIFO has only the one payload (in the top level), - * the re-used payload can be overwritten by using write(), writeFast(), - * writeBlocking(), startWrite(), or startFastWrite(). If the TX FIFO has - * other payloads enqueued, then the aforementioned functions will attempt - * to enqueue the a new payload in the TX FIFO (does not overwrite the top - * level of the TX FIFO). Currently, stopListening() also calls flush_tx() - * when ACK payloads are enabled (via enableAckPayload()). - * - * Upon exiting, this function will set the CE pin HIGH to initiate the - * re-transmission process. If only 1 re-transmission is desired, then the - * CE pin should be set to LOW after the mandatory minumum pulse duration - * of 10 microseconds. - * - * @remark This function only applies when taking advantage of the - * auto-retry feature. See setAutoAck() and setRetries() to configure the - * auto-retry feature. - * - * @note This is to be used AFTER auto-retry fails if wanting to resend - * using the built-in payload reuse feature. After issuing reUseTX(), it - * will keep resending the same payload until a transmission failure - * occurs or the CE pin is set to LOW (whichever comes first). In the - * event of a re-transmission failure, simply call this function again to - * resume re-transmission of the same payload. - */ - void reUseTX(); - - /** - * Empty all 3 of the TX (transmit) FIFO buffers. This is automatically - * called by stopListening() if ACK payloads are enabled. However, - * startListening() does not call this function. - * - * @return Current value of status register - */ - uint8_t flush_tx(void); - - /** - * Empty all 3 of the RX (receive) FIFO buffers. - * - * @return Current value of status register - */ - uint8_t flush_rx(void); - - /** - * Test whether there was a carrier on the line for the - * previous listening period. - * - * Useful to check for interference on the current channel. - * - * @return true if was carrier, false if not - */ - bool testCarrier(void); - - /** - * Test whether a signal (carrier or otherwise) greater than - * or equal to -64dBm is present on the channel. Valid only - * on nRF24L01P (+) hardware. On nRF24L01, use testCarrier(). - * - * Useful to check for interference on the current channel and - * channel hopping strategies. - * - * @code - * bool goodSignal = radio.testRPD(); - * if(radio.available()){ - * Serial.println(goodSignal ? "Strong signal > 64dBm" : "Weak signal < 64dBm" ); - * radio.read(0,0); - * } - * @endcode - * @return true if a signal less than or equal to -64dBm was detected, - * false if not. - */ - bool testRPD(void); - - /** - * Test whether this is a real radio, or a mock shim for - * debugging. Setting either pin to 0xff is the way to - * indicate that this is not a real radio. - * - * @return true if this is a legitimate radio - */ - bool isValid(); - - /** - * Close a pipe after it has been previously opened. - * Can be safely called without having previously opened a pipe. - * @param pipe Which pipe number to close, any integer not in range [0, 5] - * is ignored. - */ - void closeReadingPipe(uint8_t pipe); - -#if defined(FAILURE_HANDLING) - /** - * - * If a failure has been detected, it usually indicates a hardware issue. By default the library - * will cease operation when a failure is detected. - * This should allow advanced users to detect and resolve intermittent hardware issues. - * - * In most cases, the radio must be re-enabled via radio.begin(); and the appropriate settings - * applied after a failure occurs, if wanting to re-enable the device immediately. - * - * The three main failure modes of the radio include: - * - * 1. Writing to radio: Radio unresponsive - * - Fixed internally by adding a timeout to the internal write functions in RF24 (failure handling) - * 2. Reading from radio: Available returns true always - * - Fixed by adding a timeout to available functions by the user. This is implemented internally in RF24Network. - * 3. Radio configuration settings are lost - * - Fixed by monitoring a value that is different from the default, and re-configuring the radio if this setting reverts to the default. - * - * See the included example, GettingStarted_HandlingFailures - * - * @code - * if(radio.failureDetected) { - * radio.begin(); // Attempt to re-configure the radio with defaults - * radio.failureDetected = 0; // Reset the detection value - * radio.openWritingPipe(addresses[1]); // Re-configure pipe addresses - * radio.openReadingPipe(1, addresses[0]); - * report_failure(); // Blink LEDs, send a message, etc. to indicate failure - * } - * @endcode - */ - bool failureDetected; -#endif // defined (FAILURE_HANDLING) - - /**@}*/ - /** - * @name Optional Configurators - * - * Methods you can use to get or set the configuration of the chip. - * None are required. Calling begin() sets up a reasonable set of - * defaults. - */ - /**@{*/ - - /** - * Set the address width from 3 to 5 bytes (24, 32 or 40 bit) - * - * @param a_width The address width (in bytes) to use; this can be 3, 4 or - * 5. - */ - void setAddressWidth(uint8_t a_width); - - /** - * Set the number of retry attempts and delay between retry attempts when - * transmitting a payload. The radio is waiting for an acknowledgement - * (ACK) packet during the delay between retry attempts. - * - * @param delay How long to wait between each retry, in multiples of - * 250 us. The minumum of 0 means 250 us, and the maximum of 15 means - * 4000 us. The default value of 5 means 1500us (5 * 250 + 250). - * @param count How many retries before giving up. The default/maximum is 15. Use - * 0 to disable the auto-retry feature all together. - * - * @note Disable the auto-retry feature on a transmitter still uses the - * auto-ack feature (if enabled), except it will not retry to transmit if - * the payload was not acknowledged on the first attempt. - */ - void setRetries(uint8_t delay, uint8_t count); - - /** - * Set RF communication channel. The frequency used by a channel is - * calculated as: - * @verbatim 2400 MHz + <channel number> @endverbatim - * Meaning the default channel of 76 uses the approximate frequency of - * 2476 MHz. - * - * @note In the python wrapper, this function is the setter of the - * `channel` attribute.To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * radio.channel = 2 # set the channel to 2 (2402 MHz) - * @endcode - * - * @param channel Which RF channel to communicate on, 0-125 - */ - void setChannel(uint8_t channel); - - /** - * Get RF communication channel - * - * @note In the python wrapper, this function is the getter of the - * `channel` attribute.To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * chn = radio.channel # get the channel - * @endcode - * - * @return The currently configured RF Channel - */ - uint8_t getChannel(void); - - /** - * Set Static Payload Size - * - * This implementation uses a pre-established fixed payload size for all - * transmissions. If this method is never called, the driver will always - * transmit the maximum payload size (32 bytes), no matter how much - * was sent to write(). - * - * @note In the python wrapper, this function is the setter of the - * `payloadSize` attribute.To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * radio.payloadSize = 16 # set the static payload size to 16 bytes - * @endcode - * - * @param size The number of bytes in the payload - */ - void setPayloadSize(uint8_t size); - - /** - * Get Static Payload Size - * - * @note In the python wrapper, this function is the getter of the - * `payloadSize` attribute.To use this function in the python wrapper: - * @code{.py} - * # let `radio` be the instantiated RF24 object - * pl_size = radio.payloadSize # get the static payload size - * @endcode - * - * @see setPayloadSize() - * - * @return The number of bytes in the payload - */ - uint8_t getPayloadSize(void); - - /** - * Get Dynamic Payload Size - * - * For dynamic payloads, this pulls the size of the payload off - * the chip - * - * @note Corrupt packets are now detected and flushed per the - * manufacturer. - * @code - * if(radio.available()){ - * if(radio.getDynamicPayloadSize() < 1){ - * // Corrupt payload has been flushed - * return; - * } - * radio.read(&data,sizeof(data)); - * } - * @endcode - * - * @return Payload length of last-received dynamic payload - */ - uint8_t getDynamicPayloadSize(void); - - /** - * Enable custom payloads in the acknowledge packets - * - * ACK payloads are a handy way to return data back to senders without - * manually changing the radio modes on both units. - * - * @remarks The ACK payload feature requires the auto-ack feature to be - * enabled for any pipe using ACK payloads. This function does not - * automatically enable the auto-ack feature on pipe 0 since the auto-ack - * feature is enabled for all pipes by default. - * - * @see setAutoAck() - * - * @note ACK payloads are dynamic payloads. This function automatically - * enables dynamic payloads on pipes 0 & 1 by default. Call - * enableDynamicPayloads() to enable on all pipes (especially for RX nodes - * that use pipes other than pipe 0 to receive transmissions expecting - * responses with ACK payloads). - */ - void enableAckPayload(void); - - /** - * Disable custom payloads on the acknowledge packets - * - * @see enableAckPayload() - */ - void disableAckPayload(void); - - /** - * Enable dynamically-sized payloads - * - * This way you don't always have to send large packets just to send them - * once in a while. This enables dynamic payloads on ALL pipes. - * - */ - void enableDynamicPayloads(void); - - /** - * Disable dynamically-sized payloads - * - * This disables dynamic payloads on ALL pipes. Since Ack Payloads - * requires Dynamic Payloads, Ack Payloads are also disabled. - * If dynamic payloads are later re-enabled and ack payloads are desired - * then enableAckPayload() must be called again as well. - * - */ - void disableDynamicPayloads(void); - - /** - * Enable dynamic ACKs (single write multicast or unicast) for chosen - * messages. - * - * @note This function must be called once before using the multicast - * parameter for any functions that offer it. To use multicast behavior - * about all outgoing payloads (using pipe 0) or incoming payloads - * (concerning all RX pipes), use setAutoAck() - * - * @see - * - setAutoAck() for all pipes - * - setAutoAck(uint8_t, bool) for individual pipes - * - * @code - * radio.write(&data, 32, 1); // Sends a payload with no acknowledgement requested - * radio.write(&data, 32, 0); // Sends a payload using auto-retry/autoACK - * @endcode - */ - void enableDynamicAck(); - - /** - * Determine whether the hardware is an nRF24L01+ or not. - * - * @return true if the hardware is nRF24L01+ (or compatible) and false - * if its not. - */ - bool isPVariant(void); - - /** - * Enable or disable the auto-acknowledgement feature for all pipes. This - * feature is enabled by default. Auto-acknowledgement responds to every - * received payload with an empty ACK packet. These ACK packets get sent - * from the receiving radio back to the transmitting radio. To attach an - * ACK payload to a ACK packet, use writeAckPayload(). - * - * If this feature is disabled on a transmitting radio, then the - * transmitting radio will always report that the payload was received - * (even if it was not). Please remember that this feature's configuration - * needs to match for transmitting and receiving radios. - * - * @warning When using the `multicast` parameter to write(), this feature - * can be disabled for an individual payload. However, if this feature is - * disabled, then the `multicast` parameter will have no effect. - * - * @note If disabling auto-acknowledgment packets, the ACK payloads - * feature is also disabled as this feature is required to send ACK - * payloads. - * - * @see - * - write() - * - writeFast() - * - startFastWrite() - * - startWrite() - * - writeAckPayload() - * - * @param enable Whether to enable (true) or disable (false) the - * auto-acknowledgment feature for all pipes - */ - void setAutoAck(bool enable); - - /** - * Enable or disable the auto-acknowledgement feature for a specific pipe. - * This feature is enabled by default for all pipes. Auto-acknowledgement - * responds to every received payload with an empty ACK packet. These ACK - * packets get sent from the receiving radio back to the transmitting - * radio. To attach an ACK payload to a ACK packet, use writeAckPayload(). - * - * Pipe 0 is used for TX operations, which include sending ACK packets. If - * using this feature on both TX & RX nodes, then pipe 0 must have this - * feature enabled for the RX & TX operations. If this feature is disabled - * on a transmitting radio's pipe 0, then the transmitting radio will - * always report that the payload was received (even if it was not). - * Remember to also enable this feature for any pipe that is openly - * listening to a transmitting radio with this feature enabled. - * - * @warning If this feature is enabled for pipe 0, then the `multicast` - * parameter to write() can be used to disable this feature for an - * individual payload. However, if this feature is disabled for pipe 0, - * then the `multicast` parameter will have no effect. - * - * @note If disabling auto-acknowledgment packets on pipe 0, the ACK - * payloads feature is also disabled as this feature is required on pipe 0 - * to send ACK payloads. - * - * @see - * - write() - * - writeFast() - * - startFastWrite() - * - startWrite() - * - writeAckPayload() - * - enableAckPayload() - * - disableAckPayload() - * - * @param pipe Which pipe to configure. This number should be in range - * [0, 5]. - * @param enable Whether to enable (true) or disable (false) the - * auto-acknowledgment feature for the specified pipe - */ - void setAutoAck(uint8_t pipe, bool enable); - - /** - * Set Power Amplifier (PA) level and Low Noise Amplifier (LNA) state - * - * @param level The desired @ref PALevel as defined by @ref rf24_pa_dbm_e. - * @param lnaEnable Enable or Disable the LNA (Low Noise Amplifier) Gain. - * See table for Si24R1 modules below. @p lnaEnable only affects - * nRF24L01 modules with an LNA chip. - * - * | @p level (enum value) | nRF24L01<br>description | Si24R1<br>description when<br> @p lnaEnable = 1 | Si24R1<br>description when<br> @p lnaEnable = 0 | - * |:---------------------:|:-------:|:--------:|:-------:| - * | @ref RF24_PA_MIN (0) | -18 dBm | -6 dBm | -12 dBm | - * | @ref RF24_PA_LOW (1) | -12 dBm | -0 dBm | -4 dBm | - * | @ref RF24_PA_HIGH (2) | -6 dBm | 3 dBm | 1 dBm | - * | @ref RF24_PA_MAX (3) | 0 dBm | 7 dBm | 4 dBm | - * - * @note The getPALevel() function does not care what was passed @p lnaEnable parameter. - */ - void setPALevel(uint8_t level, bool lnaEnable = 1); - - /** - * Fetches the current @ref PALevel. - * - * @return One of the values defined by @ref rf24_pa_dbm_e. - * See tables in @ref rf24_pa_dbm_e or setPALevel() - */ - uint8_t getPALevel(void); - - /** - * Returns automatic retransmission count (ARC_CNT) - * - * Value resets with each new transmission. Allows roughly estimating signal strength. - * - * @return Returns values from 0 to 15. - */ - uint8_t getARC(void); - - /** - * Set the transmission @ref Datarate - * - * @warning setting @ref RF24_250KBPS will fail for non-plus modules (when - * isPVariant() returns false). - * - * @param speed Specify one of the following values (as defined by - * @ref rf24_datarate_e): - * | @p speed (enum value) | description | - * |:---------------------:|:------------:| - * | @ref RF24_1MBPS (0) | for 1 Mbps | - * | @ref RF24_2MBPS (1) | for 2 Mbps | - * | @ref RF24_250KBPS (2) | for 250 kbps | - * - * @return true if the change was successful - */ - bool setDataRate(rf24_datarate_e speed); - - /** - * Fetches the currently configured transmission @ref Datarate - * - * @return One of the values defined by @ref rf24_datarate_e. - * See table in @ref rf24_datarate_e or setDataRate() - */ - rf24_datarate_e getDataRate(void); - - /** - * Set the @ref CRCLength (in bits) - * - * CRC cannot be disabled if auto-ack is enabled - * @param length Specify one of the values (as defined by @ref rf24_crclength_e) - * | @p length (enum value) | description | - * |:--------------------------:|:------------------------------:| - * | @ref RF24_CRC_DISABLED (0) | to disable using CRC checksums | - * | @ref RF24_CRC_8 (1) | to use 8-bit checksums | - * | @ref RF24_CRC_16 (2) | to use 16-bit checksums | - */ - void setCRCLength(rf24_crclength_e length); - - /** - * Get the @ref CRCLength (in bits) - * - * CRC checking cannot be disabled if auto-ack is enabled - * @return One of the values defined by @ref rf24_crclength_e. - * See table in @ref rf24_crclength_e or setCRCLength() - */ - rf24_crclength_e getCRCLength(void); - - /** - * Disable CRC validation - * - * @warning CRC cannot be disabled if auto-ack/ESB is enabled. - */ - void disableCRC(void); - - /** - * This function is used to configure what events will trigger the Interrupt - * Request (IRQ) pin active LOW. - * The following events can be configured: - * 1. "data sent": This does not mean that the data transmitted was - * received, only that the attempt to send it was complete. - * 2. "data failed": This means the data being sent was not received. This - * event is only triggered when the auto-ack feature is enabled. - * 3. "data received": This means that data from a receiving payload has - * been loaded into the RX FIFO buffers. Remember that there are only 3 - * levels available in the RX FIFO buffers. - * - * By default, all events are configured to trigger the IRQ pin active LOW. - * When the IRQ pin is active, use whatHappened() to determine what events - * triggered it. Remember that calling whatHappened() also clears these - * events' status, and the IRQ pin will then be reset to inactive HIGH. - * - * The following code configures the IRQ pin to only reflect the "data received" - * event: - * @code - * radio.maskIRQ(1, 1, 0); - * @endcode - * - * @param tx_ok `true` ignores the "data sent" event, `false` reflects the - * "data sent" event on the IRQ pin. - * @param tx_fail `true` ignores the "data failed" event, `false` reflects the - * "data failed" event on the IRQ pin. - * @param rx_ready `true` ignores the "data received" event, `false` reflects the - * "data received" event on the IRQ pin. - */ - void maskIRQ(bool tx_ok, bool tx_fail, bool rx_ready); - - /** - * - * The driver will delay for this duration when stopListening() is called - * - * When responding to payloads, faster devices like ARM(RPi) are much faster than Arduino: - * 1. Arduino sends data to RPi, switches to RX mode - * 2. The RPi receives the data, switches to TX mode and sends before the Arduino radio is in RX mode - * 3. If AutoACK is disabled, this can be set as low as 0. If AA/ESB enabled, set to 100uS minimum on RPi - * - * @warning If set to 0, ensure 130uS delay after stopListening() and before any sends - */ - uint32_t txDelay; - - /** - * - * On all devices but Linux and ATTiny, a small delay is added to the CSN toggling function - * - * This is intended to minimise the speed of SPI polling due to radio commands - * - * If using interrupts or timed requests, this can be set to 0 Default:5 - */ - uint32_t csDelay; - - /** - * Transmission of constant carrier wave with defined frequency and output power - * - * @param level Output power to use - * @param channel The channel to use - * - * @warning If isPVariant() returns true, then this function takes extra - * measures that alter some settings. These settings alterations include: - * - setAutoAck() to false (for all pipes) - * - setRetries() to retry `0` times with a delay of 250 microseconds - * - set the TX address to 5 bytes of `0xFF` - * - flush_tx() - * - load a 32 byte payload of `0xFF` into the TX FIFO's top level - * - disableCRC() - */ - void startConstCarrier(rf24_pa_dbm_e level, uint8_t channel); - - /** - * Stop transmission of constant wave and reset PLL and CONT registers - * - * @warning this function will powerDown() the radio per recommendation of - * datasheet. - * @note If isPVariant() returns true, please remember to re-configure the radio's settings - * @code - * // re-establish default settings - * setCRCLength(RF24_CRC_16); - * setAutoAck(true); - * setRetries(5, 15); - * @endcode - * @see startConstCarrier() - */ - void stopConstCarrier(void); - - /** - * @brief Open or close all data pipes. - * - * This function does not alter the addresses assigned to pipes. It is simply a - * convenience function that allows controling all pipes at once. - * @param isEnabled `true` opens all pipes; `false` closes all pipes. - */ - void toggleAllPipes(bool isEnabled); - - /** - * @brief configure the RF_SETUP register in 1 transaction - * @param level This parameter is the same input as setPALevel()'s `level` parameter. - * See @ref rf24_pa_dbm_e enum for accepted values. - * @param speed This parameter is the same input as setDataRate()'s `speed` parameter. - * See @ref rf24_datarate_e enum for accepted values. - * @param lnaEnable This optional parameter is the same as setPALevel()'s `lnaEnable` - * optional parameter. Defaults to `true` (meaning LNA feature is enabled) when not specified. - */ - void setRadiation(uint8_t level, rf24_datarate_e speed, bool lnaEnable = true); - - /**@}*/ - /** - * @name Deprecated - * - * Methods provided for backwards compatibility. - */ - /**@{*/ - - /** - * Open a pipe for reading - * @deprecated For compatibility with old code only, see newer function - * openReadingPipe() - * - * @note Pipes 1-5 should share the first 32 bits. - * Only the least significant byte should be unique, e.g. - * @code - * openReadingPipe(1, 0xF0F0F0F0AA); - * openReadingPipe(2, 0xF0F0F0F066); - * @endcode - * - * @warning - * @parblock - * Pipe 0 is also used by the writing pipe so should typically be avoided as a reading pipe. - * If used, the reading pipe 0 address needs to be restored at every call to startListening(). - * - * See http://maniacalbits.blogspot.com/2013/04/rf24-addressing-nrf24l01-radios-require.html - * @endparblock - * - * @param number Which pipe# to open, 0-5. - * @param address The 40-bit address of the pipe to open. - */ - void openReadingPipe(uint8_t number, uint64_t address); - - /** - * Open a pipe for writing - * @deprecated For compatibility with old code only, see newer function - * openWritingPipe() - * - * Addresses are 40-bit hex values, e.g.: - * - * @code - * openWritingPipe(0xF0F0F0F0F0); - * @endcode - * - * @param address The 40-bit address of the pipe to open. - */ - void openWritingPipe(uint64_t address); - - /** - * Determine if an ack payload was received in the most recent call to - * write(). The regular available() can also be used. - * - * @deprecated For compatibility with old code only, see synonymous function available(). - * Use read() to retrieve the ack payload and getDynamicPayloadSize() to get the ACK payload size. - * - * @return True if an ack payload is available. - */ - bool isAckPayloadAvailable(void); - -private: - /**@}*/ - /** - * @name Low-level internal interface. - * - * Protected methods that address the chip directly. Regular users cannot - * ever call these. They are documented for completeness and for developers who - * may want to extend this class. - */ - /**@{*/ - - /** - * initializing function specific to all constructors - * (regardless of constructor parameters) - */ - void _init_obj(); - - /** - * initialize radio by performing a soft reset. - * @warning This function assumes the SPI bus object's begin() method has been - * previously called. - */ - bool _init_radio(); - - /** - * initialize the GPIO pins - */ - bool _init_pins(); - - /** - * Set chip select pin - * - * Running SPI bus at PI_CLOCK_DIV2 so we don't waste time transferring data - * and best of all, we make use of the radio's FIFO buffers. A lower speed - * means we're less likely to effectively leverage our FIFOs and pay a higher - * AVR runtime cost as toll. - * - * @param mode HIGH to take this unit off the SPI bus, LOW to put it on - */ - void csn(bool mode); - - /** - * Set chip enable - * - * @param level HIGH to actively begin transmission or LOW to put in standby. Please see data sheet - * for a much more detailed description of this pin. - */ - void ce(bool level); - - /** - * Write a chunk of data to a register - * - * @param reg Which register. Use constants from nRF24L01.h - * @param buf Where to get the data - * @param len How many bytes of data to transfer - * @return Nothing. Older versions of this function returned the status - * byte, but that it now saved to a private member on all SPI transactions. - */ - void write_register(uint8_t reg, const uint8_t* buf, uint8_t len); - - /** - * Write a single byte to a register - * - * @param reg Which register. Use constants from nRF24L01.h - * @param value The new value to write - * @param is_cmd_only if this parameter is true, then the `reg` parameter - * is written, and the `value` param is ignored. - * @return Nothing. Older versions of this function returned the status - * byte, but that it now saved to a private member on all SPI transactions. - */ - void write_register(uint8_t reg, uint8_t value, bool is_cmd_only = false); - - /** - * Write the transmit payload - * - * The size of data written is the fixed payload size, see getPayloadSize() - * - * @param buf Where to get the data - * @param len Number of bytes to be sent - * @param writeType Specify if individual payload should be acknowledged - * @return Nothing. Older versions of this function returned the status - * byte, but that it now saved to a private member on all SPI transactions. - */ - void write_payload(const void* buf, uint8_t len, const uint8_t writeType); - - /** - * Read the receive payload - * - * The size of data read is the fixed payload size, see getPayloadSize() - * - * @param buf Where to put the data - * @param len Maximum number of bytes to read - * @return Nothing. Older versions of this function returned the status - * byte, but that it now saved to a private member on all SPI transactions. - */ - void read_payload(void* buf, uint8_t len); - - /** - * Retrieve the current status of the chip - * - * @return Current value of status register - */ - uint8_t get_status(void); - -#if !defined(MINIMAL) - - /** - * Decode and print the given status to stdout - * - * @param status Status value to print - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - */ - void print_status(uint8_t status); - - /** - * Decode and print the given 'observe_tx' value to stdout - * - * @param value The observe_tx value to print - * - * @warning Does nothing if stdout is not defined. See fdevopen in stdio.h - */ - void print_observe_tx(uint8_t value); - - /** - * Print the name and value of an 8-bit register to stdout - * - * Optionally it can print some quantity of successive - * registers on the same line. This is useful for printing a group - * of related registers on one line. - * - * @param name Name of the register - * @param reg Which register. Use constants from nRF24L01.h - * @param qty How many successive registers to print - */ - void print_byte_register(const char* name, uint8_t reg, uint8_t qty = 1); - - /** - * Print the name and value of a 40-bit address register to stdout - * - * Optionally it can print some quantity of successive - * registers on the same line. This is useful for printing a group - * of related registers on one line. - * - * @param name Name of the register - * @param reg Which register. Use constants from nRF24L01.h - * @param qty How many successive registers to print - */ - void print_address_register(const char* name, uint8_t reg, uint8_t qty = 1); - - /** - * Put the value of a 40-bit address register into a char array - * - * Optionally it can print some quantity of successive - * registers on the same line. This is useful for printing a group - * of related registers on one line. - * - * @param out_buffer Output buffer, char array - * @param reg Which register. Use constants from nRF24L01.h - * @param qty How many successive registers to print - * @return The total number of characters written to the given buffer. - */ - uint8_t sprintf_address_register(char* out_buffer, uint8_t reg, uint8_t qty = 1); -#endif - - /** - * Turn on or off the special features of the chip - * - * The chip has certain 'features' which are only available when the 'features' - * are enabled. See the datasheet for details. - */ - void toggle_features(void); - -#if defined(FAILURE_HANDLING) || defined(RF24_LINUX) - - void errNotify(void); - -#endif - - /** - * @brief Manipulate the @ref Datarate and txDelay - * - * This is a helper function to setRadiation() and setDataRate() - * @param speed The desired data rate. - */ - inline uint8_t _data_rate_reg_value(rf24_datarate_e speed); - - /** - * @brief Manipulate the @ref PALevel - * - * This is a helper function to setRadiation() and setPALevel() - * @param level The desired @ref PALevel. - * @param lnaEnable Toggle the LNA feature. - */ - inline uint8_t _pa_level_reg_value(uint8_t level, bool lnaEnable); - - /**@}*/ -}; - -/** - * @example{lineno} examples/GettingStarted/GettingStarted.ino - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ - -/** - * @example{lineno} examples/AcknowledgementPayloads/AcknowledgementPayloads.ino - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with Acknowledgement (ACK) payloads attached to ACK packets. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ - -/** - * @example{lineno} examples/ManualAcknowledgements/ManualAcknowledgements.ino - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. - * This example still uses ACK packets, but they have no payloads. Instead the - * acknowledging response is sent with `write()`. This tactic allows for more - * updated acknowledgement payload data, where actual ACK payloads' data are - * outdated by 1 transmission because they have to loaded before receiving a - * transmission. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ - -/** - * @example{lineno} examples/StreamingData/StreamingData.ino - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of streaming data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ - -/** - * @example{lineno} examples/MulticeiverDemo/MulticeiverDemo.ino - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from as many as 6 nRF24L01 transceivers to - * 1 receiving transceiver. This technique is trademarked by - * Nordic Semiconductors as "MultiCeiver". - * - * This example was written to be used on up to 6 devices acting as TX nodes & - * only 1 device acting as the RX node (that's a maximum of 7 devices). - * Use the Serial Monitor to change each node's behavior. - */ - -/** - * @example{lineno} examples/InterruptConfigure/InterruptConfigure.ino - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * This example uses Acknowledgement (ACK) payloads attached to ACK packets to - * demonstrate how the nRF24L01's IRQ (Interrupt Request) pin can be - * configured to detect when data is received, or when data has transmitted - * successfully, or when data has failed to transmit. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ - -/** - * @example{lineno} examples/old_backups/GettingStarted_HandlingFailures/GettingStarted_HandlingFailures.ino - * Written by [TMRh20](http://github.com/TMRh20) in 2019 - * - * This example demonstrates the basic getting started functionality, but with - * failure handling for the radio chip. Addresses random radio failures etc, - * potentially due to loose wiring on breadboards etc. - */ - -/** - * @example{lineno} examples/old_backups/TransferTimeouts/TransferTimeouts.ino - * Written by [TMRh20](https://github.com/TMRh20) - * - * This example demonstrates the use of and extended timeout period and - * auto-retries/auto-reUse to increase reliability in noisy or low signal scenarios. - * - * Write this sketch to two different nodes. Put one of the nodes into 'transmit' - * mode by connecting with the serial monitor and sending a 'T'. The data <br> - * transfer will begin, with the receiver displaying the payload count and the - * data transfer rate. - */ - -/** - * @example{lineno} examples/old_backups/pingpair_irq/pingpair_irq.ino - * Updated by [TMRh20](https://github.com/TMRh20) - * - * This is an example of how to user interrupts to interact with the radio, and a demonstration - * of how to use them to sleep when receiving, and not miss any payloads.<br> - * The pingpair_sleepy example expands on sleep functionality with a timed sleep option for the transmitter. - * Sleep functionality is built directly into my fork of the RF24Network library<br> - */ - -/** - * @example{lineno} examples/old_backups/pingpair_sleepy/pingpair_sleepy.ino - * Updated by [TMRh20](https://github.com/TMRh20) - * - * This is an example of how to use the RF24 class to create a battery- - * efficient system. It is just like the GettingStarted_CallResponse example, but the<br> - * ping node powers down the radio and sleeps the MCU after every - * ping/pong cycle, and the receiver sleeps between payloads. <br> - */ - -/** - * @example{lineno} examples/rf24_ATTiny/rf24ping85/rf24ping85.ino - * <b>2014 Contribution by [tong67](https://github.com/tong67)</b><br> - * Updated 2020 by [2bndy5](http://github.com/2bndy5) for the - * [SpenceKonde ATTinyCore](https://github.com/SpenceKonde/ATTinyCore)<br> - * The RF24 library uses the [ATTinyCore by - * SpenceKonde](https://github.com/SpenceKonde/ATTinyCore) - * - * This sketch is a duplicate of the ManualAcknowledgements.ino example - * (without all the Serial input/output code), and it demonstrates - * a ATTiny25/45/85 or ATTiny24/44/84 driving the nRF24L01 transceiver using - * the RF24 class to communicate with another node. - * - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. - * This example still uses ACK packets, but they have no payloads. Instead the - * acknowledging response is sent with `write()`. This tactic allows for more - * updated acknowledgement payload data, where actual ACK payloads' data are - * outdated by 1 transmission because they have to loaded before receiving a - * transmission. - * - * This example was written to be used on 2 devices acting as "nodes". - */ - -/** - * @example{lineno} examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino - * <b>2014 Contribution by [tong67](https://github.com/tong67)</b><br> - * Updated 2020 by [2bndy5](http://github.com/2bndy5) for the - * [SpenceKonde ATTinyCore](https://github.com/SpenceKonde/ATTinyCore)<br> - * The RF24 library uses the [ATTinyCore by - * SpenceKonde](https://github.com/SpenceKonde/ATTinyCore) - * - * This sketch can be used to determine the best settle time values to use for - * RF24::csDelay in RF24::csn() (private function). - * @see RF24::csDelay - * - * The settle time values used here are 100/20. However, these values depend - * on the actual used RC combination and voltage drop by LED. The - * intermediate results are written to TX (PB3, pin 2 -- using Serial). - * - * For schematic details, see introductory comment block in the rf24ping85.ino sketch. - */ - -/** - * @example{lineno} examples/old_backups/pingpair_dyn/pingpair_dyn.ino - * - * This is an example of how to use payloads of a varying (dynamic) size on Arduino. - */ - -/** - * @example{lineno} examples_linux/getting_started.py - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * This is a simple example of using the RF24 class on a Raspberry Pi. - * - * Remember to install the [Python wrapper](md_docs_python_wrapper.html), then - * navigate to the "RF24/examples_linux" folder. - * <br>To run this example, enter - * @code{.sh}python3 getting_started.py @endcode and follow the prompts. - * - * @note this example requires python v3.7 or newer because it measures - * transmission time with `time.monotonic_ns()`. - */ - -/** - * @example{lineno} examples_linux/acknowledgement_payloads.py - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * This is a simple example of using the RF24 class on a Raspberry Pi to - * transmit and retrieve custom automatic acknowledgment payloads. - * - * Remember to install the [Python wrapper](md_docs_python_wrapper.html), then - * navigate to the "RF24/examples_linux" folder. - * <br>To run this example, enter - * @code{.sh}python3 acknowledgement_payloads.py @endcode and follow the prompts. - * - * @note this example requires python v3.7 or newer because it measures - * transmission time with `time.monotonic_ns()`. - */ - -/** - * @example{lineno} examples_linux/manual_acknowledgements.py - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * This is a simple example of using the RF24 class on a Raspberry Pi to - * transmit and respond with acknowledgment (ACK) transmissions. Notice that - * the auto-ack feature is enabled, but this example doesn't use automatic ACK - * payloads because automatic ACK payloads' data will always be outdated by 1 - * transmission. Instead, this example uses a call and response paradigm. - * - * Remember to install the [Python wrapper](md_docs_python_wrapper.html), then - * navigate to the "RF24/examples_linux" folder. - * <br>To run this example, enter - * @code{.sh}python3 manual_acknowledgements.py @endcode and follow the prompts. - * - * @note this example requires python v3.7 or newer because it measures - * transmission time with `time.monotonic_ns()`. - */ - -/** - * @example{lineno} examples_linux/streaming_data.py - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * This is a simple example of using the RF24 class on a Raspberry Pi for - * streaming multiple payloads. - * - * Remember to install the [Python wrapper](md_docs_python_wrapper.html), then - * navigate to the "RF24/examples_linux" folder. - * <br>To run this example, enter - * @code{.sh}python3 streaming_data.py @endcode and follow the prompts. - * - * @note this example requires python v3.7 or newer because it measures - * transmission time with `time.monotonic_ns()`. - */ - -/** - * @example{lineno} examples_linux/interrupt_configure.py - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * This is a simple example of using the RF24 class on a Raspberry Pi to - * detecting (and verifying) the IRQ (interrupt) pin on the nRF24L01. - * - * Remember to install the [Python wrapper](md_docs_python_wrapper.html), then - * navigate to the "RF24/examples_linux" folder. - * <br>To run this example, enter - * @code{.sh}python3 interrupt_configure.py @endcode and follow the prompts. - * - * @note this example requires python v3.7 or newer because it measures - * transmission time with `time.monotonic_ns()`. - */ - -/** - * @example{lineno} examples_linux/multiceiver_demo.py - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * This is a simple example of using the RF24 class on a Raspberry Pi for - * using 1 nRF24L01 to receive data from up to 6 other transceivers. This - * technique is called "multiceiver" in the datasheet. - * - * Remember to install the [Python wrapper](md_docs_python_wrapper.html), then - * navigate to the "RF24/examples_linux" folder. - * <br>To run this example, enter - * @code{.sh}python3 multiceiver_demo.py @endcode and follow the prompts. - * - * @note this example requires python v3.7 or newer because it measures - * transmission time with `time.monotonic_ns()`. - */ - -/** - * @example{lineno} examples_linux/scanner.cpp - * - * Example to detect interference on the various channels available. - * This is a good diagnostic tool to check whether you're picking a - * good channel for your application. - * - * Inspired by cpixip. - * See http://arduino.cc/forum/index.php/topic,54795.0.html - * - * Use ctrl+C to exit - */ - -/** - * @example{lineno} examples/scanner/scanner.ino - * - * Example to detect interference on the various channels available. - * This is a good diagnostic tool to check whether you're picking a - * good channel for your application. - * - * Inspired by cpixip. - * See http://arduino.cc/forum/index.php/topic,54795.0.html - */ - -/** - * @example{lineno} examples_linux/gettingstarted.cpp - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from 1 nRF24L01 transceiver to another. - * - * This example was written * This example was written to be used on up to 6 devices acting as TX nodes & - * only 1 device acting as the RX node (that's a maximum of 7 devices). - acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ - -/** - * @example{lineno} examples_linux/acknowledgementPayloads.cpp - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with Acknowledgement (ACK) payloads attached to ACK packets. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ - -/** - * @example{lineno} examples_linux/manualAcknowledgements.cpp - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. - * This example still uses ACK packets, but they have no payloads. Instead the - * acknowledging response is sent with `write()`. This tactic allows for more - * updated acknowledgement payload data, where actual ACK payloads' data are - * outdated by 1 transmission because they have to loaded before receiving a - * transmission. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ - -/** - * @example{lineno} examples_linux/streamingData.cpp - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ - -/** - * @example{lineno} examples_linux/multiceiverDemo.cpp - * Written by [2bndy5](http://github.com/2bndy5) in 2020 - * - * A simple example of sending data from as many as 6 nRF24L01 transceivers to - * 1 receiving transceiver. This technique is trademarked by - * Nordic Semiconductors as "MultiCeiver". - * - * This example was written to be used on up to 6 devices acting as TX nodes & - * only 1 device acting as the RX node (that's a maximum of 7 devices). - * Use `ctrl+c` to quit at any time. - */ - -#endif // __RF24_H__ \ No newline at end of file diff --git a/RF24/RF24_config.h b/RF24/RF24_config.h deleted file mode 100644 index 7642d803e441d52120fe39b72473145e70695120..0000000000000000000000000000000000000000 --- a/RF24/RF24_config.h +++ /dev/null @@ -1,231 +0,0 @@ - -/* - Copyright (C) - 2011 J. Coliz <maniacbug@ymail.com> - 2015-2019 TMRh20 - 2015 spaniakos <spaniakos@gmail.com> - 2015 nerdralph - 2015 zador-blood-stained - 2016 akatran - 2017-2019 Avamander <avamander@gmail.com> - 2019 IkpeohaGodson - 2021 2bndy5 - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. -*/ - -#ifndef __RF24_CONFIG_H__ -#define __RF24_CONFIG_H__ - -/*** USER DEFINES: ***/ -#define FAILURE_HANDLING -//#define SERIAL_DEBUG -//#define MINIMAL -//#define SPI_UART // Requires library from https://github.com/TMRh20/Sketches/tree/master/SPI_UART -//#define SOFTSPI // Requires library from https://github.com/greiman/DigitalIO - -/** - * User access to internally used delay time (in microseconds) during RF24::powerUp() - * @warning This default value compensates for all supported hardware. Only adjust this if you - * know your radio's hardware is, in fact, genuine and reliable. - */ -#if !defined(RF24_POWERUP_DELAY) - #define RF24_POWERUP_DELAY 5000 -#endif - -/**********************/ -#define rf24_max(a, b) (a > b ? a : b) -#define rf24_min(a, b) (a < b ? a : b) - -/** @brief The default SPI speed (in Hz) */ -#ifndef RF24_SPI_SPEED - #define RF24_SPI_SPEED 10000000 -#endif - -//ATXMega -#if defined(__AVR_ATxmega64D3__) || defined(__AVR_ATxmega128D3__) || defined(__AVR_ATxmega192D3__) || defined(__AVR_ATxmega256D3__) || defined(__AVR_ATxmega384D3__) - // In order to be available both in Windows and Linux this should take presence here. - #define XMEGA - #define XMEGA_D3 - #include "utility/ATXMegaD3/RF24_arch_config.h" - -// RaspberryPi rp2xxx-based devices (e.g. RPi Pico board) -#elif defined(PICO_BUILD) && !defined(ARDUINO) - #include "utility/rp2/RF24_arch_config.h" - #define sprintf_P sprintf - -#elif (!defined(ARDUINO)) // Any non-arduino device is handled via configure/Makefile - // The configure script detects device and copies the correct includes.h file to /utility/includes.h - // This behavior can be overridden by calling configure with respective parameters - // The includes.h file defines either RF24_RPi, MRAA, LITTLEWIRE or RF24_SPIDEV and includes the correct RF24_arch_config.h file - #include "utility/includes.h" - - #ifndef sprintf_P - #define sprintf_P sprintf - #endif // sprintf_P - -//ATTiny -#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__) || defined(__AVR_ATtiny861__) || defined(__AVR_ATtinyX5__) || defined(__AVR_ATtinyX4__) || defined(__AVR_ATtinyX313__) || defined(__AVR_ATtinyX61__) - #define RF24_TINY - #include "utility/ATTiny/RF24_arch_config.h" - -#elif defined(LITTLEWIRE) //LittleWire - #include "utility/LittleWire/RF24_arch_config.h" - -#elif defined(TEENSYDUINO) //Teensy - #include "utility/Teensy/RF24_arch_config.h" - -#else //Everything else - #include <Arduino.h> - - #if defined(ARDUINO) && !defined(__arm__) && !defined(__ARDUINO_X86__) - #if defined SPI_UART - #include <SPI_UART.h> - #define _SPI uspi - #elif defined(SOFTSPI) - // change these pins to your liking - // - #ifndef SOFT_SPI_MISO_PIN - #define SOFT_SPI_MISO_PIN 9 - #endif // SOFT_SPI_MISO_PIN - - #ifndef SOFT_SPI_MOSI_PIN - #define SOFT_SPI_MOSI_PIN 8 - #endif // SOFT_SPI_MOSI_PIN - - #ifndef SOFT_SPI_SCK_PIN - #define SOFT_SPI_SCK_PIN 7 - #endif // SOFT_SPI_SCK_PIN - -const uint8_t SPI_MODE = 0; - #define _SPI spi - - #elif defined(ARDUINO_SAM_DUE) - #include <SPI.h> - #define _SPI SPI - - #else // !defined (SPI_UART) && !defined (SOFTSPI) - #include <SPI.h> - #define _SPI SPIClass - #define RF24_SPI_PTR - #endif // !defined (SPI_UART) && !defined (SOFTSPI) - - #else // !defined(ARDUINO) || defined (__arm__) || defined (__ARDUINO_X86__) - // Define _BV for non-Arduino platforms and for Arduino DUE - #include <stdint.h> - #include <stdio.h> - #include <string.h> - - #if defined(__arm__) || defined(__ARDUINO_X86__) - #if defined(__arm__) && defined(SPI_UART) - #include <SPI_UART.h> - #define _SPI uspi - - #else // !defined (__arm__) || !defined (SPI_UART) - #include <SPI.h> - #define _SPI SPIClass - #define RF24_SPI_PTR - - #endif // !defined (__arm__) || !defined (SPI_UART) - #elif !defined(__arm__) && !defined(__ARDUINO_X86__) -// fallback to unofficially supported Hardware (courtesy of ManiacBug) -extern HardwareSPI SPI; - #define _SPI HardwareSPI - #define RF24_SPI_PTR - - #endif // !defined(__arm__) && !defined (__ARDUINO_X86__) - - #ifndef _BV - #define _BV(x) (1 << (x)) - #endif - #endif // defined (ARDUINO) && !defined (__arm__) && !defined (__ARDUINO_X86__) - - #ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) - #else - #define IF_SERIAL_DEBUG(x) - #if defined(RF24_TINY) - #define printf_P(...) - #endif // defined(RF24_TINY) - - #endif // SERIAL_DEBUG - - #if defined(__ARDUINO_X86__) - #define printf_P printf - #define _BV(bit) (1 << (bit)) - - #endif // defined (__ARDUINO_X86__) - - // Progmem is Arduino-specific - #if defined(ARDUINO_ARCH_ESP8266) || defined(ESP32) || (defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED)) - #include <pgmspace.h> - #define PRIPSTR "%s" - #ifndef pgm_read_ptr - #define pgm_read_ptr(p) (*(void* const*)(p)) - #endif - // Serial.printf() is no longer defined in the unifying Arduino/ArduinoCore-API repo - // Serial.printf() is defined if using the arduino-pico/esp32/8266 repo - #if defined(ARDUINO_ARCH_ESP32) // do not `undef` when using the espressif SDK only - #undef printf_P // needed for ESP32 core - #endif - #define printf_P Serial.printf - #elif defined(ARDUINO) && !defined(ESP_PLATFORM) && !defined(__arm__) && !defined(__ARDUINO_X86__) || defined(XMEGA) - #include <avr/pgmspace.h> - #define PRIPSTR "%S" - - #else // !defined (ARDUINO) || defined (ESP_PLATFORM) || defined (__arm__) || defined (__ARDUINO_X86__) && !defined (XMEGA) - #if !defined(ARDUINO) // This doesn't work on Arduino DUE -typedef char const char; - #else // Fill in pgm_read_byte that is used - #if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAM_DUE) - #include <avr/pgmspace.h> // added to ArduinoCore-sam (Due core) in 2013 - #endif - - // Since the official arduino/ArduinoCore-samd repo switched to a unified API in 2016, - // Serial.printf() is no longer defined in the unifying Arduino/ArduinoCore-API repo - #if defined(ARDUINO_ARCH_SAMD) && defined(ARDUINO_SAMD_ADAFRUIT) - // it is defined if using the adafruit/ArduinoCore-samd repo - #define printf_P Serial.printf - #endif // defined (ARDUINO_ARCH_SAMD) - - #ifndef pgm_read_byte - #define pgm_read_byte(addr) (*(const unsigned char*)(addr)) - #endif - #endif // !defined (ARDUINO) - - #ifndef prog_uint16_t -typedef uint16_t prog_uint16_t; - #endif - #ifndef PSTR - #define PSTR(x) (x) - #endif - #ifndef printf_P - #define printf_P printf - #endif - #ifndef strlen_P - #define strlen_P strlen - #endif - #ifndef PROGMEM - #define PROGMEM - #endif - #ifndef pgm_read_word - #define pgm_read_word(p) (*(const unsigned short*)(p)) - #endif - #if !defined pgm_read_ptr || defined ARDUINO_ARCH_MBED - #define pgm_read_ptr(p) (*(void* const*)(p)) - #endif - #ifndef PRIPSTR - #define PRIPSTR "%s" - #endif - - #endif // !defined (ARDUINO) || defined (ESP_PLATFORM) || defined (__arm__) || defined (__ARDUINO_X86__) && !defined (XMEGA) - -#endif //Everything else - -#if defined(SPI_HAS_TRANSACTION) && !defined(SPI_UART) && !defined(SOFTSPI) - #define RF24_SPI_TRANSACTIONS -#endif // defined (SPI_HAS_TRANSACTION) && !defined (SPI_UART) && !defined (SOFTSPI) - -#endif // __RF24_CONFIG_H__ diff --git a/RF24/cmake/AutoConfig_RF24_DRIVER.cmake b/RF24/cmake/AutoConfig_RF24_DRIVER.cmake deleted file mode 100644 index 6e942caff7706981c5ee0f785722cb5b25fe961b..0000000000000000000000000000000000000000 --- a/RF24/cmake/AutoConfig_RF24_DRIVER.cmake +++ /dev/null @@ -1,56 +0,0 @@ -set(RF24_LINKED_DRIVER "") -set(RF24_DRIVER "UNKNOWN" CACHE STRING "override automatic configuration of RF24's utility driver. - Specify 1 of the following supported drivers (ie -DRF24_DRIVER=SPIDEV): - wiringPi - RPi - SPIDEV - MRAA - LittleWire - pigpio" -) - -########################### -# detect pre-existing (locally installed) 3rd party libraries -########################### - -# detect installed libraries despite what RF24_DRIVER is set to -# this is always done for cross-compiling purposes -find_library(LibMRAA mraa) -find_library(LibWiringPi wiringPi) -find_library(LibLittleWire littlewire-spi) -find_library(LibPIGPIO pigpio) -if(EXISTS /dev/spidev0.0) - set(SPIDEV_EXISTS TRUE) -else() - set(SPIDEV_EXISTS FALSE) -endif() - - -if(${RF24_DRIVER} STREQUAL "UNKNOWN") # invokes automatic configuration - if("${SOC}" STREQUAL "BCM2708" OR "${SOC}" STREQUAL "BCM2709" OR "${SOC}" STREQUAL "BCM2835") - set(RF24_DRIVER RPi CACHE STRING "using folder /utility/RPi" FORCE) - elseif(NOT "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND") - message(STATUS "Found pigpio library: ${LibPIGPIO}") - set(RF24_DRIVER pigpio CACHE STRING "using folder /utility/pigpio" FORCE) - elseif(NOT "${LibWiringPi}" STREQUAL "LibWiringPi-NOTFOUND") - message(STATUS "Found wiringPi library: ${LibWiringPi}") - set(RF24_DRIVER wiringPi CACHE STRING "using folder /utility/wiringPi" FORCE) - elseif(NOT "${LibLittleWire}" STREQUAL "LibLittleWire-NOTFOUND") - message(STATUS "Found LittleWire library: ${LibLittleWire}") - set(RF24_DRIVER LittleWire CACHE STRING "using folder /utility/LittleWire" FORCE) - elseif(NOT "${LibMRAA}" STREQUAL "LibMRAA-NOTFOUND") - message(STATUS "Found MRAA library: ${LibMRAA}") - set(RF24_DRIVER MRAA CACHE STRING "using folder /utility/MRAA" FORCE) - elseif(SPIDEV_EXISTS) # should be a non-empty string if SPI is enabled - message(STATUS "detected that SPIDEV is enabled: ${SPIDEV_EXISTS}") - set(RF24_DRIVER SPIDEV CACHE STRING "using folder /utility/SPIDEV" FORCE) - endif() -endif() - -# override the auto-detect if RF24_DRIVER is defined in an env var -if(DEFINED ENV{RF24_DRIVER}) - message(STATUS "RF24_DRIVER (set from env var) = $ENV{RF24_DRIVER}") - set(RF24_DRIVER $ENV{RF24_DRIVER} CACHE STRING "" FORCE) -endif() - -message(STATUS "Using driver: ${RF24_DRIVER}") diff --git a/RF24/cmake/CPackInfo.cmake b/RF24/cmake/CPackInfo.cmake deleted file mode 100644 index 808cdff2ea4b69040098820e38096f937bff3d1d..0000000000000000000000000000000000000000 --- a/RF24/cmake/CPackInfo.cmake +++ /dev/null @@ -1,75 +0,0 @@ -# This module will build a debian compatible package to install - handy for cross-compiling - -if(NOT PKG_REV) - set(PKG_REV "1") -endif() - -# get target arch if not cross-compiling -if(NOT TARGET_ARCH) # TARGET_ARCH is defined only in the toolchain_<ARCH_TYPE>.cmake files - execute_process(COMMAND dpkg --print-architecture - OUTPUT_VARIABLE TARGET_ARCH - OUTPUT_STRIP_TRAILING_WHITESPACE - ) -endif() - -# set the Cpack generators (specific to types of packages to create) -set(CPACK_GENERATOR DEB RPM) # RPM requires rpmbuild executable - -# assemble a debian package filename from known info -include(InstallRequiredSystemLibraries) -set(CPACK_PACKAGE_FILE_NAME "lib${LibTargetName}-${RF24_DRIVER}_${${LibName}_VERSION_STRING}-${PKG_REV}_${TARGET_ARCH}") -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") -set(CPACK_PACKAGE_VERSION_MAJOR "${${LibName}_VERSION_MAJOR}") -set(CPACK_PACKAGE_VERSION_MINOR "${${LibName}_VERSION_MINOR}") -set(CPACK_PACKAGE_VERSION_PATCH "${${LibName}_VERSION_PATCH}") -set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/pkgs") # for easy uploading to github releases - -############################### -# info specific debian packages -############################### -set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${TARGET_ARCH}) -set(CPACK_DEBIAN_PACKAGE_SECTION libs) -set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) - - -############################### -# info specific rpm (fedora) packages -############################### -set(CPACK_RPM_FILE_NAME "lib${LibTargetName}-${RF24_DRIVER}-${${LibName}_VERSION_STRING}-${PKG_REV}.${TARGET_ARCH}.rpm") -set(CPACK_RPM_PACKAGE_ARCHITECTURE ${TARGET_ARCH}) -set(CPACK_RPM_PACKAGE_LICENSE "GPLv2.0") -set(CPACK_RPM_PACKAGE_VENDOR "Humanity") - -# set dependencies based on utility drivers -if("${RF24_DRIVER}" STREQUAL "MRAA") - set(CPACK_DEBIAN_PACKAGE_DEPENDS mraa) - set(CPACK_RPM_PACKAGE_REQUIRES "mraa") -elseif("${RF24_DRIVER}" STREQUAL "wiringPi") - set(CPACK_DEBIAN_PACKAGE_DEPENDS wiringPi) - set(CPACK_RPM_PACKAGE_REQUIRES "wiringPi") -elseif("${RF24_DRIVER}" STREQUAL "littlewire-spi") - set(CPACK_DEBIAN_PACKAGE_DEPENDS littlewire-spi) - set(CPACK_RPM_PACKAGE_REQUIRES "littlewire-spi") -endif() - -# create a post-install & post-removal scripts to update linker -set(POST_SCRIPTS - ${CMAKE_BINARY_DIR}/DEBIAN/postrm - ${CMAKE_BINARY_DIR}/DEBIAN/postinst -) -foreach(script ${POST_SCRIPTS}) - file(WRITE ${script} ldconfig) - execute_process(COMMAND chmod +x ${script}) - execute_process(COMMAND chmod 775 ${script}) -endforeach() -# declare scripts for deb pkgs -list(JOIN POST_SCRIPTS ";" EXTRA_CTRL_FILES) -set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA ${EXTRA_CTRL_FILES}) -# declare scripts for rpm pkgs -list(POP_FRONT POST_SCRIPTS CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE) -list(POP_FRONT POST_SCRIPTS CPACK_RPM_POST_INSTALL_SCRIPT_FILE) - -message(STATUS "ready to package: ${CPACK_PACKAGE_FILE_NAME}.deb") -message(STATUS "ready to package: ${CPACK_RPM_FILE_NAME}") - -include(CPack) diff --git a/RF24/cmake/Cache.cmake b/RF24/cmake/Cache.cmake deleted file mode 100644 index e27a501f1eecf905e1998e8e0bbac71fadc98fe0..0000000000000000000000000000000000000000 --- a/RF24/cmake/Cache.cmake +++ /dev/null @@ -1,28 +0,0 @@ -option(ENABLE_CACHE "Enable cache if available" ON) -if(NOT ENABLE_CACHE) - return() -endif() - -set(CACHE_OPTION "ccache" CACHE STRING "Compiler cache to be used") -set(CACHE_OPTION_VALUES "ccache" "sccache") -set_property(CACHE CACHE_OPTION PROPERTY STRINGS ${CACHE_OPTION_VALUES}) -list( - FIND - CACHE_OPTION_VALUES - ${CACHE_OPTION} - CACHE_OPTION_INDEX -) - -if(${CACHE_OPTION_INDEX} EQUAL -1) - message(STATUS - "Using custom compiler cache system: '${CACHE_OPTION}', explicitly supported entries are ${CACHE_OPTION_VALUES}" - ) -endif() - -find_program(CACHE_BINARY ${CACHE_OPTION}) -if(CACHE_BINARY) - message(STATUS "${CACHE_OPTION} found and enabled") - set(CMAKE_CXX_COMPILER_LAUNCHER ${CACHE_BINARY}) -else() - message(WARNING "${CACHE_OPTION} is enabled but was not found. Not using it") -endif() diff --git a/RF24/cmake/CompilerWarnings.cmake b/RF24/cmake/CompilerWarnings.cmake deleted file mode 100644 index e40f0ab79a1691c3a181f03c13b98dd2d250e470..0000000000000000000000000000000000000000 --- a/RF24/cmake/CompilerWarnings.cmake +++ /dev/null @@ -1,78 +0,0 @@ -# from here: -# -# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md - -function(set_project_warnings project_name) - option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" TRUE) - - set(MSVC_WARNINGS - /W4 # Baseline reasonable warnings - /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data - /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data - /w14263 # 'function': member function does not override any base class virtual member function - /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not - # be destructed correctly - /w14287 # 'operator': unsigned/negative constant mismatch - /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside - # the for-loop scope - /w14296 # 'operator': expression is always 'boolean_value' - /w14311 # 'variable': pointer truncation from 'type1' to 'type2' - /w14545 # expression before comma evaluates to a function which is missing an argument list - /w14546 # function call before comma missing argument list - /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect - /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'? - /w14555 # expression has no effect; expected expression with side- effect - /w14619 # pragma warning: there is no warning number 'number' - /w14640 # Enable warning on thread un-safe static member initialization - /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior. - /w14905 # wide string literal cast to 'LPSTR' - /w14906 # string literal cast to 'LPWSTR' - /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied - /permissive- # standards conformance mode for MSVC compiler. - ) - - set(CLANG_WARNINGS - -Wall - -Wextra # reasonable and standard - -Wshadow # warn the user if a variable declaration shadows one from a parent context - -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps - # catch hard to track down memory errors - # -Wold-style-cast # warn for c-style casts - -Wcast-align # warn for potential performance problem casts - -Wunused # warn on anything being unused - -Woverloaded-virtual # warn if you overload (not override) a virtual function - -Wpedantic # warn if non-standard C++ is used - -Wconversion # warn on type conversions that may lose data - -Wsign-conversion # warn on sign conversions - -Wnull-dereference # warn if a null dereference is detected - -Wdouble-promotion # warn if float is implicit promoted to double - -Wformat=2 # warn on security issues around functions that format output (ie printf) - ) - - if(WARNINGS_AS_ERRORS) - set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror) - set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX) - endif() - - set(GCC_WARNINGS - ${CLANG_WARNINGS} - -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist - -Wduplicated-cond # warn if if / else chain has duplicated conditions - -Wduplicated-branches # warn if if / else branches have duplicated code - -Wlogical-op # warn about logical operations being used where bitwise were probably wanted - -Wuseless-cast # warn if you perform a cast to the same type - ) - - if(MSVC) - set(PROJECT_WARNINGS ${MSVC_WARNINGS}) - elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - set(PROJECT_WARNINGS ${CLANG_WARNINGS}) - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(PROJECT_WARNINGS ${GCC_WARNINGS}) - else() - message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") - endif() - - target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) - -endfunction() diff --git a/RF24/cmake/GetLibInfo.cmake b/RF24/cmake/GetLibInfo.cmake deleted file mode 100644 index 3871395ed8a8937ca59421b502e57c2bce1a6835..0000000000000000000000000000000000000000 --- a/RF24/cmake/GetLibInfo.cmake +++ /dev/null @@ -1,43 +0,0 @@ -# get lib info from the maintained library.properties required by the Arduino IDE -file(STRINGS ${CMAKE_CURRENT_LIST_DIR}/../library.properties LibInfo) -foreach(line ${LibInfo}) - string(FIND ${line} "=" label_delimiter) - if(${label_delimiter} GREATER 0) - math(EXPR label_delimiter "${label_delimiter} + 1") - string(FIND ${line} "version" has_version) - string(FIND ${line} "name" has_name) - string(FIND ${line} "maintainer" has_maintainer) - string(FIND ${line} "sentence" has_sentence) - string(FIND ${line} "url" has_url) - string(FIND ${line} "paragraph" has_paragraph) - if(${has_version} EQUAL 0) - string(SUBSTRING ${line} ${label_delimiter} "-1" VERSION) - elseif(${has_name} EQUAL 0) - string(SUBSTRING ${line} ${label_delimiter} "-1" LibName) - elseif(${has_maintainer} EQUAL 0) - string(SUBSTRING ${line} ${label_delimiter} "-1" CPACK_PACKAGE_CONTACT) - elseif(${has_sentence} EQUAL 0) - string(SUBSTRING ${line} ${label_delimiter} "-1" CPACK_PACKAGE_DESCRIPTION_SUMMARY) - elseif(${has_url} EQUAL 0) - string(SUBSTRING ${line} ${label_delimiter} "-1" CMAKE_PROJECT_HOMEPAGE_URL) - elseif(${has_paragraph} EQUAL 0) - string(SUBSTRING ${line} ${label_delimiter} "-1" CPACK_PACKAGE_DESCRIPTION) - endif() - endif() -endforeach() - -# convert the LibName to lower case -string(TOLOWER ${LibName} LibTargetName) - -#parse the version information into pieces. -string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VERSION}") -string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VERSION}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VERSION}") - -# this is the library version -set(${LibName}_VERSION_MAJOR ${VERSION_MAJOR}) -set(${LibName}_VERSION_MINOR ${VERSION_MINOR}) -set(${LibName}_VERSION_PATCH ${VERSION_PATCH}) -set(${LibName}_VERSION_STRING ${${LibName}_VERSION_MAJOR}.${${LibName}_VERSION_MINOR}.${${LibName}_VERSION_PATCH}) - -message(STATUS "${LibName} library version: ${${LibName}_VERSION_STRING}") diff --git a/RF24/cmake/PreventInSourceBuilds.cmake b/RF24/cmake/PreventInSourceBuilds.cmake deleted file mode 100644 index dc4fd811bf619c5774e720cb0d83877ceaacbcea..0000000000000000000000000000000000000000 --- a/RF24/cmake/PreventInSourceBuilds.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -# This function will prevent in-source builds -function(AssureOutOfSourceBuilds) - # make sure the user doesn't play dirty with symlinks - get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) - get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) - - # disallow in-source builds - if("${srcdir}" STREQUAL "${bindir}") - message("######################################################") - message("Warning: in-source builds are disabled") - message("Please create a separate build directory and run cmake from there") - message("######################################################") - message(FATAL_ERROR "Quitting configuration") - endif() -endfunction() - -assureoutofsourcebuilds() diff --git a/RF24/cmake/Sanitizers.cmake b/RF24/cmake/Sanitizers.cmake deleted file mode 100644 index c9d3ac821ce0a6ee19175ca3df0b754f7e26d351..0000000000000000000000000000000000000000 --- a/RF24/cmake/Sanitizers.cmake +++ /dev/null @@ -1,55 +0,0 @@ -function(enable_sanitizers project_name) - - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) - - if(ENABLE_COVERAGE) - target_compile_options(${project_name} INTERFACE --coverage -O0 -g) - target_link_libraries(${project_name} INTERFACE --coverage) - endif() - - set(SANITIZERS "") - - option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" FALSE) - if(ENABLE_SANITIZER_ADDRESS) - list(APPEND SANITIZERS "address") - endif() - - option(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" FALSE) - if(ENABLE_SANITIZER_LEAK) - list(APPEND SANITIZERS "leak") - endif() - - option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" FALSE) - if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) - list(APPEND SANITIZERS "undefined") - endif() - - option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" FALSE) - if(ENABLE_SANITIZER_THREAD) - if("address" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS) - message(WARNING "Thread sanitizer does not work with Address and Leak sanitizer enabled") - else() - list(APPEND SANITIZERS "thread") - endif() - endif() - - option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" FALSE) - if(ENABLE_SANITIZER_MEMORY AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - if("address" IN_LIST SANITIZERS OR "thread" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS) - message(WARNING "Memory sanitizer does not work with Address, Thread and Leak sanitizer enabled") - else() - list(APPEND SANITIZERS "memory") - endif() - endif() - - list(JOIN SANITIZERS "," LIST_OF_SANITIZERS) - - endif() - - if(LIST_OF_SANITIZERS AND NOT "${LIST_OF_SANITIZERS}" STREQUAL "") - target_compile_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) - target_link_libraries(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) - endif() - -endfunction() diff --git a/RF24/cmake/StandardProjectSettings.cmake b/RF24/cmake/StandardProjectSettings.cmake deleted file mode 100644 index 35fdec0fd51d7c59083b51595eabf0426e176cd3..0000000000000000000000000000000000000000 --- a/RF24/cmake/StandardProjectSettings.cmake +++ /dev/null @@ -1,33 +0,0 @@ -# Set a default build type if none was specified -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) - message(STATUS "Setting build type to '${CMAKE_BUILD_TYPE}' as none was specified.") - - # Set the possible values of build type for cmake-gui, ccmake - set_property( - CACHE CMAKE_BUILD_TYPE - PROPERTY STRINGS - "Debug" - "Release" - "MinSizeRel" - "RelWithDebInfo" - ) -endif() - -# Generate compile_commands.json to make it easier to work with clang based tools -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF) - -if(ENABLE_IPO) - include(CheckIPOSupported) - check_ipo_supported( - RESULT result - OUTPUT output - ) - if(result) - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) - else() - message(SEND_ERROR "IPO is not supported: ${output}") - endif() -endif() diff --git a/RF24/cmake/StaticAnalyzers.cmake b/RF24/cmake/StaticAnalyzers.cmake deleted file mode 100644 index 5f8e56aa12d58b637f9811efacc08368d41c07fe..0000000000000000000000000000000000000000 --- a/RF24/cmake/StaticAnalyzers.cmake +++ /dev/null @@ -1,38 +0,0 @@ -option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF) -option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF) -option(ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" OFF) - -if(ENABLE_CPPCHECK) - find_program(CPPCHECK cppcheck) - if(CPPCHECK) - set(CMAKE_CXX_CPPCHECK - ${CPPCHECK} - --suppress=missingInclude - --enable=all - --inline-suppr - --inconclusive - -i - ${CMAKE_SOURCE_DIR}/imgui/lib - ) - else() - message(SEND_ERROR "cppcheck requested but executable not found") - endif() -endif() - -if(ENABLE_CLANG_TIDY) - find_program(CLANGTIDY clang-tidy) - if(CLANGTIDY) - set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option) - else() - message(SEND_ERROR "clang-tidy requested but executable not found") - endif() -endif() - -if(ENABLE_INCLUDE_WHAT_YOU_USE) - find_program(INCLUDE_WHAT_YOU_USE include-what-you-use) - if(INCLUDE_WHAT_YOU_USE) - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${INCLUDE_WHAT_YOU_USE}) - else() - message(SEND_ERROR "include-what-you-use requested but executable not found") - endif() -endif() diff --git a/RF24/cmake/detectCPU.cmake b/RF24/cmake/detectCPU.cmake deleted file mode 100644 index cc32362828d09475ba5d8496f3d8f11e21b6fd56..0000000000000000000000000000000000000000 --- a/RF24/cmake/detectCPU.cmake +++ /dev/null @@ -1,78 +0,0 @@ -# try to get the CPU model using a Linux bash command -if(NOT SOC) # if SOC variable not defined by user at CLI - if(EXISTS "/sys/class/sunxi_info/sys_info") - execute_process(COMMAND grep sunxi_platform /sys/class/sunxi_info/sys_info - OUTPUT_VARIABLE CPU_MODEL - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - else() - execute_process(COMMAND grep Hardware /proc/cpuinfo - OUTPUT_VARIABLE CPU_MODEL - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - endif() - - string(FIND "${CPU_MODEL}" ":" cpu_is_described) - if(${cpu_is_described} GREATER 0) # Hardware field does exist - math(EXPR cpu_is_described "${cpu_is_described} + 1") - string(SUBSTRING "${CPU_MODEL}" ${cpu_is_described} -1 SOC) - string(STRIP "${SOC}" SOC) - else() # Hardware field does not exist - set(SOC "UNKNOWN") # use this string as a sentinel - endif() - message(STATUS "detected SoC: ${SOC}") -else() - message(STATUS "SOC set to ${SOC}") -endif() - -string(FIND "${SOC}" "Generic AM33XX" is_AM33XX) - -#[[ detect machine hardware name -This CPU_TYPE variable is not used anywhere. -It remains as useful prompt info & to be consistent with old build system ]] -execute_process(COMMAND uname -m - OUTPUT_VARIABLE CPU_TYPE - OUTPUT_STRIP_TRAILING_WHITESPACE -) -message(STATUS "detected CPU type: ${CPU_TYPE}") - -# identify the compiler base name for customizing flags -# THIS ONLY WORKS/TESTED FOR GNU COMPILERS -if(NOT CMAKE_CROSSCOMPILING) # need to use /usr/lib/gcc soft symlink - # NOTE the following command doesn't work with " | tail -1" appended - execute_process(COMMAND ls /usr/lib/gcc - OUTPUT_VARIABLE tool_name - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - # use only last entry if multiple entries are returned; this tactic is a possible point of error - string(FIND "${tool_name}" "\n" last_list_delimiter REVERSE) - if(last_list_delimiter GREATER -1) - math(EXPR last_list_delimiter "${last_list_delimiter} + 1") - string(SUBSTRING "${tool_name}" ${last_list_delimiter} -1 tool_name) - endif() - -else() # we can use the compiler's name of the path set in the toolchain file - string(REGEX REPLACE "^\/usr\/bin\/(.*)-gcc.*" "\\1" tool_name "${CMAKE_C_COMPILER}") -endif() - -message(STATUS "tool name being used: ${tool_name}") - -# add compiler flags to optomize builds with arm-linux-gnueabihf-g* compilers -if("${tool_name}" STREQUAL "arm-linux-gnueabihf") - if("${SOC}" STREQUAL "BCM2835" OR "${SOC}" STREQUAL "BCM2708") - add_compile_options(-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard) - elseif("$SOC" STREQUAL "BCM2836" OR "${SOC}" STREQUAL "BCM2709") - add_compile_options(-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard) - elseif(${is_AM33XX} GREATER -1) - add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard) - elseif("$SOC" STREQUAL "sun4i" OR "${SOC}" STREQUAL "Sun4iw1p1") # A10 - add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard) - elseif("$SOC" STREQUAL "sun5i" OR "${SOC}" STREQUAL "Sun4iw2p1") # A13 - add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard) - elseif("$SOC" STREQUAL "sun7i" OR "${SOC}" STREQUAL "Sun8iw2p1") # A20 - add_compile_options(-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard) - elseif("$SOC" STREQUAL "sun8i" OR "${SOC}" STREQUAL "Sun8iw7p1") # H3 - add_compile_options(-march=armv8-a -mtune=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard) - endif() -endif() diff --git a/RF24/cmake/pico_sdk_import.cmake b/RF24/cmake/pico_sdk_import.cmake deleted file mode 100644 index 0a1da564fb521c9a77ebc7643134c2df23bbd294..0000000000000000000000000000000000000000 --- a/RF24/cmake/pico_sdk_import.cmake +++ /dev/null @@ -1,62 +0,0 @@ -# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake -# -# This can be dropped into an external project to help locate this SDK -# It should be include()ed prior to project() - -if(DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) - set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) - message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") -endif() - -if(DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) - set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) - message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") -endif() - -if(DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) - set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) - message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") -endif() - -set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") -set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") -set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") - -if(NOT PICO_SDK_PATH) - if(PICO_SDK_FETCH_FROM_GIT) - include(FetchContent) - set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) - if(PICO_SDK_FETCH_FROM_GIT_PATH) - get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") - endif() - FetchContent_Declare( - pico_sdk - GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk - GIT_TAG master - ) - if(NOT pico_sdk) - message("Downloading Raspberry Pi Pico SDK") - FetchContent_Populate(pico_sdk) - set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) - endif() - set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) - else () - message(FATAL_ERROR - "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." - ) - endif() -endif() - -get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") -if(NOT EXISTS ${PICO_SDK_PATH}) - message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") -endif() - -set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) -if(NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) - message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") -endif() - -set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) - -include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/RF24/cmake/toolchains/arm64.cmake b/RF24/cmake/toolchains/arm64.cmake deleted file mode 100644 index 23e41ca7f8b693777b5f2b164bb80acbd5b8fa68..0000000000000000000000000000000000000000 --- a/RF24/cmake/toolchains/arm64.cmake +++ /dev/null @@ -1,33 +0,0 @@ -###################### FOR CROSS-COMPILING using the aarch64-linux-gnu-g** compiler -# invoke this toolchain file using `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/<ARCH_TYPE>.cmake` -# this file is meant to be used generically, but will not work for all CMake projects -# this toolchain file's cmds was copied from the CMake docs then modified for better explanation and re-use - -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_PROCESSOR arm64) -set(TARGET_ARCH arm64) # only used in cmake/createDebianPkg.cmake -set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc) -set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++) - -# CMAKE_SYSROOT can only be set in a toolchain file -# set(CMAKE_SYSROOT /usr/aarch64-linux-gnu) # useful when a target machine's files are available - -# set the directory for searching installed headers -# add_compile_options(-I /usr/aarch64-linux-gnu/include) # this may not be best practice - -#[[ -# CMAKE_STAGING_PREFIX is only useful for transfering a built CMake project to a target machine -set(CMAKE_STAGING_PREFIX /home/devel/stage) # use CMAKE_INSTALL_PREFIX instead (see below comments) - -CMAKE_FIND_ROOT_PATH is an empty list by default (this list can be modified where applicable) -if cross-compiling a dependent lib (like MRAA - which is optional), then -set the lib's CMAKE_INSTALL_PREFIX to a value that is appended to RF24 lib's CMAKE_FIND_ROOT_PATH -example using MRAA: -(for MRAA/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=path/to/RF24/repo/cmake/toolchains/arm64.cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/aarch64-linux-gnu -(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm64.cmake -]] -list(APPEND CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_package() is called diff --git a/RF24/cmake/toolchains/armhf.cmake b/RF24/cmake/toolchains/armhf.cmake deleted file mode 100644 index 488b81a8932e26ba6abeceb29fe32a5b7133e350..0000000000000000000000000000000000000000 --- a/RF24/cmake/toolchains/armhf.cmake +++ /dev/null @@ -1,33 +0,0 @@ -###################### FOR CROSS-COMPILING using the arm-linux-gnueabihf-g** compiler -# invoke this toolchain file using `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/<ARCH_TYPE>.cmake` -# this file is meant to be used generically, but will not work for all CMake projects -# this toolchain file's cmds was copied from the CMake docs then modified for better explanation and re-use - -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_PROCESSOR armhf) -set(TARGET_ARCH armhf) # only used in cmake/CPackInfo.cmake -set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc) -set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++) - -# CMAKE_SYSROOT can only be set in a toolchain file -# set(CMAKE_SYSROOT /usr/arm-linux-gnueabihf) # useful when a target machine's files are available - -# set the directory for searching installed headers -# add_compile_options(-I /usr/arm-linux-gnueabihf/include) # this may not be best practice - -#[[ -# CMAKE_STAGING_PREFIX is only useful for transfering a built CMake project to a target machine -set(CMAKE_STAGING_PREFIX /home/devel/stage) # use CMAKE_INSTALL_PREFIX instead (see below comments) - -CMAKE_FIND_ROOT_PATH is an empty list by default (this list can be modified where applicable) -if cross-compiling a dependent lib (like MRAA - which is optional), then -set the lib's CMAKE_INSTALL_PREFIX to a value that is appended to RF24 lib's CMAKE_FIND_ROOT_PATH -example using MRAA: -(for MRAA/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=path/to/RF24/repo/cmake/toolchains/arm.cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/arm-linux-gnueabihf -(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm.cmake -]] -list(APPEND CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_package() is called diff --git a/RF24/cmake/toolchains/clang.cmake b/RF24/cmake/toolchains/clang.cmake deleted file mode 100644 index 4795f407b3d0b8a07bad43c30d768e4f4316a946..0000000000000000000000000000000000000000 --- a/RF24/cmake/toolchains/clang.cmake +++ /dev/null @@ -1,9 +0,0 @@ -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_PROCESSOR arm) - -set(triple arm-linux-gnueabihf) - -set(CMAKE_C_COMPILER clang) -set(CMAKE_C_COMPILER_TARGET ${triple}) -set(CMAKE_CXX_COMPILER clang++) -set(CMAKE_CXX_COMPILER_TARGET ${triple}) diff --git a/RF24/cmake/toolchains/default.cmake b/RF24/cmake/toolchains/default.cmake deleted file mode 100644 index e67d723f8526bb8748251c25e49d273a5218d9e8..0000000000000000000000000000000000000000 --- a/RF24/cmake/toolchains/default.cmake +++ /dev/null @@ -1 +0,0 @@ -# empty toolchain file to allow CI scripts to still use system default toolchains \ No newline at end of file diff --git a/RF24/cmake/toolchains/i686.cmake b/RF24/cmake/toolchains/i686.cmake deleted file mode 100644 index f3c42be069f95763d2a359b3818bfdf6ef303ec0..0000000000000000000000000000000000000000 --- a/RF24/cmake/toolchains/i686.cmake +++ /dev/null @@ -1,33 +0,0 @@ -###################### FOR CROSS-COMPILING using the i686-linux-gnu-g** compiler -# invoke this toolchain file using `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/<ARCH_TYPE>.cmake` -# this file is meant to be used generically, but will not work for all CMake projects -# this toolchain file's cmds was copied from the CMake docs then modified for better explanation and re-use - -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_PROCESSOR i686) -set(TARGET_ARCH i686) # only used in cmake/createDebianPkg.cmake -set(CMAKE_C_COMPILER /usr/bin/i686-linux-gnu-gcc) -set(CMAKE_CXX_COMPILER /usr/bin/i686-linux-gnu-g++) - -# CMAKE_SYSROOT can only be set in a toolchain file -# set(CMAKE_SYSROOT /usr/i686-linux-gnu) # useful when a target machine's files are available - -# set the directory for searching installed headers -# add_compile_options(-I /usr/i686-linux-gnu/include) # this may not be best practice - -#[[ -# CMAKE_STAGING_PREFIX is only useful for transfering a built CMake project to a target machine -set(CMAKE_STAGING_PREFIX /home/devel/stage) # use CMAKE_INSTALL_PREFIX instead (see below comments) - -CMAKE_FIND_ROOT_PATH is an empty list by default (this list can be modified where applicable) -if cross-compiling a dependent lib (like MRAA - which is optional), then -set the lib's CMAKE_INSTALL_PREFIX to a value that is appended to RF24 lib's CMAKE_FIND_ROOT_PATH -example using MRAA: -(for MRAA/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=path/to/RF24/repo/cmake/toolchains/i686.cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/i686-linux-gnu -(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/i686.cmake -]] -list(APPEND CMAKE_FIND_ROOT_PATH /usr/i686-linux-gnu) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_package() is called diff --git a/RF24/cmake/toolchains/x86_64.cmake b/RF24/cmake/toolchains/x86_64.cmake deleted file mode 100644 index e4ff737a8ed379e2ed032852af924f11e55d20b7..0000000000000000000000000000000000000000 --- a/RF24/cmake/toolchains/x86_64.cmake +++ /dev/null @@ -1,33 +0,0 @@ -###################### FOR CROSS-COMPILING using the x86_64-linux-gnux32-g** compiler -# invoke this toolchain file using `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/<ARCH_TYPE>.cmake` -# this file is meant to be used generically, but will not work for all CMake projects -# this toolchain file's cmds was copied from the CMake docs then modified for better explanation and re-use - -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_PROCESSOR x86_64) -set(TARGET_ARCH x86_64) # only used in cmake/createDebianPkg.cmake -set(CMAKE_C_COMPILER /usr/bin/x86_64-linux-gnux32-gcc) -set(CMAKE_CXX_COMPILER /usr/bin/x86_64-linux-gnux32-g++) - -# CMAKE_SYSROOT can only be set in a toolchain file -# set(CMAKE_SYSROOT /usr/x86_64-linux-gnux32) # useful when a target machine's files are available - -# set the directory for searching installed headers -# add_compile_options(-I /usr/x86_64-linux-gnux32/include) # this may not be best practice - -#[[ -# CMAKE_STAGING_PREFIX is only useful for transfering a built CMake project to a target machine -set(CMAKE_STAGING_PREFIX /home/devel/stage) # use CMAKE_INSTALL_PREFIX instead (see below comments) - -CMAKE_FIND_ROOT_PATH is an empty list by default (this list can be modified where applicable) -if cross-compiling a dependent lib (like MRAA - which is optional), then -set the lib's CMAKE_INSTALL_PREFIX to a value that is appended to RF24 lib's CMAKE_FIND_ROOT_PATH -example using MRAA: -(for MRAA/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=path/to/RF24/repo/cmake/toolchains/x86_64.cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/x86_64-linux-gnux32 -(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/x86_64.cmake -]] -list(APPEND CMAKE_FIND_ROOT_PATH /usr/x86_64-linux-gnux32) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_package() is called diff --git a/RF24/configure b/RF24/configure deleted file mode 100644 index 84dd4593d63dabeab42db53a04085ed0d521646c..0000000000000000000000000000000000000000 --- a/RF24/configure +++ /dev/null @@ -1,499 +0,0 @@ -#!/bin/bash - -CROSS_CC=arm-linux-gnueabihf-gcc -CROSS_CXX=arm-linux-gnueabihf-g++ - -pigpio_detected=0 - -function help { -cat <<EOF -configure script for RF24 library. -Options: - -Help: - -h, --help print this message - -Driver options: - --driver=[wiringPi|SPIDEV|MRAA|RPi|LittleWire] - Driver for RF24 library. [configure autodetected] - -Building options: - --os=[LINUX|DARWIN] Operating system. [configure autodetected] - --soc=[BCM2835|BCM2836|AM33XX|A10|A13|A20|H3] - SoC type to be used. [configure autodetected] - --cpu-flags=<CFLAGS> CPU defining/optimizing flags to be used. [configure autodetected] - --extra-cflags=<CFLAGS> Extra C flags passed to C/C++ compilation. [] - --extra-ldflags=<LDFLAGS> Extra C flags passed to linking. [] - --libname=<LIBNAME> Library name. [rf24] - --c_compiler=<CC> C compiler. [arm-linux-gnueabihf-gcc][gcc] - --cxx_compiler=<CXX> C++ compiler [arm-linux-gnueabihf-g++][g++] - --no-clean Don't clean previous build artifacts - -Installation options: - --prefix=<PREFIX> Installation prefix path. [/usr/local] - --lib-dir=<DIR> Library target installation directory. [PREFIX/lib] - --header-dir=<DIR> Header files target installation directory. [PREFIX/include] - --examples-dir=<DIR> Example files installation directory. [PREFIX/bin] - --ldconfig=<LDCONFIG> Ldconfig binary. Can be set to '' to skip ldconfig step. [ldconfig] - -Cross-compilation options: - --remote-host=<REMOTE_HOST> Remote hostname for installation. - --remote-user=<REMOTE_USER> Remote username for installation. [current user] - --remote-port=<REMOTE_PORT> Ssh port of remote machine. [22] - --remote=<USER@HOST> Remote ssh host identification for installation [REMOTE_USER@REMOTE_HOST] - --remote-prefix=<RPREFIX> Remote host installation prefix path. [/usr/local] - --remote-lib-dir=<DIR> Remote library target installation directory [RPREFIX/lib] - --remote-header-dir=<DIR> Remote header files target installation directory. [RPREFIX/include] - --remote-ldconfig=<RLDCON> Remote ldconfig binary filename. Can be set to '' to skip ldconfig call. [ldconfig] - --remote-examples-dir=<DIR> Example files remote installation directory. Default: [REMOTE_PREFIX/bin] - -EOF -} - -function execute_check { - if [ "${REMOTE}" ]; then - ssh -o 'PasswordAuthentication=no' -o 'PreferredAuthentications=publickey' -o 'ConnectTimeout=30' -o 'BatchMode=yes' -o 'StrictHostKeyChecking=no' -p ${REMOTE_PORT} ${REMOTE} $1 - else - eval $1 - fi -} - -if [[ -f "/usr/lib/libpigpio.so" || -f "/usr/local/lib/libpigpio.so" || -f "/usr/arm-linux-gnueabihf/lib/libpigpio.so" ]]; then - echo "[INFO] pigpio lib found." - pigpio_detected=1 -fi - -function die { - echo "[ERROR] $1" - exit $2 -} - -function detect_machine { - local cpu=$(execute_check "uname -m 2>/dev/null") - local machine=$(execute_check "cat -v /sys/firmware/devicetree/base/model 2>/dev/null") - local hardware=$(execute_check "grep sunxi_platform /sys/class/sunxi_info/sys_info 2>/dev/null | sed 's/^.*: \(.*\)$/\1/'") - if [ -z "$hardware" ]; then - local hardware=$(execute_check "grep Hardware /proc/cpuinfo 2>/dev/null | sed 's/^.*: \(.*\)$/\1/'") - fi - local soc="unknown" - local tp="unknown" - - if [ -z "$cpu" ]; then - cpu="unknown" - fi - - case $hardware in - BCM2708|BCM2835) - soc="BCM2835" - if [[ $machine == "Raspberry"* ]]; then - tp="RPi" - fi - ;; - BCM2709) - soc="BCM2836" - if [[ $machine == "Raspberry"* ]]; then - tp="RPi2" - fi - ;; - sun4i|Sun4iw1p1) - soc="A10" - ;; - sun5i|Sun4iw2p1) - soc="A13" - ;; - Sun4iw2p2) - soc="A12" - ;; - Sun4iw2p3) - soc="A10s" - ;; - sun6i|Sun8iw1p1) - soc="A31" - ;; - Sun8iw1p2) - soc="A31s" - ;; - sun7i|Sun8iw2p1) - soc="A20" - if [[ $machine == "Banana Pi"* ]]; then - tp="BananaPi" - elif [[ $machine == "Banana Pro"* ]]; then - tp="BananaPro" - fi - ;; - sun8i|Sun8iw7p1) - soc="H3" - ;; - Sun8iw3p1) - soc="A23" - ;; - Sun8iw5p1) - soc="A33" - ;; - Sun8iw6p1) - soc="A83t" - ;; - sun9i|Sun9iw1p1) - soc="A80" - ;; - Sun9iw1p2) - soc="A80t" - ;; - sun50i|Sun50iw1p1) - soc="A64" - ;; - 'Generic AM33XX'*) - soc="AM33XX" - ;; - *) - soc="unknown" - esac - echo "${soc} ${tp} ${cpu}" -} - -function gcc_cpu_flags { - local soc=$1 - case $soc in - BCM2835) - flags="-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard" - ;; - BCM2836) - flags="-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard" - ;; - AM33XX) - flags="-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard" - ;; - A10) - flags="-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard" - ;; - A13) - flags="-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard" - ;; - A20) - flags="-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard" - ;; - H3) - flags="-march=armv8-a -mtune=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard" - ;; - *) - flags="" - esac - echo ${flags} -} - -function detect_driver { - if [[ $(execute_check "cat /proc/cpuinfo | grep Hardware | grep 'BCM2708\|BCM2709\|BCM2835'") ]]; then - result=RPi - elif [[ $(execute_check 'ls /dev/spidev* 2>/dev/null') ]]; then - result=SPIDEV - elif [[ $(execute_check "file /usr/lib/libwiringPi.so*") ]]; then - result=wiringPi - elif [[ $(execute_check "${REMOTE_LDCONFIG} -p | grep libmraa") ]]; then - result=MRAA - elif [[ $(execute_check "${REMOTE_LDCONFIG} -p | grep liblittlewire-spi") ]]; then - result=LittleWire - elif [ $pigpio_detected -eq 1 ]; then - result=pigpio - else - result="" - fi - echo $result -} - -function gen_symlink_names { - base_name="$1" - version="$2" - - IFS='.' read -r -a ver <<< "$version" - versions="" - for index in "${!ver[@]}" ; do - verstr="" - for ind in `seq 0 $(expr $index - 1)` ; do - verstr="${verstr}.${ver[$ind]}" - done - versions="${base_name}${verstr} $versions" - done - echo ${versions} -} - -params="OS SOC DRIVER CPUFLAGS CFLAGS PREFIX REMOTE_PREFIX LIB LIBNAME LIB_VERSION LIBSYMLINKS LIBDEPRECATE CC CXX LIB_DIR REMOTE_LIB_DIR HEADER_DIR REMOTE_HEADER_DIR DRIVER_DIR ARCH_DIR REMOTE REMOTE_HOST REMOTE_USER REMOTE_PORT SHARED_LINKER_FLAGS SHARED_LINKER_LIBS LDCONFIG REMOTE_LDCONFIG EXAMPLES_DIR REMOTE_EXAMPLES_DIR" - -for opt do - if [ "$opt" = "-h" ] || [ "$opt" = "--help" ]; then - help - exit 0 - fi - optarg="${opt#*=}" - case "$opt" in - --os=*) - OS="$optarg" - ;; - --soc=*) - SOC="$optarg" - ;; - --cpu-flags=*) - CPUFLAGS="$optarg" - ;; - --extra-cflags=*) - CFLAGS="$optarg" - ;; - --extra-ldflags=*) - LDFLAGS="$optarg" - ;; - --libname=*) - LIB="$optarg" - ;; - --c_compiler=*) - CC="$optarg" - ;; - --cxx_compiler=*) - CXX="$optarg" - ;; - --no-clean*) - NO_CLEAN="1" - ;; - --prefix=*) - PREFIX="$optarg" - ;; - --lib-dir=*) - LIB_DIR="$optarg" - ;; - --header-dir=*) - HEADER_DIR="$optarg" - ;; - --examples-dir=*) - EXAMPLES_DIR="$optarg" - ;; - --ldconfig=*) - LDCONFIG="$optarg" - ;; - --driver=*) - DRIVER="$optarg" - ;; - --remote-host=*) - REMOTE_HOST="$optarg" - ;; - --remote-user=*) - REMOTE_USER="$optarg" - ;; - --remote-port=*) - REMOTE_PORT="$optarg" - ;; - --remote=*) - REMOTE="$optarg" - ;; - --remote-prefix=*) - REMOTE_PREFIX="$optarg" - ;; - --remote-lib-dir=*) - REMOTE_LIB_DIR="$optarg" - ;; - --remote-header-dir=*) - REMOTE_HEADER_DIR="$optarg" - ;; - --remote-ldconfig=*) - REMOTE_LDCONFIG="$optarg" - ;; - --remote-examples-dir=*) - REMOTE_EXAMPLES_DIR="$optarg" - ;; - *) - echo "[WARNING] Unknown option detected:$opt, ignored" - ;; - esac -done - -#******************************************* -# remote machine verification -if [ "${REMOTE_HOST}" ]; then - if [ "${REMOTE_USER}" ]; then - REMOTE=${REMOTE_USER}@${REMOTE_HOST} - else - REMOTE=${REMOTE_HOST} - fi -fi -if [ "${REMOTE}" ]; then - echo "[SECTION] Checking remote host." - if [ -z "${REMOTE_HOST}" ]; then - REMOTE_HOST=${REMOTE/*@/} - fi - if [ -z "${REMOTE_PORT}" ]; then - REMOTE_PORT=22 - fi - if [ "$(nmap ${REMOTE_HOST} -Pn --host-timeout 30s -p ${REMOTE_PORT} 2>/dev/null | grep open)" ]; then - echo " [OK] ssh daemon on ${REMOTE_HOST} port ${REMOTE_PORT} seems to be listening." - else - echo " [WARNING] ssh on ${REMOTE_HOST} port ${REMOTE_PORT} seems not to be listening or nmap not installed." - fi - if [[ "$(execute_check 'echo ok 2>/dev/null' 2>/dev/null)" ]]; then - echo " [OK] Remote machine ssh passwordless login configured fine." - else - die "Remote machine ssh and/or passwordless login check failed." 4 - fi - if [[ $(execute_check "sudo echo ok 2>/dev/null") ]]; then - echo " [OK] Remote machine sudo configured fine." - else - die "Remote machine sudo test failed." 5 - fi -fi - -if [ -z "${CC}" ]; then - echo "[SECTION] Detecting arm compilation environment." - if [[ $(command -v ${CROSS_CC} 2>/dev/null) ]]; then - echo " [OK] ${CROSS_CC} detected." - CC=${CROSS_CC} - CROSS_SYSROOT="$(${CC} --print-sysroot)" - if [ "${CROSS_SYSROOT}" = "/" ]; then - CROSS_SYSROOT="" - fi - else - echo " [INFO] ${CROSS_CC} not found." - fi - if [[ $(command -v ${CROSS_CXX} 2>/dev/null) ]]; then - echo " [OK] ${CROSS_CXX} detected." - CXX=${CROSS_CXX} - else - echo " [INFO] ${CROSS_CXX} not found." - fi -fi - -if [ "${CROSS_SYSROOT}" ]; then - PREFIX="${CROSS_SYSROOT}/usr/local" -fi - -PREFIX=${PREFIX:-/usr/local} -REMOTE_PREFIX=${REMOTE_PREFIX:-/usr/local} -LIB_DIR=${LIB_DIR:-${PREFIX}/lib} -REMOTE_LIB_DIR=${REMOTE_LIB_DIR:-${REMOTE_PREFIX}/lib} -HEADER_DIR=${HEADER_DIR:-${PREFIX}/include/RF24} -REMOTE_HEADER_DIR=${REMOTE_HEADER_DIR:-${REMOTE_PREFIX}/include/RF24} -EXAMPLES_DIR=${EXAMPLES_DIR:-${PREFIX}/bin} -REMOTE_EXAMPLES_DIR=${REMOTE_EXAMPLES_DIR:-${REMOTE_PREFIX}/bin} -LDCONFIG=${LDCONFIG-ldconfig} -REMOTE_LDCONFIG=${REMOTE_LDCONFIG-/sbin/ldconfig} -LIB=${LIB:-rf24} -LIB_VERSION=${LIB_VERSION:-$(awk -F "=" '/version/ {print $2}' library.properties)} -LIB_DEPRECATE_NAME=${LIB_DEPRECATE_NAME:-"rf24-bcm"} -LIB_DEPRECATE_VERSION=${LIB_DEPRECATE_VERSION:-""} -CC=${CC:-gcc} -CXX=${CXX:-g++} -ARCH_DIR=${ARCH_DIR:-utility} - - -if [ -z "${SOC}" ]; then - echo "[SECTION] Detecting target machine." - info=($(detect_machine)) - SOC=${info[0]} - TYPE=${info[1]} - CPU=${info[2]} - echo "[OK] machine detected: SoC=${SOC}, Type=${TYPE}, CPU=${CPU}." -fi - -if [ -z "${CPUFLAGS}" ]; then - CPUFLAGS=$(gcc_cpu_flags $SOC) -fi - - -#******************************************* -# DRIVER detection -if [ -z "${DRIVER}" ]; then - echo "[SECTION] Detecting DRIVER" - DRIVER=$(detect_driver) - if [ -z "${DRIVER}" ]; then - die "No supported driver detected. Run configure with --driver=<driver> to set a driver explicitly." 1 - fi - echo " [OK] DRIVER detected:${DRIVER}." -fi - -case ${DRIVER} in -wiringPi) - SHARED_LINKER_LIBS+=" -lpigpio -lwiringPi" - CFLAGS+=" -lwiringPi" - ;; -SPIDEV) - if [ $pigpio_detected -eq 1 ]; then - echo "[INFO] linking to pigpio for interrupt compatibility" - SHARED_LINKER_LIBS+=" -lpigpio" - else - CFLAGS+=" -DRF24_NO_INTERRUPT" - fi - ;; -RPi) - if [ $pigpio_detected -eq 1 ]; then - echo "[INFO] linking to pigpio for interrupt compatibility" - SHARED_LINKER_LIBS+=" -lpigpio" - else - CFLAGS+=" -DRF24_NO_INTERRUPT" - fi - ;; -MRAA) - SHARED_LINKER_LIBS+=" -lmraa" - ;; -LittleWire) - SHARED_LINKER_LIBS+=" -llittlewire-spi" - ;; -pigpio) - if [ $pigpio_detected -eq 0 ]; then - die "[ERROR] pigpio was not detected. Make sure pigpio is installed." 2 - else - SHARED_LINKER_LIBS+=" -lpigpio" - fi - ;; -*) - die "Unsupported DRIVER: ${DRIVER}." 2 - ;; -esac - -#******************************************* -# OS detection -if [ -z "${OS}" ]; then - echo "[SECTION] Detecting OS." - OS=$(execute_check "uname") - OS=${OS^^} - echo " [INFO] OS detected:${OS}." -fi - -case ${OS} in -LINUX) - DYN_SUFFIX=so - SHARED_LINKER_FLAGS+=" -shared -Wl,-soname,lib${LIB}.${DYN_SUFFIX}.${LIB_VERSION%%.*}" - ;; -DARWIN) - DYN_SUFFIX=dylib - SHARED_LINKER_FLAGS+=" -dynamiclib -install_name ${LIB_DIR}/lib${LIB}.${DYN_SUFFIX}.${LIB_VERSION%%.*}" - ;; -*) - die "Unsupported OS: ${OS}." 3 - ;; -esac - - -LIBNAME=${LIBNAME:-lib${LIB}.${DYN_SUFFIX}.${LIB_VERSION}} -LIBSYMLINKS="${LIBSYMLINKS:-$(gen_symlink_names lib${LIB}.${DYN_SUFFIX} ${LIB_VERSION})}" -if [ "${LIB_DEPRECATE_NAME}" ]; then - LIBDEPRECATE="${LIBDEPRECATE:-lib${LIB_DEPRECATE_NAME}.${DYN_SUFFIX}}" - if [ "${LIB_DEPRECATE_VERSION}" ]; then - LIBDEPRECATE="${LIBDEPRECATE}.${LIB_DEPRECATE_VERSION}" - fi -fi -DRIVER_DIR=${DRIVER_DIR:-${ARCH_DIR}/${DRIVER}} -CFLAGS="$CPUFLAGS -Ofast -Wall -pthread $CFLAGS" - -echo "[SECTION] Preparing configuration." -cp ${DRIVER_DIR}/includes.h ${ARCH_DIR}/includes.h - -echo "[SECTION] Saving configuration." -echo -n "" > Makefile.inc -for param in ${params}; do - if [[ ${!param} ]]; then - echo "${param}=${!param}" >> Makefile.inc - fi -done - -if [ -z "${NO_CLEAN}" ]; then - echo "[SECTION] Cleaning previous builds." - make clean >/dev/null -fi - - -echo "[OK] Finished." diff --git a/RF24/datasheets/nRF24L01P_datasheet_v1.pdf b/RF24/datasheets/nRF24L01P_datasheet_v1.pdf deleted file mode 100644 index b35803355e80ef44c658b3ac139300cea8e40d34..0000000000000000000000000000000000000000 Binary files a/RF24/datasheets/nRF24L01P_datasheet_v1.pdf and /dev/null differ diff --git a/RF24/datasheets/nRF24L01_datasheet_v2.pdf b/RF24/datasheets/nRF24L01_datasheet_v2.pdf deleted file mode 100644 index f8d77a456a96a7ff109a51537c30d117b7e4ffcc..0000000000000000000000000000000000000000 Binary files a/RF24/datasheets/nRF24L01_datasheet_v2.pdf and /dev/null differ diff --git a/RF24/docs/README.md b/RF24/docs/README.md deleted file mode 100644 index 4de76d0c6b799f2f636b7f6ea5d23b6ead140741..0000000000000000000000000000000000000000 --- a/RF24/docs/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Please browse the docs from either http://nrf24.github.io/RF24 or https://rf24.rtfd.io -## Intended for use in Doxygen - -These markdown files (\*.md) in this docs folder contain relative hyperlinks. Any relative hyperlinks will not work when viewing these markdown files in github. diff --git a/RF24/docs/arduino.md b/RF24/docs/arduino.md deleted file mode 100644 index c0e106eeeccb93bfc000e0d53f2f7d2957473dfe..0000000000000000000000000000000000000000 --- a/RF24/docs/arduino.md +++ /dev/null @@ -1,286 +0,0 @@ -# Arduino - -<!-- markdownlint-disable MD031 --> -RF24 is fully compatible with Arduino boards. - -See [Arduino Board reference](http://www.arduino.cc/en/Reference/Board) and [Arduino SPI reference](http://arduino.cc/en/Reference/SPI) for more information - -RF24 makes use of the standard hardware SPI pins (MISO, MOSI, SCK) and requires two additional pins, to control -the chip-select and chip-enable functions. - -```cpp -RF24 radio(ce_pin, cs_pin); -``` - -These pins must be chosen and designated by the user and can use any -available pins. - -## Alternate SPI Support - -RF24 supports alternate SPI methods, in case the standard hardware SPI pins are otherwise unavailable. - -### Software Driven SPI - -Software driven SPI is provided by the [DigitalIO library](https://github.com/greiman/DigitalIO). - -Setup: - -1. Install the digitalIO library -2. Open RF24_config.h in a text editor. - Uncomment the line - ```cpp - #define SOFTSPI - ``` - or add the build flag/option - ```shell - -DSOFTSPI - ``` -3. In your sketch, add - ```cpp - #include <DigitalIO.h> - ``` - -@note Note: Pins are listed as follows and can be modified by editing the RF24_config.h file. - -```cpp -#define SOFT_SPI_MISO_PIN 16 -#define SOFT_SPI_MOSI_PIN 15 -#define SOFT_SPI_SCK_PIN 14 -``` - -Or add the build flag/option - -```shell --DSOFT_SPI_MISO_PIN=16 -DSOFT_SPI_MOSI_PIN=15 -DSOFT_SPI_SCK_PIN=14 -``` - -### Alternate Hardware (UART) Driven SPI - -The Serial Port (UART) on Arduino can also function in SPI mode, and can double-buffer data, while the -default SPI hardware cannot. - -The SPI_UART library is available at [TMRh20/Sketches](https://github.com/TMRh20/Sketches/tree/master/SPI_UART) - -Enabling: - -1. Install the SPI_UART library -2. Edit RF24_config.h and uncomment - ```cpp - #define SPI_UART - ``` -3. In your sketch, add - ```cpp - #include <SPI_UART.h> - ``` - -SPI_UART SPI Pin Connections: -| NRF |Arduino Uno Pin| -|----:|:--------------| -| MOSI| TX(0) | -| MISO| RX(1) | -| SCK | XCK(4) | -| CE | User Specified| -| CSN | User Specified| - -@note SPI_UART on Mega boards requires soldering to an unused pin on the chip. See [#24](https://github.com/TMRh20/RF24/issues/24) for more information on SPI_UART. - -### Using a specific SPI Bus - -An alternate SPI bus can be specified using the overloaded `RF24::begin(_SPI*)` method. -This is useful for some boards that offer more than 1 hardware-driven SPI bus or cetain Arduino -cores that implement a software-driven (AKA bit-banged) SPI bus that does not use the DigitalIO -library. - -@warning The SPI bus object's `SPIClass::begin()` method **must** be called before -calling the overloaded `RF24::begin(_SPI*)` method. - -Below are some example snippets that demonstrate how this can be done. - -#### ESP8266 example - -@see The following example code is meant for the popular NodeMCU board. Please refer to the -[ESP8266 ArduinoCore's SPI documentation](https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#spi) -for [other ESP8266-based boards](https://arduino-esp8266.readthedocs.io/en/latest/boards.html#). - -```cpp -#include <SPI.h> -#include <RF24.h> - -// notice these pin numbers are not the same used in the library examples -RF24 radio(D4, D3); // the (ce_pin, csn_pin) connected to the radio - -void setup() { - Serial.begin(115200); - while (!Serial) {} //some boards need this - - // by default (with no arguments passed) SPI uses D5 (HSCLK), D6 (HMISO), D7 (HMOSI) - SPI.pins(6, 7, 8, 0); - // this means the following pins are used for the SPI bus: - // MOSI = SD1 - // MISO = SD0 - // SCLK = CLK - // CSN = GPIO0 (labeled D3 on the board) - // **notice we also passed `D3` to the RF24 contructor's csn_pin parameter** - - SPI.begin(); - - if (!radio.begin(&SPI)) { - Serial.println(F("radio hardware not responding!!")); - while (1) {} // hold program in infinite loop to prevent subsequent errors - } - - // ... continue with program as normal (see library examples/ folder) -} -``` - -#### ESP32 example - -@see Please review the Espressif's -[SPI_Multiple_Buses.ino example for the ESP32](https://github.com/espressif/arduino-esp32/blob/master/libraries/SPI/examples/SPI_Multiple_Buses/SPI_Multiple_Buses.ino) -located in their ArduinoCore repository (along with the SPI library for the ESP32). - -```cpp -#include <SPI.h> -#include <RF24.h> - -// to use custom-defined pins, uncomment the following -// #define MY_MISO 26 -// #define MY_MOSI 27 -// #define MY_SCLK 25 -// #define MY_SS 32 // pass MY_SS as the csn_pin parameter to the RF24 constructor - -// notice these pin numbers are not the same used in the library examples -RF24 radio(2, 0); // the (ce_pin, csn_pin) connected to the radio - -SPIClass* hspi = nullptr; // we'll instantiate this in the `setup()` function -// by default the HSPI bus predefines the following pins -// HSPI_MISO = 12 -// HSPI_MOSI = 13 -// HSPI_SCLK = 14 -// HSPI_SS = 15 - -void setup() { - Serial.begin(115200); - while (!Serial) {} //some boards need this - - hspi = new SPIClass(HSPI); // by default VSPI is used - hspi->begin(); - // to use the custom defined pins, uncomment the following - // hspi->begin(MY_SCLK, MY_MISO, MY_MOSI, MY_SS) - - if (!radio.begin(hspi)) { - Serial.println(F("radio hardware not responding!!")); - while (1) {} // hold program in infinite loop to prevent subsequent errors - } - - // ... continue with program as normal (see library examples/ folder) -} -``` - -#### Teensy example - -@see The overloaded RF24::begin(\_SPI\*) is not needed according to the -[Teensyduino SPI documentation](https://www.pjrc.com/teensy/td_libs_SPI.html). -Please review the table provided in the -[Teensyduino documentation](https://www.pjrc.com/teensy/td_libs_SPI.html) for what pins are used by -default for certain Teensy boards. - -```cpp -#include <SPI.h> -#include <RF24.h> - -// these pins are the alternate SPI pins available for Teensy LC/3.0/3.1/3.2/3.5/3.6 -#define MY_MISO 8 -#define MY_MOSI 7 -#define MY_SCLK 14 - -// notice these pin numbers are not the same used in the library examples -RF24 radio(2, 0); // the (ce_pin, csn_pin) connected to the radio - -void setup() { - Serial.begin(115200); - while (!Serial) {} //some boards need this - - SPI.setMOSI(MY_MOSI); - SPI.setMISO(MY_MISO); - SPI.setSCK(MY_SCLK); - - if (!radio.begin()) { - Serial.println(F("radio hardware not responding!!")); - while (1) {} // hold program in infinite loop to prevent subsequent errors - } - - // ... continue with program as normal (see library examples/ folder) -} -``` - -<!-- -#### MBED example -@see The [ArduinoCore-mbed SPI library](https://github.com/arduino/ArduinoCore-mbed/tree/master/libraries/SPI) -has predefined the possible hardware-driven SPI buses. This applies to Arduino Nano 33 BLE and -Arduino Portenta boards. - -```cpp -#include <SPI.h> -#include <RF24.h> - -RF24 radio(7, 8); // the (ce_pin, csn_pin) connected to the radio - -void setup() { - Serial.begin(115200); - while (!Serial) {} //some boards need this - - SPI1.begin(); - - if (!radio.begin(&SPI1)) { - Serial.println(F("radio hardware not responding!!")); - while (1) {} // hold program in infinite loop to prevent subsequent errors - } - - // ... continue with program as normal (see library examples/ folder) -} -``` - -#### ATSAMD21 example -@see The Suport for secondary SPI bus on ATSAMD21 chips is sparcely documented. However, -[Sparkfun has a tutorial about using a second SPI bus](https://learn.sparkfun.com/tutorials/adding-more-sercom-ports-for-samd-boards/adding-an-spi) -that often refers to the -[ArduinoCore-samd SPI library source code](https://github.com/arduino/ArduinoCore-samd/blob/master/libraries/SPI/SPI.h). This example applies Sparkfun's tutorial toward the RF24 library. -Special thanks to [ex-caliper](https://github.com/ex-caliper) for the lead! - -```cpp -#include <SPI.h> -#include <RF24.h> -#include "wiring_private.h" // pinPeripheral() - -// Define the pins are the alternate SPI pins we will use. These pin numbers ARE NOT chosen at random. -// The Sparkfun tutorial explains these choices in more detail (link is in "See Also" comment above). -#define MY_MISO 3 -#define MY_MOSI 4 -#define MY_SCLK 5 - -// instantiate the secondary SPI bus -SPIClass MY_SPI(&sercom2, MY_MISO, MY_SCLK, MY_MOSI, SPI_PAD_0_SCK_3, SERCOM_RX_PAD_1); - -// notice these pin numbers are not the same used in the library examples -RF24 radio(7, 6); // the (ce_pin, csn_pin) connected to the radio - -void setup() { - Serial.begin(115200); - while (!Serial) {} //some boards need this - - // enable the alternate functionality for our secondary SPI bus' pins - pinPeripheral(MY_MISO, PIO_SERCOM_ALT); - pinPeripheral(MY_MOSI, PIO_SERCOM_ALT); - pinPeripheral(MY_SCLK, PIO_SERCOM); - - MY_SPI.begin(); // initialize the secondary SPI bus - - if (!radio.begin(&MY_SPI)) { - Serial.println(F("radio hardware not responding!!")); - while (1) {} // hold program in infinite loop to prevent subsequent errors - } - - // ... continue with program as normal (see library examples/ folder) -} -``` --> diff --git a/RF24/docs/attiny.md b/RF24/docs/attiny.md deleted file mode 100644 index 379d81b1fcf69d815bd541fd976707d1c67053a0..0000000000000000000000000000000000000000 --- a/RF24/docs/attiny.md +++ /dev/null @@ -1,79 +0,0 @@ -# ATTiny - -ATTiny support for this library relys on the SpenceKonde ATTinyCore. Be sure to have added this core to the Arduino Boards Manager with [this install guide](http://highlowtech.org/?p=1695) - -See the included rf24ping85 example for pin info and usage - -@warning The ATTiny2313 is unsupported due to lack of sufficient memory resources - -Some versions of Arduino IDE may require a patch to allow use of the full program space on ATTiny. See [this resource](https://github.com/TCWORLD/ATTinyCore/tree/master/PCREL%20Patch%20for%20GCC) for the ATTiny patch. - -ATTiny board support initially added from [jscrane/RF24](https://github.com/jscrane/RF24) - -## Hardware Configuration - -By [tong67](https://github.com/tong67) - -### ATtiny25/45/85 Pin map with CE_PIN 3 and CSN_PIN 4 - -```text - +-\/-+ - NC PB5 1|o |8 Vcc --- nRF24L01 VCC, pin2 --- LED --- 5V -nRF24L01 CE, pin3 --- PB3 2| |7 PB2 --- nRF24L01 SCK, pin5 -nRF24L01 CSN, pin4 --- PB4 3| |6 PB1 --- nRF24L01 MOSI, pin6 -nRF24L01 GND, pin1 --- GND 4| |5 PB0 --- nRF24L01 MISO, pin7 - +----+ -``` - -### ATtiny25/45/85 Pin map with CE_PIN 3 and CSN_PIN 3 - PB3 and PB4 are free to use for application - -- Circuit idea from [NerdRalph's 3 pin solution](http://nerdralph.blogspot.ca/2014/01/nrf24l01-control-with-3-attiny85-pins.html) -- Original RC combination was 1K/100nF. 22K/10nF combination worked better. -- For best settletime delay value in RF24::csn() the timingSearch3pin.ino sketch can be used. -- This configuration is enabled when CE_PIN and CSN_PIN are equal, e.g. both 3 -- Because CE is always high the power consumption is higher than for 5 pins solution - -```text - ^^ - +-\/-+ nRF24L01 CE, pin3 ------| // - PB5 1|o |8 Vcc --- nRF24L01 VCC, pin2 ------x----------x--|<|-- 5V - NC PB3 2| |7 PB2 --- nRF24L01 SCK, pin5 --|<|---x-[22k]--| LED - NC PB4 3| |6 PB1 --- nRF24L01 MOSI, pin6 1n4148 | -nRF24L01 GND, pin1 -x- GND 4| |5 PB0 --- nRF24L01 MISO, pin7 | - | +----+ | - |-----------------------------------------------||----x-- nRF24L01 CSN, pin4 - 10nF -``` - -### ATtiny24/44/84 Pin map with CE_PIN 8 and CSN_PIN 7 - -- Schematic provided and successfully tested by [Carmine Pastore](https://github.com/Carminepz) - -```text - +-\/-+ -nRF24L01 VCC, pin2 --- VCC 1|o |14 GND --- nRF24L01 GND, pin1 - PB0 2| |13 AREF - PB1 3| |12 PA1 - PB3 4| |11 PA2 --- nRF24L01 CE, pin3 - PB2 5| |10 PA3 --- nRF24L01 CSN, pin4 - PA7 6| |9 PA4 --- nRF24L01 SCK, pin5 -nRF24L01 MISO, pin7 --- PA6 7| |8 PA5 --- nRF24L01 MOSI, pin6 - +----+ -``` - -### ATtiny2313/4313 Pin map with CE_PIN 12 and CSN_PIN 13 - -```text - +-\/-+ - PA2 1|o |20 VCC --- nRF24L01 VCC, pin2 - PD0 2| |19 PB7 --- nRF24L01 SCK, pin5 - PD1 3| |18 PB6 --- nRF24L01 MOSI, pin6 - PA1 4| |17 PB5 --- nRF24L01 MISO, pin7 - PA0 5| |16 PB4 --- nRF24L01 CSN, pin4 - PD2 6| |15 PB3 --- nRF24L01 CE, pin3 - PD3 7| |14 PB2 - PD4 8| |13 PB1 - PD5 9| |12 PB0 -nRF24L01 GND, pin1 --- GND 10| |11 PD6 - +----+ -``` diff --git a/RF24/docs/atxmega.md b/RF24/docs/atxmega.md deleted file mode 100644 index b79659072812e7fd04e6fac701c4ec3b87a724af..0000000000000000000000000000000000000000 --- a/RF24/docs/atxmega.md +++ /dev/null @@ -1,55 +0,0 @@ -# ATXMEGA - -The RF24 driver can be build as a static library with Atmel Studio 7 in order to be included as any other library in another program for the XMEGA family. - -Currently only the [ATXMEGA D3](https://www.microchip.com/wwwproducts/en/ATxmega64d3) family is implemented. - -## Preparation - -Create an empty GCC Static Library project in Atmel Studio 7. - -As not all files are required, copy the following directory structure in the project: - -```text -utility\ - ATXMegaD3\ - compatibility.c - compatibility.h - gpio.cpp - gpio.h - gpio_helper.c - gpio_helper.h - includes.h - RF24_arch_config.h - spi.cpp - spi.h -nRF24L01.h -printf.h -RF24.cpp -RF24.h -RF24_config.h -``` - -## Usage - -Add the library to your project! - -In the file where the `main()` is put the following in order to update the millisecond functionality: - -```cpp -ISR(TCE0_OVF_vect) -{ - update_milisec(); -} -``` - -Declare the rf24 radio with `RF24 radio(XMEGA_PORTC_PIN3, XMEGA_SPI_PORT_C);` - -1. First parameter is the CE pin which can be any available pin on the microcontroller. -2. Second parameter is the CS which can be on port C (**XMEGA_SPI_PORT_C**) or on port D (**XMEGA_SPI_PORT_D**). - -Call the `__start_timer()` to start the millisecond timer. - -@note The millisecond functionality is based on the TCE0 so don't use these pins as IO. - -@note The operating frequency of the uC is 32MHz. If you have a different frequency, change the TCE0 registers appropriatly in function `__start_timer()` in **compatibility.c** file for your frequency. diff --git a/RF24/docs/cross_compile.md b/RF24/docs/cross_compile.md deleted file mode 100644 index bcff6c5fcfe47db0b95be5231586662f82ea53fa..0000000000000000000000000000000000000000 --- a/RF24/docs/cross_compile.md +++ /dev/null @@ -1,98 +0,0 @@ -# Linux cross-compilation - -<!-- markdownlint-disable MD031 --> -@warning These instructions are no longer recommended because they involve disabling security measures -for the target system. Please try the [instructions using CMake](md_docs_using_cmake.html). - -RF24 library supports cross-compilation. Advantages of cross-compilation: - -- development tools don't have to be installed on target machine -- resources of target machine don't have to be sufficient for compilation -- compilation time can be reduced for large projects - -Following prerequisites need to be assured: - -- ssh passwordless access to target machine [Here is a hint](https://linuxconfig.org/passwordless-ssh) -- sudo of a remote user without password [Here is a hint](http://askubuntu.com/questions/334318/sudoers-file-enable-nopasswd-for-user-all-commands) -- cross-compilation toolchain for your target machine; for RPi - ```shell - git clone https://github.com/raspberrypi/tools rpi_tools - ``` - and cross-compilation tools must be in PATH, for example - ```shell - export PATH=$PATH:/your/dir/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin - ``` - -## Cross compilation steps - -1. clone RF24 to a machine for cross-compilation - ```shell - git clone https://github.com/nRF24/RF24 - cd RF24 - ``` -2. configure for cross compilation - ```shell - ./configure --remote=pi@target_linux_host - ``` - eventually - ```shell - ./configure --remote=pi@target_linux_host --driver=<driver> - ``` -3. build - ```shell - make - ``` -4. (optional) install library to cross-compilation machine into cross-exvironment - important for compilation of examples - ```shell - sudo make install - ``` -5. upload library to target machine - ```shell - make upload - ``` -6. (optional) compile examples - ```shell - cd examples_linux - make - ``` -7. (optional) upload examples to target machine - ```shell - make upload - ``` - -## Cross comilation steps for python wrapper - -### Prerequisites - -- Python setuptools must be installed on both target and cross-compilation machines - ```shell - sudo pip install setuptools - ``` - or - ```shell - sudo apt-get install python-setuptools - ``` - -### Installation steps - -1. Assure having libboost-python-dev library in your cross-compilation environment. Alternatively, you can install it into your target machine and copy /usr and /lib directories to the cross-compilation machine. - For example - ```shell - mkdir -p rpi_root && rsync -a pi@target_linux_host:/usr :/lib rpi_root - export CFLAGS="--sysroot=/your/dir/rpi_root -I/your/dir/rpi_root/usr/include/python2.7/" - ``` -2. Build the python wrapper - ```shell - cd pyRF24 - ./setup.py build --compiler=crossunix - ``` -3. Make the egg package - ```shell - ./setup.py bdist_egg --plat-name=cross - ``` - `dist/RF24-<version>-cross.egg` should be created. -4. Upload it to the target machine and install there: - ```shell - scp dist/RF24-*-cross.egg pi@target_linux_host: - ssh pi@target_linux_host 'sudo easy_install RF24-*-cross.egg' - ``` diff --git a/RF24/docs/linux_install.md b/RF24/docs/linux_install.md deleted file mode 100644 index 58e2ac613b0b29e2d06900d463cfdf96be450b29..0000000000000000000000000000000000000000 --- a/RF24/docs/linux_install.md +++ /dev/null @@ -1,96 +0,0 @@ -# Linux Installation - -<!-- markdownlint-disable MD031 --> -Generic Linux devices are supported via SPIDEV, MRAA, RPi native via BCM2835, or using LittleWire. - -@note The SPIDEV option should work with most Linux systems supporting spi userspace device. - -@warning These install instructions are beginning to age because they were designed with the assumption that -the arm-linux-gnueabihf-g\*\* compilers were available and default for the system. If you have problems -using the manual install instructions (especially on a 64-bit OS), please try the -[instructions using CMake](md_docs_using_cmake.html). - -@note Since wiringPi is no longer maintained or distributed (as of RPi OS 11 bullseye), -pigpio is now required for using the radio's IRQ pin. This applies to RPi, SPIDEV, and pigpio drivers. The MRAA driver may provide its own IRQ implementation. Remember that the RPi OS lite variant does not ship with pigpio installed. - -## Automated Install - -**Designed & Tested on RPi** - Defaults to SPIDEV on devices supporting it - -1. Install prerequisites if there are any (pigpio, MRAA, LittleWire libraries, setup SPI device etc) -2. Download the install.sh file from [http://tmrh20.github.io/RF24Installer/RPi/install.sh](http://tmrh20.github.io/RF24Installer/RPi/install.sh) - ```shell - wget http://tmrh20.github.io/RF24Installer/RPi/install.sh - ``` -3. Make it executable - ```shell - chmod +x install.sh - ``` -4. Run it and choose your options - ```shell - ./install.sh - ``` -5. Run an example from one of the libraries - ```shell - cd rf24libs/RF24/examples_linux - ``` - Edit the gettingstarted example, to set your pin configuration - ```shell - nano gettingstarted.cpp - make - sudo ./gettingstarted - ``` - -## Manual Install - -1. Install prerequisites if there are any (pigpio, MRAA, LittleWire libraries, setup SPI device etc) - @note See the [MRAA](http://iotdk.intel.com/docs/master/mraa/index.html) documentation for more info on installing MRAA -2. Make a directory to contain the RF24 and possibly RF24Network lib and enter it - ```shell - mkdir ~/rf24libs - cd ~/rf24libs - ``` -3. Clone the RF24 repo - ```shell - git clone https://github.com/tmrh20/RF24.git RF24 - ``` -4. Change to the new RF24 directory - ```shell - cd RF24 - ``` -5. Configure build environment using - ```shell - ./configure - ``` - script. It auto detectes device and build environment. - - For overriding autodetections, use command-line switches, see - ```shell - ./configure --help - ``` - for description. -6. Build the library, and run an example file - ```shell - make - sudo make install - ``` - ```shell - cd examples_linux - ``` - Edit the gettingstarted example, to set your pin configuration - ```shell - ano gettingstarted.cpp - make - sudo ./gettingstarted - ``` - -### Build using SPIDEV - -1. Make sure that spi device support is enabled and /dev/spidev\<a\>.\<b\> is present -2. Manual Install using SPIDEV: - ```shell - ./configure --driver=SPIDEV - make - sudo make install - ``` -3. See the gettingstarted example for an example of pin configuration diff --git a/RF24/docs/main_page.md b/RF24/docs/main_page.md deleted file mode 100644 index 5290a569dae046e4a8825df1080c0a0e19283af4..0000000000000000000000000000000000000000 --- a/RF24/docs/main_page.md +++ /dev/null @@ -1,80 +0,0 @@ -# Optimized High Speed Driver for nRF24L01(+) 2.4GHz Wireless Transceiver - -## Design Goals - -This library fork is designed to be... - -- More compliant with the manufacturer specified operation of the chip, while allowing advanced users - to work outside the recommended operation. -- Utilize the capabilities of the radio to their full potential via Arduino -- More reliable, responsive, bug-free and feature rich -- Easy for beginners to use, with well documented examples and features -- Consumed with a public interface that's similar to other Arduino standard libraries - -## News - -See the releases' descriptions on -[the library's release page](http://github.com/nRF24/RF24/releases) for a list of -changes. - -## Useful References - -- [RF24 Class Documentation](classRF24.html) -- [Support & Configuration](pages.html) -- [Source Code](https://github.com/nRF24/RF24/) -- [nRF24L01 v2.0 Datasheet](http://github.com/nRF24/RF24/raw/master/datasheets/nRF24L01_datasheet_v2.pdf) -- [nRF24L01+ v1.0 Datasheet](http://github.com/nRF24/RF24/raw/master/datasheets/nRF24L01P_datasheet_v1.pdf) - -### Additional Information and Add-ons - -- [RF24Network](http://nRF24.github.io/RF24Network): OSI Network Layer for multi-device communication. Create a home sensor network. -- [RF24Mesh](http://nRF24.github.io/RF24Mesh): Dynamic Mesh Layer for RF24Network -- [RF24Ethernet](http://nRF24.github.io/RF24Ethernet): TCP/IP Radio Mesh Networking (shares Arduino Ethernet API) -- [RF24Audio](http://nRF24.github.io/RF24Audio): Realtime Wireless Audio streaming -- [TMRh20 Blog: RF24 Optimization Overview](http://tmrh20.blogspot.com/2014/03/high-speed-data-transfers-and-wireless.html) -- [TMRh20: RPi/Linux with RF24Gateway](http://tmrh20.blogspot.com/2016/08/raspberry-pilinux-with-nrf24l01.html) -- [All TMRh20 Documentation Main Page](http://tmrh20.github.io/) - -### More Information - -- [Project Blog: TMRh20.blogspot.com](http://TMRh20.blogspot.com) -- [Maniacal Bits Blog](http://maniacalbits.blogspot.ca/) -- [Original Maniacbug RF24Network Blog Post](https://maniacbug.wordpress.com/2012/03/30/rf24network/) -- [ManiacBug on GitHub](https://github.com/maniacbug/RF24) (Original Library Author) -- [MySensors.org](http://www.mysensors.org/) (User friendly sensor networks/IoT) - -## Platform Support Pages - -- [Arduino](md_docs_arduino.html) (Uno, Nano, Mega, Due, Galileo, etc) -- [ATTiny](md_docs_attiny.html) -- [Pico SDK support](md_docs_pico_sdk.html) -- [Linux Installation](md_docs_linux_install.html) (or the alternative [instructions using CMake](md_docs_using_cmake.html)), - ([Linux/RPi General](md_docs_rpi_general.html), [MRAA](md_docs_mraa.html) supported boards (Galileo, Edison, etc), LittleWire) -- [Cross-compilation](md_docs_cross_compile.html) for linux devices -- [Python wrapper](md_docs_python_wrapper.html) available for Linux devices - -### General µC Pin layout - -@see also the individual board [support pages](pages.html) for more info - -Observe - - - -The table below shows how to connect the the pins of the NRF24L01(+) to different boards. -CE and CSN are configurable. - -| PIN | NRF24L01 | Arduino UNO | ATtiny25/45/85 [0] | ATtiny44/84 [1] | LittleWire [2] | RPI | RPi -P1 Connector | -| --- | -------- | ----------- | ------------------ | --------------- | ----------------------- | ---------- | ----------------- | -| 1 | GND | GND | pin 4 | pin 14 | GND | rpi-gnd | (25) | -| 2 | VCC | 3.3V | pin 8 | pin 1 | regulator 3.3V required | rpi-3v3 | (17) | -| 3 | CE | digIO 7 | pin 2 | pin 12 | pin to 3.3V | rpi-gpio22 | (15) | -| 4 | CSN | digIO 8 | pin 3 | pin 11 | RESET | rpi-gpio8 | (24) | -| 5 | SCK | digIO 13 | pin 7 | pin 9 | SCK | rpi-sckl | (23) | -| 6 | MOSI | digIO 11 | pin 6 | pin 7 | MOSI | rpi-mosi | (19) | -| 7 | MISO | digIO 12 | pin 5 | pin 8 | MISO | rpi-miso | (21) | -| 8 | IRQ | - | - | - | - | - | - | - -- [0] https://learn.sparkfun.com/tutorials/tiny-avr-programmer-hookup-guide/attiny85-use-hints -- [1] http://highlowtech.org/?p=1695 The ATTiny2313 is unsupported due to lack of sufficient memory resources. -- [2] http://littlewire.github.io/ diff --git a/RF24/docs/mraa.md b/RF24/docs/mraa.md deleted file mode 100644 index 7d8f5d936aabab9855cd7a7dbd3cc032886db157..0000000000000000000000000000000000000000 --- a/RF24/docs/mraa.md +++ /dev/null @@ -1,40 +0,0 @@ -# MRAA - -<!-- markdownlint-disable MD031 --> -MRAA is a Low Level Skeleton Library for Communication on GNU/Linux platforms. -Review the [MRAA documentation](http://iotdk.intel.com/docs/master/mraa/index.html) for more information - -RF24 supports all MRAA supported platforms, but it might not have been tested on each individual platform due to the wide range of hardware support: - -- [Report an RF24 bug or issue](https://github.com/TMRh20/RF24/issues) - -## Setup and installation - -Build using the **MRAA** library from [MRAA documentation](http://iotdk.intel.com/docs/master/mraa/index.html) - -MRAA is not included. - -1. Install, and build MRAA - ```shell - git clone https://github.com/intel-iot-devkit/mraa.git - cd mraa - mkdir build - cd build - cmake .. -DBUILDSWIGNODE=OFF - sudo make install - ``` -2. Complete the install - ```shell - nano /etc/ld.so.conf - ``` - Add the line - ```shell - /usr/local/lib/arm-linux-gnueabihf - ``` - Run - ```shell - sudo ldconfig - ``` -3. Install RF24, using MRAA - - See [Linux Install instructions](md_docs_linux_install.html) diff --git a/RF24/docs/pico_sdk.md b/RF24/docs/pico_sdk.md deleted file mode 100644 index f2a069905731fec58575255e03a8cee188ac1801..0000000000000000000000000000000000000000 --- a/RF24/docs/pico_sdk.md +++ /dev/null @@ -1,174 +0,0 @@ -# Raspberry Pi Pico SDK (for the RP2040) - -<!-- markdownlint-disable MD031 MD046 --> -Just to be very clear and concise: The following instructions are -**not required to use the Arduino IDE** with any RP2040-based boards. -These instructions pertain to using only [Raspberry Pi's Pico SDK](https://github.com/raspberrypi/pico-sdk) -for RP2040 based boards. - -## Prerequisite - -Follow Raspberry Pi's -["Getting Started with Pico" document](https://rptl.io/pico-get-started) to -setup a proper development environment on your host PC (the machine that -will build your project). Notice that the setup instructions are a little -different for building on a Windows PC. - -Either set an environment variable named `PICO_SDK_PATH` that points to your -local clone of the pico-sdk or put the pico-sdk next to the RF24 folder or -next to the folder containing your project using the RF24 library: - - path/to/github/repos/ - pico-sdk/ - RF24/ - my_rf24_project/ - -Alternatively, the RF24 repository (and optionally the RF24Network and RF24Mesh -repositories) can be included into your project's "lib" folder as copies or -git submodules. For more detail, see the below instructions to incorporate -RF24 libs into your project. - -## Building the RF24 examples for the Pico SDK - -Each example imports a set of constants (`CE_PIN`, `CSN_PIN`, `IRQ_PIN`) from the -examples_pico/defaultPins.h file. Default values for SPI pins (SCK, MOSI, MISO) -come from the Pico SDK repository's -[pico-sdk/src/boards/include/boards/\<board_name>.h files](https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards) - -1. Create a "build" directory in the RF24 repository's root directory and - navigate to it: - ```sh - cd RF24 - mkdir build - cd build - ``` -2. Configure CMake for your desired build type and specific RP2040-based board - ```sh - cmake ../examples_pico -DCMAKE_BUILD_TYPE=Release -DPICO_BOARD=pico - ``` - Or if building on a Windows PC: - ```sh - cmake -G "NMake Makefiles" ../examples_pico -DCMAKE_BUILD_TYPE=Release -DPICO_BOARD=pico - ``` - The supported RP2040-based boards are listed in header files in the Pico SDK - repository's [pico-sdk/src/boards/include/boards/\<board_name>.h files](https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards). - If the `-DPICO_BOARD` option is not specified, then the Pico SDK will default to building for the Raspberry Pi Pico board. -3. Build the examples using the CMakeLists.txt file located in the - RF24/examples_pico directory. - ```sh - cmake --build . --config Release - ``` - Notice we specified the build type again using the `--config` option. - - @note If you see an error stating "'PICO_DEFAULT_SPI_SCK_PIN' was not declared in this scope", - then it means the board you selected with the `-DPICO_BOARD` option (in step 2) does not have a - default set of SPI pins defined for it. To workaround this error, see the below instructions to - use different pins for the SPI bus. - - @warning If doing consecutive build attempts, it is strongly encouraged to delete all files in the build - directory before re-attempting to build the project. - -## Incorporating RF24 libs into your project - -In order to use the RF24 libraries in your RP2040 based project: - -1. Make a copy of the RF24 library (and optionally RF24Network and RF24Mesh - libraries) in a "lib" directory located in your project's root directory. - - path/to/my/project/ - lib/ - RF24/ - RF24Network/ - RF24Mesh/ - src/ - CMakeLists.txt - ... - - Alternatively you can add the RF24\* repositories as [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules). -2. Include their CMakeLists.txt files from the RF24 libraries in your project's top-level - CMakeLists.txt file (usually located in the "src" directory). The following snippet - assumes that your project's "src" directory is on the same level as the previously - mentioned "lib" directory. - ```cmake - include(../lib/RF24/CMakeLists.txt) - include(../lib/RF24Network/CMakeLists.txt) - include(../lib/RF24Mesh/CMakeLists.txt) - ``` -3. In the same CMakeLists.txt file from step 2, add the RF24 libraries into the - `target_link_libraries` configuration: - ```cmake - target_link_libraries(${CMAKE_PROJECT_NAME} - # ... Your project's other libraries ... - RF24 - RF24Network - RF24Mesh - ) - ``` - If you are using tinyUSB, this line (or similar) should already exist: - ```cmake - target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) - ``` -4. Finally, remember to include the necessary RF24\* libraries' header files in your - project's source code where applicable. - ```cpp - #include <RF24.h> - #include <RF24Network.h> - #include <RF24Mesh.h> - ``` - @note Any of the project's source file(s) that includes any of RF24\* libraries must be a C++ file. - It is highly recommended to use the `.cpp` file extension for such project source files. - -## Using different pins for the SPI bus - -Initially (without modification), the SPI bus uses the default pins defined in the -Pico SDK repository's [pico-sdk/src/boards/include/boards/\<board_name>.h files](https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards). -However, there may be some boards that do not define the necessary pins to use as defaults. This can -be rememdied using either project source code or build-time configuration. - -@warning There is no support for software driven SPI on RP2040 based boards at this time. -If someone is so inclined to implement this using the Pico SDK's PIO (Programable Input -Output) feature, please submit an issue or pull request to the -[RF24 repository](http://github.com/nRF24/RF24). - -@note Before deciding what pins to use for the SPI bus, review the -[GPIO pins' "Function Select Table" in the Pico SDK documentation](https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__gpio.html#details). -There are essentially 2 SPI buses with multiple pin options for each. - -### Project Source code option - -This option is the most reliable and flexible. It involves calling `SPI.begin()` and then passing the `SPI` object to `RF24::begin(_SPI*)`. - -```cpp -#include <RF24.h> - -RF24 radio(7, 8); // pin numbers connected to the radio's CE and CSN pins (respectively) - -int main() -{ - // again please review the GPIO pins' "Function Select Table" in the Pico SDK docs - spi.begin(spi0, 2, 3, 4); // spi0 or spi1 bus, SCK, TX, RX - - if (!radio.begin(&spi)) { - printf("Radio hardware is not responding!\n"); - } - // continue with program as normal ... -} -``` - -### Build-time configuration option - -To specify the default SPI pins used at build time, you can use either: - -1. declare these pins in the CMakeLists.txt file - ```cmake - target_compile_definitions(${CMAKE_PROJECT_NAME} - PUBLIC PICO_DEFAULT_SPI=0 # can only be 0 or 1 (as in `spi0` or `spi1`) - PUBLIC PICO_DEFAULT_SPI_SCK_PIN=2 # depends on which SPI bus (0 or 1) is being used - PUBLIC PICO_DEFAULT_SPI_TX_PIN=3 # depends on which SPI bus (0 or 1) is being used - PUBLIC PICO_DEFAULT_SPI_RX_PIN=4 # depends on which SPI bus (0 or 1) is being used - ) - ``` -2. additional command line arguments - ```shell - cmake --build . --config Release -DPICO_DEFAULT_SPI=0 -DPICO_DEFAULT_SPI_SCK_PIN=2 -DPICO_DEFAULT_SPI_TX_PIN=3 -DPICO_DEFAULT_SPI_RX_PIN=4 - ``` diff --git a/RF24/docs/portability.md b/RF24/docs/portability.md deleted file mode 100644 index 3d92ebbaa0dfa6847a76ebf5fafac97ac0b6a439..0000000000000000000000000000000000000000 --- a/RF24/docs/portability.md +++ /dev/null @@ -1,38 +0,0 @@ -# RF24 Portability - -The RF24 radio driver mainly utilizes the [Arduino API](http://arduino.cc/en/reference/homePage) -for GPIO, SPI, and timing functions, which are easily replicated on various platforms. - -Support files for these platforms are stored under RF24/utility, and can be modified to provide the -required functionality. - -## Basic Hardware Template - -### RF24/utility - -The RF24 library now includes a basic hardware template to assist in porting to various platforms. - -The following files can be included to replicate standard Arduino functions as needed, allowing devices from ATTiny to Raspberry Pi to utilize the same core RF24 driver. - -| File | Purpose | -| ------------------ | ---------------------------------------------------------------------------- | -| RF24_arch_config.h | Basic Arduino/AVR compatibility, includes for remaining support files, etc | -| includes.h | Linux only. Defines specific platform, include correct RF24_arch_config file | -| spi.h | Provides standardized SPI (`transfer()`) methods | -| gpio.h | Provides standardized GPIO (`digitalWrite()`) methods | -| compatibility.h | Provides standardized timing (`millis()`, `delay()`) methods | -| your_custom_file.h | Provides access to custom drivers for spi, gpio, etc | - -Examples are provided via the included hardware support templates in **RF24/utility** - -See the [modules](modules.html) page for examples of class declarations. - -## Device Detection - -1. The main detection for Linux devices is done in the configure script, with the includes.h from the proper hardware directory copied to RF24/utility/includes.h -2. Secondary detection is completed in RF24_config.h, causing the include.h file to be included for all supported Linux devices -3. RF24.h contains the declaration for SPI and GPIO objects 'spi' and 'gpio' to be used for porting-in related functions. - -## Code - -To have your ported code included in this library, or for assistance in porting, create a pull request or open an issue at [RF24 Library issues](https://github.com/nRF24/RF24) diff --git a/RF24/docs/python_wrapper.md b/RF24/docs/python_wrapper.md deleted file mode 100644 index d2e777d18644fab3c42e8acde3ecab957990aeed..0000000000000000000000000000000000000000 --- a/RF24/docs/python_wrapper.md +++ /dev/null @@ -1,101 +0,0 @@ -# Python Wrapper - -<!-- markdownlint-disable MD031 --> -By [mz-fuzzy](https://github.com/mz-fuzzy) - -## Python Wrapper Prerequisites - -### RF24 - -The RF24 lib needs to be built in C++ & installed for the python wrapper to wrap it. - -See [Linux Installation](md_docs_linux_install.html) (or [installing with CMake](md_docs_using_cmake.html) -alternatively) and [Linux/RPi General](md_docs_rpi_general.html) - -### Python2 - -```shell -sudo apt-get install python-dev libboost-python-dev python-pip python-rpi.gpio -``` - -Next, install some up-to-date python packages. - -```shell -python -m pip install --upgrade pip setuptools -``` - -### Python3 - -```shell -sudo apt-get install python3-dev libboost-python-dev python3-pip python3-rpi.gpio -``` - -Next, install some up-to-date python3 packages. - -```shell -python3 -m pip install --upgrade pip setuptools -``` - -## Installation - -@note Steps 2 and 3 have to be repeated if installing the python wrappers for -RF24Network and RF24Mesh libraries. The prerequisites stated above still apply -to each library. - -1. For python3, setup.py needs a manually created symlink for the boost.python library: - ```shell - sudo ln -s $(ls /usr/lib/$(ls /usr/lib/gcc | tail -1)/libboost_python3*.so | tail -1) /usr/lib/$(ls /usr/lib/gcc | tail -1)/libboost_python3.so - ``` -2. Build the library. - - This step and the next step need to be executed from the appropriate directory of - the cloned RF24* repository: - - navigate to *pyRF24* directory in the RF24 cloned repository - - navigate to *RPi/pyRF24Network* directory in the RF24Network cloned repository - - navigate to *pyRF24Mesh* directory in the RF24Mesh cloned repository - - When in the correct directory, run the following command: - ```shell - ./setup.py build - ``` - or for python3 - ```shell - python3 setup.py build - ``` - @note Build takes several minutes on arm-based machines. Machines with RAM less than 1GB may need to increase amount of swap for build. -3. Install the library - ```shell - sudo ./setup.py install - ``` - or for python3 - ```shell - sudo python3 setup.py install - ``` - See the additional [Platform Support pages](pages.html) for information on connecting your hardware. - - See the included [\*.py files in the "examples_linux" folder](examples.html) for usage information. -4. Running the Example - - The python examples location differ for each RF24* resopitories. - - navigate to *examples_linux* directory in the RF24 cloned repository - - navigate to *RPi/pyRF24Network/examples* directory in the RF24Network cloned repository - - navigate to *examples_RPi* directory in the RF24Mesh cloned repository - - Navigate to the examples_linux directory - ```shell - cd ../examples_linux - ``` - Edit the getting_started.py example to configure the appropriate pins per the [Linux/RPi General](md_docs_rpi_general.html) documentation. - ```shell - nano getting_started.py - ``` - Configure another device, Arduino or RPi with the same example code. It could be C++ or python (see the [list of available examples](examples.html)), but we'll use the same example file on a different device in this tutorial. - - Run the example - ```shell - sudo python getting_started.py - ``` - or for python3 - ```shell - sudo python3 getting_started.py - ``` diff --git a/RF24/docs/rpi_general.md b/RF24/docs/rpi_general.md deleted file mode 100644 index 1081b2c086bfa77d107f470947e1d928c595315e..0000000000000000000000000000000000000000 --- a/RF24/docs/rpi_general.md +++ /dev/null @@ -1,91 +0,0 @@ -# Linux General/Raspberry Pi - -<!-- markdownlint-disable MD031 --> -RF24 supports a variety of Linux based devices via various drivers. Some boards like RPi can utilize multiple methods -to drive the GPIO and SPI functionality. - -## Potential PreConfiguration - -If SPI is not already enabled, load it on boot: - -```shell -sudo raspi-config -``` - -1. Update the tool via the menu as required -2. Select **Advanced** and **enable the SPI kernel module** -3. Update other software and libraries - ```shell - sudo apt-get update - sudo apt-get upgrade - ``` - -## Build Options - -The default build on Raspberry Pi utilizes the included **BCM2835** driver from [the BCM2835 Library](http://www.airspayce.com/mikem/bcm2835) - -1. See [the Linux section for automated installation](md_docs_linux_install.html). -2. Manual install: - ```shell - make - sudo make install - ``` - -## Connections and Pin Configuration - -Using pin 15(GPIO22) for CE, pin 24(GPIO8 commonly labeled as CE0) for CSN - -Can use any available SPI BUS for CSN. - -In general, use - -```cpp -RF24 radio(<ce_pin>, <a>*10+<b>); -``` - -for proper constructor to address the correct spi device at /dev/spidev\<a\>.\<b\> - -Choose any GPIO output pin for radio CE pin. - -### General - -```cpp -RF24 radio(22,0); -``` - -### MRAA Constructor - -```cpp -RF24 radio(15,0); -``` - -See [the MRAA documentation for Raspberry Pi support](http://iotdk.intel.com/docs/master/mraa/rasppi.html) - -### SPI_DEV Constructor - -```cpp -RF24 radio(22, 0); -``` - -See [the Raspberry Pi documentation about the GPIO pins](https://www.raspberrypi.com/documentation/computers/os.html#gpio-and-the-40-pin-header) - -### Pins - -| PIN | NRF24L01 | RPI | RPi -P1 Connector | -| --- | -------- | ---------- | ----------------- | -| 1 | GND | rpi-gnd | (25) | -| 2 | VCC | rpi-3v3 | (17) | -| 3 | CE | rpi-gpio22 | (15) | -| 4 | CSN | rpi-gpio8 | (24) | -| 5 | SCK | rpi-sckl | (23) | -| 6 | MOSI | rpi-mosi | (19) | -| 7 | MISO | rpi-miso | (21) | -| 8 | IRQ | - | - | - -## breif history of RF24 library lineage - -Based on the arduino lib from [J. Coliz](maniacbug@ymail.com), -the library was berryfied by [Purinda Gunasekara](purinda@gmail.com) -then forked from github [stanleyseow/RF24](https://github.com/stanleyseow/RF24) to [jscrane/RF24-rpi](https://github.com/jscrane/RF24-rpi) - -Network lib also based on [farconada/RF24Network](https://github.com/farconada/RF24Network) diff --git a/RF24/docs/sphinx/Makefile b/RF24/docs/sphinx/Makefile deleted file mode 100644 index bbe765a0f4c5c81cce6e50644478784f93bef726..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = ../sphinx -BUILDDIR = ../_build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/RF24/docs/sphinx/README.md b/RF24/docs/sphinx/README.md deleted file mode 100644 index 5ca5047f109e535e6ee1f9dd211151d88786be1a..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Intended for Sphinx only - -The files in this folder are only used to generate documentation using Sphinx (from Doxygen's XML output). diff --git a/RF24/docs/sphinx/RF24_config_8h.rst b/RF24/docs/sphinx/RF24_config_8h.rst deleted file mode 100644 index 009f9dda482db148ca681bfd17ebb2449e70d566..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/RF24_config_8h.rst +++ /dev/null @@ -1,9 +0,0 @@ -RF24_config.h -============= - -.. doxygenfile:: RF24_config.h - -.. literalinclude:: ../../RF24_config.h - :linenos: - :lineno-match: - :start-at: /*** USER DEFINES: ***/ diff --git a/RF24/docs/sphinx/_static/Logo large.png b/RF24/docs/sphinx/_static/Logo large.png deleted file mode 100644 index 25e42159f1427f4a210c1cd0e18cdf6d84793889..0000000000000000000000000000000000000000 Binary files a/RF24/docs/sphinx/_static/Logo large.png and /dev/null differ diff --git a/RF24/docs/sphinx/_static/custom_material.css b/RF24/docs/sphinx/_static/custom_material.css deleted file mode 100644 index 7b55bb1c1737ae34d7b86de9601279577275a9b7..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/_static/custom_material.css +++ /dev/null @@ -1,87 +0,0 @@ -.md-typeset .admonition, -.md-typeset details { - font-size: 0.75rem; -} - -.md-typeset .admonition.tip>.admonition-title::before, -.md-typeset .admonition.hint>.admonition-title::before { - mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,3L1,9L12,15L21,10.09V17H23V9M5,13.18V17.18L12,21L19,17.18V13.18L12,17L5,13.18Z" /></svg>'); -} - -.md-typeset .admonition.seealso>.admonition-title::before { - mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z"/></svg>'); - background-color: hsl(301, 100%, 63%); -} - -.md-typeset .admonition.seealso { - border-left: .2rem solid hsl(301, 100%, 63%); -} - -.md-typeset .admonition.seealso>.admonition-title { - background-color: hsla(287, 100%, 63%, 0.25); - border-left-color: hsl(301, 100%, 63%); -} - -.md-typeset .admonition.important>.admonition-title::before { - mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"/></svg>'); - background-color: hsl(123, 100%, 63%); -} - -.md-typeset .admonition.important { - border-left: .2rem solid hsl(123, 100%, 63%); -} - -.md-typeset .admonition.important>.admonition-title { - background-color: hsla(123, 100%, 63%, 0.25); -} - -.md-typeset .admonition.warning>.admonition-title::before { - background-color: hsl(0, 100%, 63%); -} - -.md-typeset .admonition.warning { - border-left: .2rem solid hsl(0, 100%, 63%); -} - -.md-typeset .admonition.warning>.admonition-title { - background-color: hsla(0, 100%, 63%, 0.25); - border-left-color: hsl(0, 100%, 63%); -} - -html .md-nav--primary .md-nav__title--site .md-nav__button { - top: 0; - left: 0; - width: inherit; - height: auto; -} - -thead { - background-color: var(--md-default-fg-color--light); - color: var(--md-primary-bg-color); -} - -.md-nav__title .md-nav__button.md-logo img, .md-nav__title .md-nav__button.md-logo svg { - height: 3rem; - width: auto; -} - -.md-header__button.md-logo img, .md-header__button.md-logo svg { - width: auto; -} - -/* CSS for Remark admonitions (translated by breathe from doxygen's @remark(s) cmd */ -:root { - --md-admonition-icon--remark: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/></svg>') -} -.md-typeset .admonition.remark { - border-color: rgb(116, 66, 255); -} -.md-typeset .remark > .admonition-title { - background-color: rgba(116, 66, 255, 0.1); - border-color: rgb(116, 66, 255); -} -.md-typeset .remark > .admonition-title::before { - background-color: rgb(116, 66, 255); - -webkit-mask-image: var(--md-admonition-icon--remark); - mask-image: var(--md-admonition-icon--remark); -} diff --git a/RF24/docs/sphinx/_static/new_favicon.ico b/RF24/docs/sphinx/_static/new_favicon.ico deleted file mode 100644 index c15a1650af557d6ec815ebd7c0b5dbf5cc080676..0000000000000000000000000000000000000000 Binary files a/RF24/docs/sphinx/_static/new_favicon.ico and /dev/null differ diff --git a/RF24/docs/sphinx/classRF24.rst b/RF24/docs/sphinx/classRF24.rst deleted file mode 100644 index ef57f74c1d33d3394c46c6b485610c4add6b8cfb..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/classRF24.rst +++ /dev/null @@ -1,150 +0,0 @@ -RF24 class -~~~~~~~~~~ - -.. cpp:class:: RF24 - - .. doxygenfunction:: RF24 (uint16_t,uint16_t,uint32_t) - .. doxygenfunction:: begin (void) - .. doxygenfunction:: begin (_SPI *spiBus) - -Dynamically Instantiated Pins -============================= - -.. doxygenfunction:: RF24::RF24 (uint32_t _spi_speed=RF24_SPI_SPEED) -.. doxygenfunction:: RF24::begin (uint16_t _cepin, uint16_t _cspin) -.. doxygenfunction:: RF24::begin (_SPI *spiBus, uint16_t _cepin, uint16_t _cspin) - -Basic API -============ - -.. doxygenfunction:: RF24::startListening -.. doxygenfunction:: RF24::stopListening -.. doxygenfunction:: RF24::available (void) -.. doxygenfunction:: RF24::available (uint8_t *pipe_num) -.. doxygenfunction:: RF24::read -.. doxygenfunction:: RF24::write (const void *buf, uint8_t len) -.. doxygenfunction:: RF24::openWritingPipe (const uint8_t *address) -.. doxygenfunction:: RF24::openWritingPipe (uint64_t address) -.. doxygenfunction:: RF24::openReadingPipe (uint8_t number, const uint8_t *address) -.. doxygenfunction:: RF24::openReadingPipe (uint8_t number, uint64_t address) -.. doxygenfunction:: RF24::closeReadingPipe - -Advanced API -============ - -.. doxygenfunction:: RF24::isChipConnected -.. doxygenfunction:: RF24::isValid -.. doxygenfunction:: RF24::isPVariant -.. doxygenfunction:: RF24::whatHappened - -Debugging helpers -******************* - -.. doxygenvariable:: RF24::failureDetected -.. doxygenfunction:: RF24::printDetails -.. doxygenfunction:: RF24::printPrettyDetails -.. doxygenfunction:: RF24::getARC - -Advanced Transmission -********************* - -.. doxygenfunction:: RF24::write (const void *buf, uint8_t len, const bool multicast) -.. doxygenfunction:: RF24::writeAckPayload -.. doxygenfunction:: RF24::writeFast (const void *buf, uint8_t len) -.. doxygenfunction:: RF24::writeFast (const void *buf, uint8_t len, const bool multicast) -.. doxygenfunction:: RF24::reUseTX -.. doxygenfunction:: RF24::writeBlocking -.. doxygenfunction:: RF24::startFastWrite -.. doxygenfunction:: RF24::startWrite -.. doxygenfunction:: RF24::txStandBy() -.. doxygenfunction:: RF24::txStandBy (uint32_t timeout, bool startTx=0) - -Power Management -**************** - -.. doxygenfunction:: RF24::powerDown -.. doxygenfunction:: RF24::powerUp - -FIFO Management -*************** - -.. doxygenfunction:: RF24::rxFifoFull -.. doxygenfunction:: RF24::flush_tx -.. doxygenfunction:: RF24::flush_rx -.. doxygenfunction:: RF24::isFifo (bool about_tx) -.. doxygenfunction:: RF24::isFifo (bool about_tx, bool check_empty) - -Ambiguous Signal Detection -************************** - -.. doxygenfunction:: RF24::startConstCarrier -.. doxygenfunction:: RF24::stopConstCarrier -.. doxygenfunction:: RF24::testCarrier -.. doxygenfunction:: RF24::testRPD - -Configuration API -================== - -.. doxygenfunction:: RF24::setAddressWidth -.. doxygenfunction:: RF24::setRetries -.. doxygenfunction:: RF24::maskIRQ -.. doxygenfunction:: RF24::toggleAllPipes - -Channel (Frequency) -******************* - -.. doxygenfunction:: RF24::setChannel -.. doxygenfunction:: RF24::getChannel - -Dynamic Delays -************** -.. doxygenvariable:: RF24::txDelay -.. doxygenvariable:: RF24::csDelay - -Payload Sizes -************* - -.. doxygenfunction:: RF24::setPayloadSize -.. doxygenfunction:: RF24::getPayloadSize -.. doxygenfunction:: RF24::enableDynamicPayloads -.. doxygenfunction:: RF24::disableDynamicPayloads -.. doxygenfunction:: RF24::getDynamicPayloadSize - -Auto-Acknowledgement -******************** - -.. doxygenfunction:: RF24::setAutoAck (bool enable) -.. doxygenfunction:: RF24::setAutoAck (uint8_t pipe, bool enable) -.. doxygenfunction:: RF24::enableAckPayload -.. doxygenfunction:: RF24::disableAckPayload -.. doxygenfunction:: RF24::enableDynamicAck -.. doxygenfunction:: RF24::isAckPayloadAvailable - -Radiation Options -***************** - -.. doxygenfunction:: RF24::setPALevel -.. doxygenfunction:: RF24::getPALevel -.. doxygenfunction:: RF24::setDataRate -.. doxygenfunction:: RF24::getDataRate -.. doxygenfunction:: RF24::setRadiation - -CRC Lengths -*********** - -.. doxygenfunction:: RF24::setCRCLength -.. doxygenfunction:: RF24::getCRCLength -.. doxygenfunction:: RF24::disableCRC - -Protected API -============== - -These are the members and functions made available to derivatives that inherit from the RF24 class. - -.. doxygenfunction:: RF24::beginTransaction -.. doxygenfunction:: RF24::endTransaction -.. doxygenfunction:: RF24::read_register (uint8_t reg) -.. doxygenfunction:: RF24::read_register (uint8_t reg, uint8_t *buf, uint8_t len) -.. doxygenvariable:: RF24::ack_payloads_enabled -.. doxygenvariable:: RF24::addr_width -.. doxygenvariable:: RF24::dynamic_payloads_enabled \ No newline at end of file diff --git a/RF24/docs/sphinx/conf.py b/RF24/docs/sphinx/conf.py deleted file mode 100644 index 5b19b340fb8d84653468efb8b3695281c6b7e711..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/conf.py +++ /dev/null @@ -1,163 +0,0 @@ -"""Configuration file for the Sphinx documentation builder. - -This file only contains a selection of the most common options. For a full -list see the documentation: -https://www.sphinx-doc.org/en/master/usage/configuration.html -""" -import subprocess -import os -import json - -# pylint: disable=invalid-name - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -# -- Project information ----------------------------------------------------- - -project = "RF24 library" -copyright = "2021, nRF24 org" -author = "nRF24" - -# The full version, including alpha/beta/rc tags -release = "1.4.2" # the minimum version that supports sphinx builds and RTD hosting -with open("../../library.json", "rb") as lib_json: - # get updated info from PlatformIO JSON - release = json.load(lib_json)["version"] - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = "en" - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "breathe", - "sphinx_immaterial", - "sphinx.ext.autosectionlabel", - "sphinx_immaterial.apidoc.cpp.cppreference", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - -# code-blocks will use this as their default syntax highlighting -highlight_language="c++" -primary_domain="cpp" - -# If true, '()' will be appended to :func: etc. cross-reference text. -add_function_parentheses = True - -# -- Options for breathe (XML output from doxygen) --------------------------- - -breathe_projects = {"RF24": "xml"} -breathe_default_project = "RF24" -breathe_show_define_initializer = True -breathe_show_enumvalue_initializer = True -breathe_domain_by_extension = { "h" : "cpp" } - -# debug options -# breathe_debug_trace_directives = True -# breathe_debug_trace_doxygen_ids = True -# breathe_debug_trace_qualification = True - -READTHEDOCS = os.environ.get('READTHEDOCS', None) == 'True' - -if READTHEDOCS: - subprocess.call("cd ../..; doxygen", shell=True) - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -# html_theme = "sphinx_rtd_theme" -html_theme = "sphinx_immaterial" -html_theme_options = { - "features": [ - # "navigation.expand", - "navigation.tabs", - # "toc.integrate", - # "navigation.sections", - "navigation.instant", - # "header.autohide", - "navigation.top", - # "search.highlight", - "search.share", - ], - "palette": [ - { - "media": "(prefers-color-scheme: dark)", - "scheme": "slate", - "primary": "lime", - "accent": "light-blue", - "toggle": { - "icon": "material/lightbulb", - "name": "Switch to light mode", - }, - }, - { - "media": "(prefers-color-scheme: light)", - "scheme": "default", - "primary": "light-blue", - "accent": "green", - "toggle": { - "icon": "material/lightbulb-outline", - "name": "Switch to dark mode", - }, - }, - ], - # Set the repo location to get a badge with stats - "repo_url": "https://github.com/nRF24/RF24/", - "repo_name": "RF24", - "repo_type": "github", - # If False, expand all TOC entries - "globaltoc_collapse": False, -} - -object_description_options = [ - ("cpp:functionParam", dict(include_in_toc=False, generate_synopses=None)), - ("cpp:function", dict(include_fields_in_toc=False)), -] - -# Set link name generated in the top bar. -html_title = "RF24 C++ library" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# These paths are either relative to html_static_path -# or fully qualified paths (eg. https://...) -html_css_files = ["custom_material.css"] - -# The name of an image file (relative to this directory) to use as a favicon of -# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# -html_favicon = "_static/new_favicon.ico" - -# project logo -html_logo = "_static/Logo large.png" - -# split site index page into 2 pages: -# 1 with only alphabet-like links to partial lists, 1 with full listing -html_split_index = True diff --git a/RF24/docs/sphinx/deprecated.rst b/RF24/docs/sphinx/deprecated.rst deleted file mode 100644 index 3e1b5a0a58f59469880c69ab361d4198cd5d994e..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/deprecated.rst +++ /dev/null @@ -1,5 +0,0 @@ -Deprecated API -============== - -.. doxygenpage:: deprecated - :content-only: diff --git a/RF24/docs/sphinx/enums.rst b/RF24/docs/sphinx/enums.rst deleted file mode 100644 index 4c6090539ddae659c1a0bf7cf54cdb5bee68dfcf..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/enums.rst +++ /dev/null @@ -1,12 +0,0 @@ -Enumerations -============ - - -.. doxygengroup:: PALevel - :members: - -.. doxygengroup:: Datarate - :members: - -.. doxygengroup:: CRCLength - :members: diff --git a/RF24/docs/sphinx/examples.rst b/RF24/docs/sphinx/examples.rst deleted file mode 100644 index 3dbdead767c79fc463654444c3a0f350e15864ec..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples.rst +++ /dev/null @@ -1,58 +0,0 @@ -Examples -========== - -Arduino Examples ----------------- - -.. toctree:: - :maxdepth: 1 - - examples/Arduino/GettingStarted - examples/Arduino/AcknowledgementPayloads - examples/Arduino/ManualAcknowledgements - examples/Arduino/StreamingData - examples/Arduino/MulticeiverDemo - examples/Arduino/Scanner - examples/Arduino/InterruptConfigure - -Linux Examples ----------------- - -.. toctree:: - :maxdepth: 1 - - examples/Linux/GettingStarted - examples/Linux/AcknowledgementPayloads - examples/Linux/ManualAcknowledgements - examples/Linux/StreamingData - examples/Linux/MulticeiverDemo - examples/Linux/Scanner - examples/Linux/InterruptConfigure - -PicoSDK Examples ----------------- - -.. toctree:: - :maxdepth: 1 - - examples/PicoSDK/default_pins - examples/PicoSDK/GettingStarted - examples/PicoSDK/AcknowledgementPayloads - examples/PicoSDK/ManualAcknowledgements - examples/PicoSDK/StreamingData - examples/PicoSDK/MulticeiverDemo - examples/PicoSDK/Scanner - examples/PicoSDK/InterruptConfigure - -Python Examples ----------------- - -.. toctree:: - :maxdepth: 1 - - examples/Python/GettingStarted - examples/Python/AcknowledgementPayloads - examples/Python/ManualAcknowledgements - examples/Python/StreamingData - examples/Python/MulticeiverDemo - examples/Python/InterruptConfigure diff --git a/RF24/docs/sphinx/examples/Arduino/AcknowledgementPayloads.rst b/RF24/docs/sphinx/examples/Arduino/AcknowledgementPayloads.rst deleted file mode 100644 index 70deeb2fe7def3ffcff54fdb5ef006b793016b97..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Arduino/AcknowledgementPayloads.rst +++ /dev/null @@ -1,7 +0,0 @@ -AcknowledgementPayloads.ino -=========================== - -.. literalinclude:: ../../../../examples/AcknowledgementPayloads/AcknowledgementPayloads.ino - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Arduino/GettingStarted.rst b/RF24/docs/sphinx/examples/Arduino/GettingStarted.rst deleted file mode 100644 index f873a6750efa49a68eccdd52dc10a5a2e0357d91..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Arduino/GettingStarted.rst +++ /dev/null @@ -1,7 +0,0 @@ -GettingStarted.ino -================== - -.. literalinclude:: ../../../../examples/GettingStarted/GettingStarted.ino - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Arduino/InterruptConfigure.rst b/RF24/docs/sphinx/examples/Arduino/InterruptConfigure.rst deleted file mode 100644 index fe59f38d6e9f48fde024047acf3f577a8c4f8f62..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Arduino/InterruptConfigure.rst +++ /dev/null @@ -1,7 +0,0 @@ -InterruptConfigure.ino -====================== - -.. literalinclude:: ../../../../examples/InterruptConfigure/InterruptConfigure.ino - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Arduino/ManualAcknowledgements.rst b/RF24/docs/sphinx/examples/Arduino/ManualAcknowledgements.rst deleted file mode 100644 index ad6b904c2d4f093b221fa32b13296b2c0beca1c7..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Arduino/ManualAcknowledgements.rst +++ /dev/null @@ -1,7 +0,0 @@ -ManualAcknowledgements.ino -========================== - -.. literalinclude:: ../../../../examples/ManualAcknowledgements/ManualAcknowledgements.ino - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Arduino/MulticeiverDemo.rst b/RF24/docs/sphinx/examples/Arduino/MulticeiverDemo.rst deleted file mode 100644 index 1e30f7b00fde8211ad0dfbdc72a7b4af176e5cc4..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Arduino/MulticeiverDemo.rst +++ /dev/null @@ -1,7 +0,0 @@ -MulticeiverDemo.ino -==================== - -.. literalinclude:: ../../../../examples/MulticeiverDemo/MulticeiverDemo.ino - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Arduino/Scanner.rst b/RF24/docs/sphinx/examples/Arduino/Scanner.rst deleted file mode 100644 index e9e64bce79e06ce7961ce6245cf55101bc70c266..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Arduino/Scanner.rst +++ /dev/null @@ -1,7 +0,0 @@ -Scanner.ino -================== - -.. literalinclude:: ../../../../examples/scanner/scanner.ino - :lines: 10- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Arduino/StreamingData.rst b/RF24/docs/sphinx/examples/Arduino/StreamingData.rst deleted file mode 100644 index b13add5da71b78c5edc77ad2f62f6ef49e0b3b9e..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Arduino/StreamingData.rst +++ /dev/null @@ -1,7 +0,0 @@ -StreamingData.ino -================== - -.. literalinclude:: ../../../../examples/StreamingData/StreamingData.ino - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Linux/AcknowledgementPayloads.rst b/RF24/docs/sphinx/examples/Linux/AcknowledgementPayloads.rst deleted file mode 100644 index 00473fb66f17780733dc46d5d9d7011e4499198f..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Linux/AcknowledgementPayloads.rst +++ /dev/null @@ -1,7 +0,0 @@ -AcknowledgementPayloads.cpp -=========================== - -.. literalinclude:: ../../../../examples_linux/acknowledgementPayloads.cpp - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Linux/GettingStarted.rst b/RF24/docs/sphinx/examples/Linux/GettingStarted.rst deleted file mode 100644 index d4d5c24db04e1f5fa78f28d21c7384ca7185d0a6..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Linux/GettingStarted.rst +++ /dev/null @@ -1,7 +0,0 @@ -GettingStarted.cpp -================== - -.. literalinclude:: ../../../../examples_linux/gettingstarted.cpp - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Linux/InterruptConfigure.rst b/RF24/docs/sphinx/examples/Linux/InterruptConfigure.rst deleted file mode 100644 index 7591bb0f915f45493d3d5b78c7a720ddc1bc6cb8..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Linux/InterruptConfigure.rst +++ /dev/null @@ -1,7 +0,0 @@ -InterruptConfigure.cpp -====================== - -.. literalinclude:: ../../../../examples_linux/interruptConfigure.cpp - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Linux/ManualAcknowledgements.rst b/RF24/docs/sphinx/examples/Linux/ManualAcknowledgements.rst deleted file mode 100644 index a2a8b9a04bdfb45ccd59273f4a4bdf0bbaaf64af..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Linux/ManualAcknowledgements.rst +++ /dev/null @@ -1,7 +0,0 @@ -ManualAcknowledgements.cpp -========================== - -.. literalinclude:: ../../../../examples_linux/manualAcknowledgements.cpp - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Linux/MulticeiverDemo.rst b/RF24/docs/sphinx/examples/Linux/MulticeiverDemo.rst deleted file mode 100644 index bb4e9e816f4b4bce5cd4d01e2e95c0713ea8d0bb..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Linux/MulticeiverDemo.rst +++ /dev/null @@ -1,7 +0,0 @@ -MulticeiverDemo.cpp -==================== - -.. literalinclude:: ../../../../examples_linux/multiceiverDemo.cpp - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Linux/Scanner.rst b/RF24/docs/sphinx/examples/Linux/Scanner.rst deleted file mode 100644 index 4cd1b6fd8292935f687f101760cbd95054192f62..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Linux/Scanner.rst +++ /dev/null @@ -1,7 +0,0 @@ -Scanner.cpp -================== - -.. literalinclude:: ../../../../examples_linux/scanner.cpp - :lines: 15- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Linux/StreamingData.rst b/RF24/docs/sphinx/examples/Linux/StreamingData.rst deleted file mode 100644 index 53121fae553edbcc32abfb40662a6afd2af66d83..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Linux/StreamingData.rst +++ /dev/null @@ -1,7 +0,0 @@ -StreamingData.cpp -================== - -.. literalinclude:: ../../../../examples_linux/streamingData.cpp - :lines: 7- - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/PicoSDK/AcknowledgementPayloads.rst b/RF24/docs/sphinx/examples/PicoSDK/AcknowledgementPayloads.rst deleted file mode 100644 index d7163893a109c7cb2875f1b602d752bddfbee85e..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/PicoSDK/AcknowledgementPayloads.rst +++ /dev/null @@ -1,9 +0,0 @@ -acknowledgementPayloads -=========================== - -.. seealso:: - `defaultPins.h <default_pins.html>`_ - -.. literalinclude:: ../../../../examples_pico/acknowledgementPayloads.cpp - :caption: examples_pico/acknowledgementPayloads.cpp - :linenos: diff --git a/RF24/docs/sphinx/examples/PicoSDK/GettingStarted.rst b/RF24/docs/sphinx/examples/PicoSDK/GettingStarted.rst deleted file mode 100644 index 0477328cacdd05b000a6e2b508ac7e132efe0f94..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/PicoSDK/GettingStarted.rst +++ /dev/null @@ -1,9 +0,0 @@ -gettingStarted -================== - -.. seealso:: - `defaultPins.h <default_pins.html>`_ - -.. literalinclude:: ../../../../examples_pico/gettingStarted.cpp - :caption: examples_pico/gettingStarted.cpp - :linenos: diff --git a/RF24/docs/sphinx/examples/PicoSDK/InterruptConfigure.rst b/RF24/docs/sphinx/examples/PicoSDK/InterruptConfigure.rst deleted file mode 100644 index 4b8533ed4661a55a0d4ee3d6c2d876803e244f94..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/PicoSDK/InterruptConfigure.rst +++ /dev/null @@ -1,9 +0,0 @@ -interruptConfigure -====================== - -.. seealso:: - `defaultPins.h <default_pins.html>`_ - -.. literalinclude:: ../../../../examples_pico/interruptConfigure.cpp - :caption: examples_pico/interruptConfigure.cpp - :linenos: diff --git a/RF24/docs/sphinx/examples/PicoSDK/ManualAcknowledgements.rst b/RF24/docs/sphinx/examples/PicoSDK/ManualAcknowledgements.rst deleted file mode 100644 index 66f8aa4713e9c4bd1be54f14088d75483d04e866..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/PicoSDK/ManualAcknowledgements.rst +++ /dev/null @@ -1,9 +0,0 @@ -manualAcknowledgements -========================== - -.. seealso:: - `defaultPins.h <default_pins.html>`_ - -.. literalinclude:: ../../../../examples_pico/manualAcknowledgements.cpp - :caption: examples_pico/manualAcknowledgements.cpp - :linenos: diff --git a/RF24/docs/sphinx/examples/PicoSDK/MulticeiverDemo.rst b/RF24/docs/sphinx/examples/PicoSDK/MulticeiverDemo.rst deleted file mode 100644 index 612e4d2fb29381257229542fb20e020e7a99b8d1..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/PicoSDK/MulticeiverDemo.rst +++ /dev/null @@ -1,9 +0,0 @@ -multiceiverDemo -==================== - -.. seealso:: - `defaultPins.h <default_pins.html>`_ - -.. literalinclude:: ../../../../examples_pico/multiceiverDemo.cpp - :caption: examples_pico/multiceiverDemo.cpp - :linenos: diff --git a/RF24/docs/sphinx/examples/PicoSDK/Scanner.rst b/RF24/docs/sphinx/examples/PicoSDK/Scanner.rst deleted file mode 100644 index 0f29e1496634df6c95ed793d6567a41d2e67cf7b..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/PicoSDK/Scanner.rst +++ /dev/null @@ -1,9 +0,0 @@ -scanner -================== - -.. seealso:: - `defaultPins.h <default_pins.html>`_ - -.. literalinclude:: ../../../../examples_pico/scanner.cpp - :caption: examples_pico/scanner.cpp - :linenos: diff --git a/RF24/docs/sphinx/examples/PicoSDK/StreamingData.rst b/RF24/docs/sphinx/examples/PicoSDK/StreamingData.rst deleted file mode 100644 index d6d2e878046afe03ed71f5f1f6cceb2b0f098657..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/PicoSDK/StreamingData.rst +++ /dev/null @@ -1,9 +0,0 @@ -streamingData -================== - -.. seealso:: - `defaultPins.h <default_pins.html>`_ - -.. literalinclude:: ../../../../examples_pico/streamingData.cpp - :caption: examples_pico/streamingData.cpp - :linenos: diff --git a/RF24/docs/sphinx/examples/PicoSDK/default_pins.rst b/RF24/docs/sphinx/examples/PicoSDK/default_pins.rst deleted file mode 100644 index 54087260a3a5ec2b0487409e78d2fd5abdff0984..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/PicoSDK/default_pins.rst +++ /dev/null @@ -1,5 +0,0 @@ -PicoSDK Examples' Default Pins -============================== - -.. literalinclude:: ../../../../examples_pico/defaultPins.h - :linenos: diff --git a/RF24/docs/sphinx/examples/Python/AcknowledgementPayloads.rst b/RF24/docs/sphinx/examples/Python/AcknowledgementPayloads.rst deleted file mode 100644 index c7d719d96f995b3a2b621705f020671888e443d8..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Python/AcknowledgementPayloads.rst +++ /dev/null @@ -1,8 +0,0 @@ -acknowledgement_payloads.py -=========================== - -.. literalinclude:: ../../../../examples_linux/acknowledgement_payloads.py - :language: python - :caption: examples_linux/acknowledgement_payloads.py - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Python/GettingStarted.rst b/RF24/docs/sphinx/examples/Python/GettingStarted.rst deleted file mode 100644 index 70b242fd04f8adb0559d85814e16342b7440b755..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Python/GettingStarted.rst +++ /dev/null @@ -1,8 +0,0 @@ -getting_started.py -================== - -.. literalinclude:: ../../../../examples_linux/getting_started.py - :language: python - :caption: examples_linux/getting_started.py - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Python/InterruptConfigure.rst b/RF24/docs/sphinx/examples/Python/InterruptConfigure.rst deleted file mode 100644 index 8c89ad3d28ee2fbfc1b04a97a4c44632eb71654b..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Python/InterruptConfigure.rst +++ /dev/null @@ -1,8 +0,0 @@ -interrupt_configure.py -====================== - -.. literalinclude:: ../../../../examples_linux/interrupt_configure.py - :language: python - :caption: examples_linux/interrupt_configure.py - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Python/ManualAcknowledgements.rst b/RF24/docs/sphinx/examples/Python/ManualAcknowledgements.rst deleted file mode 100644 index d94e852d4f42d036bdab7d0c4768a765e619eac5..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Python/ManualAcknowledgements.rst +++ /dev/null @@ -1,8 +0,0 @@ -manual_acknowledgements.py -========================== - -.. literalinclude:: ../../../../examples_linux/manual_acknowledgements.py - :language: python - :caption: examples_linux/manual_acknowledgements.py - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Python/MulticeiverDemo.rst b/RF24/docs/sphinx/examples/Python/MulticeiverDemo.rst deleted file mode 100644 index 96ef84fd3871a5a6488bcc4c47afebe3c8408be8..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Python/MulticeiverDemo.rst +++ /dev/null @@ -1,8 +0,0 @@ -multiceiver_demo.py -==================== - -.. literalinclude:: ../../../../examples_linux/multiceiver_demo.py - :language: python - :caption: examples_linux/multiceiver_demo.py - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/examples/Python/StreamingData.rst b/RF24/docs/sphinx/examples/Python/StreamingData.rst deleted file mode 100644 index f2f1f9fe8fcebb5756a76e693693e8d299923ee1..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/examples/Python/StreamingData.rst +++ /dev/null @@ -1,8 +0,0 @@ -streaming_data.py -================== - -.. literalinclude:: ../../../../examples_linux/streaming_data.py - :language: python - :caption: examples_linux/streaming_data.py - :linenos: - :lineno-match: diff --git a/RF24/docs/sphinx/index.rst b/RF24/docs/sphinx/index.rst deleted file mode 100644 index 52e79137238e947852e51f36025ebbd5f25d3574..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/index.rst +++ /dev/null @@ -1,44 +0,0 @@ - -:hero: Optimized high speed nRF24L01+ driver class documentation - -Introduction -============= - -.. doxygenpage:: index - :content-only: - -Site Index ------------ - -:ref:`Site index<genindex>` - -.. toctree:: - :maxdepth: 2 - :caption: API Reference - :hidden: - - classRF24 - enums - nRF24L01_8h - RF24_config_8h - deprecated - - -.. toctree:: - :maxdepth: 1 - :hidden: - - pages - - -.. toctree:: - :maxdepth: 1 - :hidden: - - modules - -.. toctree:: - :maxdepth: 2 - :hidden: - - examples diff --git a/RF24/docs/sphinx/make.bat b/RF24/docs/sphinx/make.bat deleted file mode 100644 index bba10073f8dec08ce53d43cd3974f692f001b999..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=../sphinx -set BUILDDIR=../_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/RF24/docs/sphinx/md_common_issues.rst b/RF24/docs/sphinx/md_common_issues.rst deleted file mode 100644 index 8a15d373c8ea749099576609c2140a4bebd686ad..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_common_issues.rst +++ /dev/null @@ -1,5 +0,0 @@ -Common Issues -============= - -.. doxygenpage:: md_COMMON_ISSUES - :content-only: diff --git a/RF24/docs/sphinx/md_contributing.rst b/RF24/docs/sphinx/md_contributing.rst deleted file mode 100644 index 8a9b00db5b8a8863a0efb6800a6efd880a192582..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_contributing.rst +++ /dev/null @@ -1,5 +0,0 @@ -Contributing -============= - -.. doxygenpage:: md_CONTRIBUTING - :content-only: diff --git a/RF24/docs/sphinx/md_docs_arduino.rst b/RF24/docs/sphinx/md_docs_arduino.rst deleted file mode 100644 index 48f9376f82386c70571a44f990697a480886b5b6..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_arduino.rst +++ /dev/null @@ -1,5 +0,0 @@ -Arduino -============= - -.. doxygenpage:: md_docs_arduino - :content-only: diff --git a/RF24/docs/sphinx/md_docs_attiny.rst b/RF24/docs/sphinx/md_docs_attiny.rst deleted file mode 100644 index 1c07080f1d195a31d5aa6f6a563c31a0092609bf..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_attiny.rst +++ /dev/null @@ -1,6 +0,0 @@ -ATTiny -============= -.. highlight:: none - -.. doxygenpage:: md_docs_attiny - :content-only: diff --git a/RF24/docs/sphinx/md_docs_atxmega.rst b/RF24/docs/sphinx/md_docs_atxmega.rst deleted file mode 100644 index 5a9ff21d94a7065ed55d67705830660c57093b9d..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_atxmega.rst +++ /dev/null @@ -1,5 +0,0 @@ -ATXMEGA -============= - -.. doxygenpage:: md_docs_atxmega - :content-only: diff --git a/RF24/docs/sphinx/md_docs_cross_compile.rst b/RF24/docs/sphinx/md_docs_cross_compile.rst deleted file mode 100644 index 8ffccf90a4238433c88faf753275f7404bcde3b5..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_cross_compile.rst +++ /dev/null @@ -1,7 +0,0 @@ -Linux cross-compilation -======================= - -.. highlight:: none - -.. doxygenpage:: md_docs_cross_compile - :content-only: diff --git a/RF24/docs/sphinx/md_docs_linux_install.rst b/RF24/docs/sphinx/md_docs_linux_install.rst deleted file mode 100644 index 2f3d04aa501dfe33268bc2d3c27e72fce6721b82..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_linux_install.rst +++ /dev/null @@ -1,5 +0,0 @@ -Linux Installation -================== - -.. doxygenpage:: md_docs_linux_install - :content-only: diff --git a/RF24/docs/sphinx/md_docs_mraa.rst b/RF24/docs/sphinx/md_docs_mraa.rst deleted file mode 100644 index 361d98c3e9fc8e8ff1b61508feca97261365153d..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_mraa.rst +++ /dev/null @@ -1,5 +0,0 @@ -MRAA -============= - -.. doxygenpage:: md_docs_mraa - :content-only: diff --git a/RF24/docs/sphinx/md_docs_pico_sdk.rst b/RF24/docs/sphinx/md_docs_pico_sdk.rst deleted file mode 100644 index 9f9dd0078cb425e6e3b083e70dad749794d1e8eb..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_pico_sdk.rst +++ /dev/null @@ -1,5 +0,0 @@ -Raspberry Pi Pico SDK -===================== - -.. doxygenpage:: md_docs_pico_sdk - :content-only: diff --git a/RF24/docs/sphinx/md_docs_portability.rst b/RF24/docs/sphinx/md_docs_portability.rst deleted file mode 100644 index 7801a9cc2876680b4e06c75603912d2b858c06f5..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_portability.rst +++ /dev/null @@ -1,5 +0,0 @@ -RF24 portability -================ - -.. doxygenpage:: md_docs_portability - :content-only: diff --git a/RF24/docs/sphinx/md_docs_python_wrapper.rst b/RF24/docs/sphinx/md_docs_python_wrapper.rst deleted file mode 100644 index d0120e4bc140f6aeedc437bc25bb63695cf936db..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_python_wrapper.rst +++ /dev/null @@ -1,5 +0,0 @@ -Python wrapper -============== - -.. doxygenpage:: md_docs_python_wrapper - :content-only: diff --git a/RF24/docs/sphinx/md_docs_rpi_general.rst b/RF24/docs/sphinx/md_docs_rpi_general.rst deleted file mode 100644 index a69ff21e6d2f3df1a91e7d235c8853d81dd1b62a..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_rpi_general.rst +++ /dev/null @@ -1,5 +0,0 @@ -Linux General/Raspberry Pi -========================== - -.. doxygenpage:: md_docs_rpi_general - :content-only: diff --git a/RF24/docs/sphinx/md_docs_using_cmake.rst b/RF24/docs/sphinx/md_docs_using_cmake.rst deleted file mode 100644 index 8ef13be893ca86dc66276f08dbaa9a11fa73206c..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/md_docs_using_cmake.rst +++ /dev/null @@ -1,7 +0,0 @@ -Using CMake -============= - -.. highlight:: none - -.. doxygenpage:: md_docs_using_cmake - :content-only: diff --git a/RF24/docs/sphinx/modules.rst b/RF24/docs/sphinx/modules.rst deleted file mode 100644 index 3fd4cccc0fa892eae093962dfe4c18f18f1fa6ca..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/modules.rst +++ /dev/null @@ -1,11 +0,0 @@ -Modules -========= - -.. toctree:: - :maxdepth: 2 - - modules/Porting_Timing - modules/Porting_GPIO - modules/Porting_Includes - modules/Porting_General - modules/Porting_SPI diff --git a/RF24/docs/sphinx/modules/Porting_GPIO.rst b/RF24/docs/sphinx/modules/Porting_GPIO.rst deleted file mode 100644 index 99ad4a37bec859f7111731935e080f66e43caed8..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/modules/Porting_GPIO.rst +++ /dev/null @@ -1,15 +0,0 @@ -Porting: GPIO -============= - -.. doxygengroup:: Porting_GPIO - :members: - :undoc-members: - :protected-members: - :private-members: - :content-only: - -gpio.h ------------ - -.. literalinclude:: ../../../utility/Template/gpio.h - :caption: utility/Template/gpio.h diff --git a/RF24/docs/sphinx/modules/Porting_General.rst b/RF24/docs/sphinx/modules/Porting_General.rst deleted file mode 100644 index 2e9af1fde94cb03a45ffea42a0d5cc7c0148eab3..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/modules/Porting_General.rst +++ /dev/null @@ -1,15 +0,0 @@ -Porting: General -================ - -.. doxygengroup:: Porting_General - :members: - :undoc-members: - :protected-members: - :private-members: - :content-only: - -RF24_arch_config.h ------------------- - -.. literalinclude:: ../../../utility/Template/RF24_arch_config.h - :caption: utility/Template/RF24_arch_config.h diff --git a/RF24/docs/sphinx/modules/Porting_Includes.rst b/RF24/docs/sphinx/modules/Porting_Includes.rst deleted file mode 100644 index a2feea4e72590bcbcaf04bfcbc03a29976cd0037..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/modules/Porting_Includes.rst +++ /dev/null @@ -1,15 +0,0 @@ -Porting: Includes -================== - -.. doxygengroup:: Porting_Includes - :members: - :undoc-members: - :protected-members: - :private-members: - :content-only: - -includes.h ------------ - -.. literalinclude:: ../../../utility/Template/includes.h - :caption: utility/Template/includes.h diff --git a/RF24/docs/sphinx/modules/Porting_SPI.rst b/RF24/docs/sphinx/modules/Porting_SPI.rst deleted file mode 100644 index d07887840ba38ecfab2908b9d7c526f086731147..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/modules/Porting_SPI.rst +++ /dev/null @@ -1,15 +0,0 @@ -Porting: SPI -============ - -.. doxygengroup:: Porting_SPI - :members: - :undoc-members: - :protected-members: - :private-members: - :content-only: - -spi.h ------------ - -.. literalinclude:: ../../../utility/Template/spi.h - :caption: utility/Template/spi.h diff --git a/RF24/docs/sphinx/modules/Porting_Timing.rst b/RF24/docs/sphinx/modules/Porting_Timing.rst deleted file mode 100644 index feca6c206d52fc4cac3b167edcf5287870f4cde1..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/modules/Porting_Timing.rst +++ /dev/null @@ -1,15 +0,0 @@ -Porting: Timing -=============== - -.. doxygengroup:: Porting_Timing - :members: - :undoc-members: - :protected-members: - :private-members: - :content-only: - -compatibility.h ---------------- - -.. literalinclude:: ../../../utility/Template/compatibility.h - :caption: utility/Template/compatibility.h diff --git a/RF24/docs/sphinx/nRF24L01_8h.rst b/RF24/docs/sphinx/nRF24L01_8h.rst deleted file mode 100644 index 3ea6913646ec0f3b654fa31c3bdaff8d83cfc9db..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/nRF24L01_8h.rst +++ /dev/null @@ -1,7 +0,0 @@ -nRF24L01.h -========== - -.. literalinclude:: ../../nRF24L01.h - :linenos: - :lineno-match: - :start-at: /* Memory Map */ diff --git a/RF24/docs/sphinx/pages.rst b/RF24/docs/sphinx/pages.rst deleted file mode 100644 index a14c72a357279863fcf2983892b61404b6ceac8d..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/pages.rst +++ /dev/null @@ -1,19 +0,0 @@ -Related Pages -============= - -.. toctree:: - :maxdepth: 1 - - md_common_issues - md_contributing - md_docs_arduino - md_docs_attiny - md_docs_atxmega - md_docs_cross_compile - md_docs_linux_install - md_docs_mraa - md_docs_pico_sdk - md_docs_portability - md_docs_python_wrapper - md_docs_rpi_general - md_docs_using_cmake diff --git a/RF24/docs/sphinx/requirements.txt b/RF24/docs/sphinx/requirements.txt deleted file mode 100644 index 1707fa2f1aef918a1a79c5cb19a42fbf510f0fdc..0000000000000000000000000000000000000000 --- a/RF24/docs/sphinx/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -breathe -sphinx-immaterial diff --git a/RF24/docs/using_cmake.md b/RF24/docs/using_cmake.md deleted file mode 100644 index ce7af1c4ce84ad05edf041b47d3b7292c12ebd91..0000000000000000000000000000000000000000 --- a/RF24/docs/using_cmake.md +++ /dev/null @@ -1,247 +0,0 @@ -# Using CMake - -<!-- markdownlint-disable MD031 --> -A more modern approach instead of using hand-crafted _Makefiles_ & _configure_ scripts -to build & install software. Please note that these instructions are not needed if you -have already installed the library using [these older instructions](md_docs_linux_install.html) - -## Installing the library - -You can install the library in a few different ways. - -- Building and installing the library from source code is preferable since it will include all the latest changes. -- Installing the library (via a package manager) from a pre-built package is mostly for cross-compiling purposes, but it can be useful for environments that don't have all the build-time dependencies (namely CMake). - -@warning If you have previously installed the library from source code using the -[the older instructions](md_docs_linux_install.html), then you will need to -uninstall it manually to avoid runtime conflicts. -```shell -sudo rm /usr/local/lib/librf24.* -sudo rm /usr/local/lib/librf24-bcm.so -sudo rm -r /usr/local/include/RF24 -``` - -The _librf24-bcm.so_ file may not exist if you used CMake to install the library. - -@note Since wiringPi is no longer maintained or distributed (as of RPi OS 11 bullseye), -pigpio is now required for using the radio's IRQ pin. This applies to RPi, SPIDEV, and pigpio drivers. The MRAA driver may provide its own IRQ implementation. Remember that the RPi OS lite variant does not ship with pigpio installed. - -### Automatic Installation - -There is a newer automatic install script that makes use of the CMake approach. - -1. Download the install.sh file from [https://github.com/nRF24/.github/blob/main/installer/install.sh](https://github.com/nRF24/.github/blob/main/installer/install.sh) - ```shell - wget https://raw.githubusercontent.com/nRF24/.github/main/installer/install.sh - ``` -2. Make it executable - ```shell - chmod +x install.sh - ``` -3. Run it and choose your options - ```shell - ./install.sh - ``` - The script will detect needed dependencies and install what it needs according to the user input. - - It will also ask to install a python package named [pyRF24](https://github.com/nRF24/pyRF24). - This is not the same as the traditionally provided python wrappers as the pyRF24 package can be - used independent of the C++ installed libraries. For more information on this newer python - package, please check out [the pyRF24 documentation](https://nrf24.github.io/pyRF24/). - Note, the pyRF24 API is more pythonic instead of a direct port of the C++ API (eg. snake casing - instead of camel casing). -4. Try an example from one of the libraries - ```shell - cd ~/rf24libs/RF24/examples_linux - ``` - - Edit the gettingstarted example, to set your pin configuration - ```shell - nano gettingstarted.cpp - ``` - - Build the examples. Remember to set the `RF24_DRIVER` option according to the one that was - selected during the scripted install. - ```shell - mkdir build && cd build - cmake .. -D RF24_DRIVER=SPIDEV - make - ``` - - Run the example - ```shell - sudo ./gettingstarted - ``` - -### Building from source code - -1. Install prerequisites if there are any (pigpio, wiringPi, MRAA, LittleWire libraries, setup SPI device etc) - - CMake may need to be installed - ```shell - sudo apt-get install cmake - ``` - @note See the [MRAA documentation](http://iotdk.intel.com/docs/master/mraa/index.html) for more information on installing MRAA -2. Make a directory to contain the RF24 library and possibly other RF24\* libraries and enter it - ```shell - mkdir ~/rf24libs - cd ~/rf24libs - ``` -3. Clone the [RF24 repo](https://github.com/nRF24/RF24) and navigate to it - ```shell - git clone https://github.com/nRF24/RF24.git RF24 - cd RF24 - ``` -4. Create a build directory inside the RF24 directory and navigate to it. - ```shell - mkdir build - cd build - ``` -5. Configure build environment - - @note When using these instructions to install RF24Mesh, RF24Network, or RF24Gateway, - the following `RF24_DRIVER` option is only needed for the RF24 library and - examples as well as the examples for RF24Network, RF24Mesh, and RF24Gateway. The `RF24_DRIVER` - option is not needed when installing the libraries for RF24Network, RF24Mesh, and RF24Gateway. - - Instead of specifying the `RF24_DRIVER` option in the CLI, it is recommended to use a environment - variable named `RF24_DRIVER`. - - ```shell - export RF24_DRIVER=SPIDEV - ``` - - These instructions assume you have not set an environment variable. - - ```shell - cmake .. -D RF24_DRIVER=SPIDEV - ``` - Instead of using `SPIDEV` driver (recommended), you can also specify the `RPi`, `wiringPi`, - `MRAA`, or `LittleWire` as alternative drivers. - - If the `RF24_DRIVER` option is not specified (and it is not set as an environment variable), then - it will be automatically configured based on the detected CPU or installed libraries (which - defaults to `SPIDEV` when auto-detection fails). -6. Build and install the library - ```shell - make - sudo make install - ``` -7. Build the examples - - Navigate to the _examples_linux_ directory - ```shell - cd ../examples_linux - ``` - Make sure the pins used in the examples match the pins you used to connect the radio module - ```shell - nano gettingstarted.cpp - ``` - and edit the pin numbers as directed in the [linux/RPi general documation](md_docs_rpi_general.html). - Create a build directory in the examples_linux directory and navigate to it. - ```shell - mkdir build - cd build - ``` - Now you are ready to build the examples. - ```shell - cmake .. - make - ``` - If using the `MRAA` or `wiringPi` drivers, then you may need to specify the `RF24_DRIVER` - option again. - ```shell - cmake .. -D RF24_DRIVER=wiringPi - make - ``` - - Remember that the `RF24_DRIVER` option is needed for the RF24Network, RF24Mesh, and RF24Gateway - examples if you specified that option (via CLI or environment variable) when installing the - RF24 library and examples. -8. Run an example file - ```shell - sudo ./gettingstarted - ``` - -### Using a package manager - -The RF24 library now (as of v1.4.1) has pre-built packages (.deb or .rpm files) that -can be installed on a Raspberry Pi. These packages can be found on the library's -[GitHub release page](https://GitHub.com/nRF24/RF24/releases) - -1. Download the appropriate package for your machine - - Go to the library's [GitHub release page](https://GitHub.com/nRF24/RF24/releases), and look for - the latest release's assets. - - For all Raspberry Pi variants using the Raspberry Pi OS (aka Raspbian), you need the file marked - for _armhf_ architecture. - - For Raspberry Pi variants using a 64-bit OS (like Ubuntu), you need the file marked for - _arm64_ architecture. - - Notice that the filenames will include the name of the utility driver that the package was built with. - This does not mean that the LittleWire, MRAA, or wiringPi libraries are included in the package (you will still - need to install those yourself beforehand). -2. Install the downloaded pkg - - If you downloaded the file directly from your target machine using the desktop environment, then - you only need to double-click the package (deb or rpm) file, and the OS should do the rest. - - If you downloaded the file remotely and want to copy it over ssh, then use the `scp` command in a terminal. - ```shell - scp pkg_filename.deb pi@host_name:~/Downloads - ``` - @note You do not need to do this from within an ssh session. Also, you can use the target machine's IP - address instead of its host name. - - The `scp` command will ask you for a password belonging to the user's name on the remote machine (we used - `pi` in the above example). - - Now you can open up a ssh session and install the copied package from the terminal. - ```shell - ssh pi@host_name - cd Downloads - dpkg -i pkg_filename.deb - ``` - -## Cross-compiling the library - -The RF24 library comes with some pre-made toolchain files (located in the -_RF24/cmake/toolchains_ directory) to use in CMake. To use these toolchain files, -additional command line options are needed when configuring CMake to build the library -(step 5 in the above instructions to build from source). - -```shell -cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/armhf.cmake -make -``` - -If you plan on using the cross-compiled library with your personal cross-compiled -project, then it is advised to specify the path that your project will look in when -linking to the RF24 library: - -```shell -cmake .. -D CMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/armhf.cmake -make -sudo make install -``` - -Remember to also specify the `RF24_DRIVER` option (via CLI or environment variable) if -not using the auto-configuration feature (see step 5 in the above instructions to build -from source). - -### Installing the library remotely - -To install remotely, you can create an installable package file using CMake's built-in -program called CPack. - -```shell -cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/armhf.cmake -make -cpack -``` - -This will create a deb file and a rpm file in a new sub-directory called "pkgs" within -the build directory. You can use either of these packages to install the library to -your target machine (see the above instructions about using a package manager). diff --git a/RF24/doxygen-custom.css b/RF24/doxygen-custom.css deleted file mode 100644 index 236f3e3b9b5d9494e9aff6861f18efd1fb88d9c1..0000000000000000000000000000000000000000 --- a/RF24/doxygen-custom.css +++ /dev/null @@ -1,815 +0,0 @@ -/* The standard CSS for doxygen */ - -body, table, div, p, dl { - font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; - font-size: 12px; -} - -/* @group Heading Levels */ - -h1 { - font-size: 150%; -} - -.title { - font-size: 150%; - font-weight: bold; - margin: 10px 2px; -} - -h2 { - font-size: 120%; -} - -h3 { - font-size: 100%; -} - -dt { - font-weight: bold; -} - -div.multicol { - -moz-column-gap: 1em; - -webkit-column-gap: 1em; - -moz-column-count: 3; - -webkit-column-count: 3; -} - -p.startli, p.startdd, p.starttd { - margin-top: 2px; -} - -p.endli { - margin-bottom: 0px; -} - -p.enddd { - margin-bottom: 4px; -} - -p.endtd { - margin-bottom: 2px; -} - -/* @end */ - -caption { - font-weight: bold; -} - -span.legend { - font-size: 70%; - text-align: center; -} - -h3.version { - font-size: 90%; - text-align: center; -} - -div.qindex, div.navtab { - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; - margin: 2px; - padding: 2px; -} - -div.qindex, div.navpath { - width: 100%; - line-height: 110%; -} - -div.navtab { - margin-right: 15px; -} - -/* @group Link Styling */ - -a { - color: #3D578C; - font-weight: normal; - text-decoration: none; -} - -.contents a:visited { - color: #4665A2; -} - -a:hover { - text-decoration: underline; -} - -a.qindex { - font-weight: bold; -} - -a.qindexHL { - font-weight: bold; - background-color: #9CAFD4; - color: #ffffff; - border: 1px double #869DCA; -} - -.contents a.qindexHL:visited { - color: #ffffff; -} - -a.el { - font-weight: bold; -} - -a.elRef { -} - -a.code { - color: #4665A2; -} - -a.codeRef { - color: #4665A2; -} - -/* @end */ - -dl.el { - margin-left: -1cm; -} - -.fragment { - font-family: monospace, fixed; - font-size: 105%; -} - -pre.fragment { - border: 1px solid #C4CFE5; - background-color: #FBFCFD; - padding: 4px 6px; - margin: 4px 8px 4px 2px; - overflow: auto; - word-wrap: break-word; - font-size: 9pt; - line-height: 125%; -} - -div.ah { - background-color: black; - font-weight: bold; - color: #ffffff; - margin-bottom: 3px; - margin-top: 3px; - padding: 0.2em; - border: solid thin #333; - border-radius: 0.5em; - -webkit-border-radius: .5em; - -moz-border-radius: .5em; - box-shadow: 2px 2px 3px #999; - -webkit-box-shadow: 2px 2px 3px #999; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; - background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000), color-stop(0.3, #444)); - background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); -} - -div.groupHeader { - margin-left: 16px; - margin-top: 12px; - font-weight: bold; -} - -div.groupText { - margin-left: 16px; - font-style: italic; -} - -body { - background: white; - color: black; - margin: 0; -} - -div.contents { - margin-top: 10px; - margin-left: 10px; - margin-right: 5px; -} - -td.indexkey { - background-color: #EBEFF6; - font-weight: bold; - border: 1px solid #C4CFE5; - margin: 2px 0px 2px 0; - padding: 2px 10px; -} - -td.indexvalue { - background-color: #EBEFF6; - border: 1px solid #C4CFE5; - padding: 2px 10px; - margin: 2px 0px; -} - -tr.memlist { - background-color: #EEF1F7; -} - -p.formulaDsp { - text-align: center; -} - -img.formulaDsp { - -} - -img.formulaInl { - vertical-align: middle; -} - -div.center { - text-align: center; - margin-top: 0px; - margin-bottom: 0px; - padding: 0px; -} - -div.center img { - border: 0px; -} - -address.footer { - text-align: right; - padding-right: 12px; -} - -img.footer { - border: 0px; - vertical-align: middle; -} - -/* @group Code Colorization */ - -span.keyword { - color: #008000 -} - -span.keywordtype { - color: #604020 -} - -span.keywordflow { - color: #e08000 -} - -span.comment { - color: #800000 -} - -span.preprocessor { - color: #806020 -} - -span.stringliteral { - color: #002080 -} - -span.charliteral { - color: #008080 -} - -span.vhdldigit { - color: #ff00ff -} - -span.vhdlchar { - color: #000000 -} - -span.vhdlkeyword { - color: #700070 -} - -span.vhdllogic { - color: #ff0000 -} - -/* @end */ - -/* -.search { - color: #003399; - font-weight: bold; -} - -form.search { - margin-bottom: 0px; - margin-top: 0px; -} - -input.search { - font-size: 75%; - color: #000080; - font-weight: normal; - background-color: #e8eef2; -} -*/ - -td.tiny { - font-size: 75%; -} - -.dirtab { - padding: 4px; - border-collapse: collapse; - border: 1px solid #A3B4D7; -} - -th.dirtab { - background: #EBEFF6; - font-weight: bold; -} - -hr { - height: 0px; - border: none; - border-top: 1px solid #4A6AAA; -} - -hr.footer { - height: 1px; -} - -/* @group Member Descriptions */ - -table.memberdecls { - border-spacing: 0px; - padding: 0px; -} - -.mdescLeft, .mdescRight, -.memItemLeft, .memItemRight, -.memTemplItemLeft, .memTemplItemRight, .memTemplParams { - background-color: #F9FAFC; - border: none; - margin: 4px; - padding: 1px 0 0 8px; -} - -.mdescLeft, .mdescRight { - padding: 0px 8px 4px 8px; - color: #555; -} - -.memItemLeft, .memItemRight, .memTemplParams { - border-top: 1px solid #C4CFE5; -} - -.memItemLeft, .memTemplItemLeft { - white-space: nowrap; -} - -.memItemRight { - width: 100%; -} - -.memTemplParams { - color: #4665A2; - white-space: nowrap; -} - -/* @end */ - -/* @group Member Details */ - -/* Styles for detailed member documentation */ - -.memtemplate { - font-size: 80%; - color: #4665A2; - font-weight: normal; - margin-left: 9px; -} - -.memnav { - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} - -.mempage { - width: 100%; -} - -.memitem { - padding: 0; - margin-bottom: 10px; - margin-right: 5px; -} - -.memname { - white-space: nowrap; - font-weight: bold; - margin-left: 6px; -} - -.memproto { - border-top: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; - padding: 6px 0px 6px 0px; - color: #253555; - font-weight: bold; - text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); - /* opera specific markup */ - box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - border-top-right-radius: 8px; - border-top-left-radius: 8px; - /* firefox specific markup */ - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - -moz-border-radius-topright: 8px; - -moz-border-radius-topleft: 8px; - /* webkit specific markup */ - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - -webkit-border-top-right-radius: 8px; - -webkit-border-top-left-radius: 8px; - background-image: url('nav_f.png'); - background-repeat: repeat-x; - background-color: #E2E8F2; - -} - -.memdoc { - border-bottom: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; - padding: 2px 5px; - background-color: #FBFCFD; - border-top-width: 0; - /* opera specific markup */ - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; - box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - /* firefox specific markup */ - -moz-border-radius-bottomleft: 8px; - -moz-border-radius-bottomright: 8px; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); - /* webkit specific markup */ - -webkit-border-bottom-left-radius: 8px; - -webkit-border-bottom-right-radius: 8px; - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - background-image: -webkit-gradient(linear, center top, center bottom, from(#FFFFFF), color-stop(0.6, #FFFFFF), color-stop(0.60, #FFFFFF), color-stop(0.95, #F7F8FB), to(#EEF1F7)); -} - -.paramkey { - text-align: right; -} - -.paramtype { - white-space: nowrap; -} - -.paramname { - color: #602020; - white-space: nowrap; -} - -.paramname em { - font-style: normal; -} - -.params, .retval, .exception, .tparams { - border-spacing: 6px 2px; -} - -.params .paramname, .retval .paramname { - font-weight: bold; - vertical-align: top; -} - -.params .paramtype { - font-style: italic; - vertical-align: top; -} - -.params .paramdir { - font-family: "courier new", courier, monospace; - vertical-align: top; -} - - -/* @end */ - -/* @group Directory (tree) */ - -/* for the tree view */ - -.ftvtree { - font-family: sans-serif; - margin: 0px; -} - -/* these are for tree view when used as main index */ - -.directory { - font-size: 9pt; - font-weight: bold; - margin: 5px; -} - -.directory h3 { - margin: 0px; - margin-top: 1em; - font-size: 11pt; -} - -/* -The following two styles can be used to replace the root node title -with an image of your choice. Simply uncomment the next two styles, -specify the name of your image and be sure to set 'height' to the -proper pixel height of your image. -*/ - -/* -.directory h3.swap { - height: 61px; - background-repeat: no-repeat; - background-image: url("yourimage.gif"); -} -.directory h3.swap span { - display: none; -} -*/ - -.directory > h3 { - margin-top: 0; -} - -.directory p { - margin: 0px; - white-space: nowrap; -} - -.directory div { - display: none; - margin: 0px; -} - -.directory img { - vertical-align: -30%; -} - -/* these are for tree view when not used as main index */ - -.directory-alt { - font-size: 100%; - font-weight: bold; -} - -.directory-alt h3 { - margin: 0px; - margin-top: 1em; - font-size: 11pt; -} - -.directory-alt > h3 { - margin-top: 0; -} - -.directory-alt p { - margin: 0px; - white-space: nowrap; -} - -.directory-alt div { - display: none; - margin: 0px; -} - -.directory-alt img { - vertical-align: -30%; -} - -/* @end */ - -div.dynheader { - margin-top: 8px; -} - -address { - font-style: normal; - color: #2A3D61; -} - -table.doxtable { - border-collapse: collapse; -} - -table.doxtable td, table.doxtable th { - border: 1px solid #2D4068; - padding: 3px 7px 2px; -} - -table.doxtable th { - background-color: #374F7F; - color: #FFFFFF; - font-size: 110%; - padding-bottom: 4px; - padding-top: 5px; - text-align: left; -} - -.tabsearch { - top: 0px; - left: 10px; - height: 36px; - background-image: url('tab_b.png'); - z-index: 101; - overflow: hidden; - font-size: 13px; -} - -.navpath ul { - font-size: 11px; - background-image: url('tab_b.png'); - background-repeat: repeat-x; - height: 30px; - line-height: 30px; - color: #8AA0CC; - border: solid 1px #C2CDE4; - overflow: hidden; - margin: 0px; - padding: 0px; -} - -.navpath li { - list-style-type: none; - float: left; - padding-left: 10px; - padding-right: 15px; - background-image: url('bc_s.png'); - background-repeat: no-repeat; - background-position: right; - color: #364D7C; -} - -.navpath li.navelem a { - height: 32px; - display: block; - text-decoration: none; - outline: none; -} - -.navpath li.navelem a:hover { - color: #6884BD; -} - -.navpath li.footer { - list-style-type: none; - float: right; - padding-left: 10px; - padding-right: 15px; - background-image: none; - background-repeat: no-repeat; - background-position: right; - color: #364D7C; - font-size: 8pt; -} - - -div.summary { - float: right; - font-size: 8pt; - padding-right: 5px; - width: 50%; - text-align: right; -} - -div.summary a { - white-space: nowrap; -} - -div.ingroups { - font-size: 8pt; - padding-left: 5px; - width: 50%; - text-align: left; -} - -div.ingroups a { - white-space: nowrap; -} - -div.header { - background-image: url('nav_h.png'); - background-repeat: repeat-x; - background-color: #F9FAFC; - margin: 0px; - border-bottom: 1px solid #C4CFE5; -} - -div.headertitle { - padding: 5px 5px 5px 10px; -} - -dl { - padding: 0 0 0 10px; -} - -dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug { - border-left: 4px solid; - padding: 0 0 0 6px; -} - -dl.note { - border-color: #D0C000; -} - -dl.warning, dl.attention { - border-color: #FF0000; -} - -dl.pre, dl.post, dl.invariant { - border-color: #00D000; -} - -dl.deprecated { - border-color: #505050; -} - -dl.todo { - border-color: #00C0E0; -} - -dl.test { - border-color: #3030E0; -} - -dl.bug { - border-color: #C08050; -} - -#projectlogo { - text-align: center; - vertical-align: bottom; - border-collapse: separate; -} - -#projectlogo img { - border: 0px none; -} - -#projectname { - font: 300% Tahoma, Arial, sans-serif; - margin: 0px; - padding: 2px 0px; -} - -#projectbrief { - font: 120% Tahoma, Arial, sans-serif; - margin: 0px; - padding: 0px; -} - -#projectnumber { - font: 50% Tahoma, Arial, sans-serif; - margin: 0px; - padding: 0px; -} - -#titlearea { - padding: 0px; - margin: 0px; - width: 100%; - border-bottom: 1px solid #5373B4; -} - -.image { - text-align: left; -} - -.dotgraph { - text-align: center; -} - -.mscgraph { - text-align: center; -} - -.caption { - font-weight: bold; -} -td.fielddoc -th.markdownTableHeadLeft, -th.markdownTableHeadRight, -th.markdownTableHeadCenter, -th.markdownTableHeadNone { - background-image: none; - border-radius: unset; -} - -td.fielddoc tr:last-child { - border-bottom: 1px solid #2D4068; -} diff --git a/RF24/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino b/RF24/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino deleted file mode 100644 index 498b8230e03a8c864f4b4dfe4b6881880207320a..0000000000000000000000000000000000000000 --- a/RF24/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino +++ /dev/null @@ -1,207 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with Acknowledgement (ACK) payloads attached to ACK packets. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ -#include <SPI.h> -#include "printf.h" -#include "RF24.h" - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin - -// an identifying device destination -// Let these addresses be used for the pair -uint8_t address[][6] = { "1Node", "2Node" }; -// It is very helpful to think of an address as a path instead of as -// an identifying device destination -// to use different addresses on a pair of radios, we need a variable to - -// uniquely identify which address this radio will use to transmit -bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX role, false = RX role - -// For this example, we'll be using a payload containing -// a string & an integer number that will be incremented -// on every successful transmission. -// Make a data structure to store the entire payload of different datatypes -struct PayloadStruct { - char message[7]; // only using 6 characters for TX & ACK payloads - uint8_t counter; -}; -PayloadStruct payload; - -void setup() { - - Serial.begin(115200); - while (!Serial) { - // some boards need to wait to ensure access to serial over USB - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - Serial.println(F("radio hardware is not responding!!")); - while (1) {} // hold in infinite loop - } - - // print example's introductory prompt - Serial.println(F("RF24/examples/AcknowledgementPayloads")); - - // To set the radioNumber via the Serial monitor on startup - Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'")); - while (!Serial.available()) { - // wait for user input - } - char input = Serial.parseInt(); - radioNumber = input == 1; - Serial.print(F("radioNumber = ")); - Serial.println((int)radioNumber); - - // role variable is hardcoded to RX behavior, inform the user of this - Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // to use ACK payloads, we need to enable dynamic payload lengths (for all nodes) - radio.enableDynamicPayloads(); // ACK payloads are dynamically sized - - // Acknowledgement packets have no payloads by default. We need to enable - // this feature for all nodes (TX & RX) to use ACK payloads. - radio.enableAckPayload(); - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // additional setup specific to the node's role - if (role) { - // setup the TX payload - - memcpy(payload.message, "Hello ", 6); // set the payload message - radio.stopListening(); // put radio in TX mode - } else { - // setup the ACK payload & load the first response into the FIFO - - memcpy(payload.message, "World ", 6); // set the payload message - // load the payload for the first received transmission on pipe 0 - radio.writeAckPayload(1, &payload, sizeof(payload)); - - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data -} - -void loop() { - - if (role) { - // This device is a TX node - - unsigned long start_timer = micros(); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - unsigned long end_timer = micros(); // end the timer - - if (report) { - Serial.print(F("Transmission successful! ")); // payload was delivered - Serial.print(F("Time to transmit = ")); - Serial.print(end_timer - start_timer); // print the timer result - Serial.print(F(" us. Sent: ")); - Serial.print(payload.message); // print the outgoing message - Serial.print(payload.counter); // print the outgoing counter - uint8_t pipe; - if (radio.available(&pipe)) { // is there an ACK payload? grab the pipe number that received it - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming ACK payload - Serial.print(F(" Recieved ")); - Serial.print(radio.getDynamicPayloadSize()); // print incoming payload size - Serial.print(F(" bytes on pipe ")); - Serial.print(pipe); // print pipe number that received the ACK - Serial.print(F(": ")); - Serial.print(received.message); // print incoming message - Serial.println(received.counter); // print incoming counter - - // save incoming counter & increment for next outgoing - payload.counter = received.counter + 1; - - } else { - Serial.println(F(" Recieved: an empty ACK packet")); // empty ACK packet received - } - - - } else { - Serial.println(F("Transmission failed or timed out")); // payload was not delivered - } - - // to make this example readable in the serial monitor - delay(1000); // slow transmissions down by 1 second - - } else { - // This device is a RX node - - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getDynamicPayloadSize(); // get the size of the payload - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming payload - Serial.print(F("Received ")); - Serial.print(bytes); // print the size of the payload - Serial.print(F(" bytes on pipe ")); - Serial.print(pipe); // print the pipe number - Serial.print(F(": ")); - Serial.print(received.message); // print incoming message - Serial.print(received.counter); // print incoming counter - Serial.print(F(" Sent: ")); - Serial.print(payload.message); // print outgoing message - Serial.println(payload.counter); // print outgoing counter - - // save incoming counter & increment for next outgoing - payload.counter = received.counter + 1; - // load the payload for the first received transmission on pipe 0 - radio.writeAckPayload(1, &payload, sizeof(payload)); - } - } // role - - if (Serial.available()) { - // change the role via the serial monitor - - char c = toupper(Serial.read()); - if (c == 'T' && !role) { - // Become the TX node - - role = true; - Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); - - memcpy(payload.message, "Hello ", 6); // change payload message - radio.stopListening(); // this also discards any unused ACK payloads - - } else if (c == 'R' && role) { - // Become the RX node - - role = false; - Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); - memcpy(payload.message, "World ", 6); // change payload message - - // load the payload for the first received transmission on pipe 0 - radio.writeAckPayload(1, &payload, sizeof(payload)); - radio.startListening(); - } - } -} // loop diff --git a/RF24/examples/GettingStarted/GettingStarted.ino b/RF24/examples/GettingStarted/GettingStarted.ino deleted file mode 100644 index 39739e0ec1ce7e0e9ffe96182197a9bfc240cb9c..0000000000000000000000000000000000000000 --- a/RF24/examples/GettingStarted/GettingStarted.ino +++ /dev/null @@ -1,154 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ -#include <SPI.h> -#include "printf.h" -#include "RF24.h" - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin - -// Let these addresses be used for the pair -uint8_t address[][6] = { "1Node", "2Node" }; -// It is very helpful to think of an address as a path instead of as -// an identifying device destination - -// to use different addresses on a pair of radios, we need a variable to -// uniquely identify which address this radio will use to transmit -bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX role, false = RX role - -// For this example, we'll be using a payload containing -// a single float number that will be incremented -// on every successful transmission -float payload = 0.0; - -void setup() { - - Serial.begin(115200); - while (!Serial) { - // some boards need to wait to ensure access to serial over USB - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - Serial.println(F("radio hardware is not responding!!")); - while (1) {} // hold in infinite loop - } - - // print example's introductory prompt - Serial.println(F("RF24/examples/GettingStarted")); - - // To set the radioNumber via the Serial monitor on startup - Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'")); - while (!Serial.available()) { - // wait for user input - } - char input = Serial.parseInt(); - radioNumber = input == 1; - Serial.print(F("radioNumber = ")); - Serial.println((int)radioNumber); - - // role variable is hardcoded to RX behavior, inform the user of this - Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // float datatype occupies 4 bytes - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // additional setup specific to the node's role - if (role) { - radio.stopListening(); // put radio in TX mode - } else { - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - -} // setup - -void loop() { - - if (role) { - // This device is a TX node - - unsigned long start_timer = micros(); // start the timer - bool report = radio.write(&payload, sizeof(float)); // transmit & save the report - unsigned long end_timer = micros(); // end the timer - - if (report) { - Serial.print(F("Transmission successful! ")); // payload was delivered - Serial.print(F("Time to transmit = ")); - Serial.print(end_timer - start_timer); // print the timer result - Serial.print(F(" us. Sent: ")); - Serial.println(payload); // print payload sent - payload += 0.01; // increment float payload - } else { - Serial.println(F("Transmission failed or timed out")); // payload was not delivered - } - - // to make this example readable in the serial monitor - delay(1000); // slow transmissions down by 1 second - - } else { - // This device is a RX node - - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getPayloadSize(); // get the size of the payload - radio.read(&payload, bytes); // fetch payload from FIFO - Serial.print(F("Received ")); - Serial.print(bytes); // print the size of the payload - Serial.print(F(" bytes on pipe ")); - Serial.print(pipe); // print the pipe number - Serial.print(F(": ")); - Serial.println(payload); // print the payload's value - } - } // role - - if (Serial.available()) { - // change the role via the serial monitor - - char c = toupper(Serial.read()); - if (c == 'T' && !role) { - // Become the TX node - - role = true; - Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); - radio.stopListening(); - - } else if (c == 'R' && role) { - // Become the RX node - - role = false; - Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); - radio.startListening(); - } - } - -} // loop diff --git a/RF24/examples/InterruptConfigure/InterruptConfigure.ino b/RF24/examples/InterruptConfigure/InterruptConfigure.ino deleted file mode 100644 index 7f3de4fe958141475ee56dffe9f0fbb0b405194d..0000000000000000000000000000000000000000 --- a/RF24/examples/InterruptConfigure/InterruptConfigure.ino +++ /dev/null @@ -1,345 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * This example uses Acknowledgement (ACK) payloads attached to ACK packets to - * demonstrate how the nRF24L01's IRQ (Interrupt Request) pin can be - * configured to detect when data is received, or when data has transmitted - * successfully, or when data has failed to transmit. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ -#include <SPI.h> -#include "printf.h" -#include "RF24.h" - -// We will be using the nRF24L01's IRQ pin for this example -#define IRQ_PIN 2 // this needs to be a digital input capable pin -volatile bool wait_for_event = false; // used to wait for an IRQ event to trigger - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin - -// Let these addresses be used for the pair -uint8_t address[][6] = { "1Node", "2Node" }; -// It is very helpful to think of an address as a path instead of as -// an identifying device destination - -// to use different addresses on a pair of radios, we need a variable to -// uniquely identify which address this radio will use to transmit -bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX node, false = RX node - -// For this example, we'll be using a payload containing -// a string that changes on every transmission. (successful or not) -// Make a couple arrays of payloads & an iterator to traverse them -const uint8_t tx_pl_size = 5; -const uint8_t ack_pl_size = 4; -uint8_t pl_iterator = 0; -// The " + 1" compensates for the c-string's NULL terminating 0 -char tx_payloads[][tx_pl_size + 1] = { "Ping ", "Pong ", "Radio", "1FAIL" }; -char ack_payloads[][ack_pl_size + 1] = { "Yak ", "Back", " ACK" }; - -void interruptHandler(); // prototype to handle IRQ events -void printRxFifo(); // prototype to print RX FIFO with 1 buffer - - -void setup() { - Serial.begin(115200); - while (!Serial) { - // some boards need to wait to ensure access to serial over USB - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - Serial.println(F("radio hardware is not responding!!")); - while (1) {} // hold in infinite loop - } - - // print example's introductory prompt - Serial.println(F("RF24/examples/InterruptConfigure")); - - // To set the radioNumber via the Serial monitor on startup - Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'")); - while (!Serial.available()) { - // wait for user input - } - char input = Serial.parseInt(); - radioNumber = input == 1; - Serial.print(F("radioNumber = ")); - Serial.println((int)radioNumber); - - // role variable is hardcoded to RX behavior, inform the user of this - Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); - - // setup the IRQ_PIN - pinMode(IRQ_PIN, INPUT); - attachInterrupt(digitalPinToInterrupt(IRQ_PIN), interruptHandler, FALLING); - // IMPORTANT: do not call radio.available() before calling - // radio.whatHappened() when the interruptHandler() is triggered by the - // IRQ pin FALLING event. According to the datasheet, the pipe information - // is unreliable during the IRQ pin FALLING transition. - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // For this example we use acknowledgment (ACK) payloads to trigger the - // IRQ pin when data is received on the TX node. - // to use ACK payloads, we need to enable dynamic payload lengths - radio.enableDynamicPayloads(); // ACK payloads are dynamically sized - - // Acknowledgement packets have no payloads by default. We need to enable - // this feature for all nodes (TX & RX) to use ACK payloads. - radio.enableAckPayload(); - // Fot this example, we use the same address to send data back and forth - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // additional setup specific to the node's role - if (role) { - // setup for TX mode - radio.stopListening(); // put radio in TX mode - - } else { - // setup for RX mode - - // let IRQ pin only trigger on "data ready" event in RX mode - radio.maskIRQ(1, 1, 0); // args = "data_sent", "data_fail", "data_ready" - - // Fill the TX FIFO with 3 ACK payloads for the first 3 received - // transmissions on pipe 1 - radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); - - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data -} - -void loop() { - if (role && !wait_for_event) { - - // delay(1); // wait for IRQ pin to fully RISE - - // This device is a TX node. This if block is only triggered when - // NOT waiting for an IRQ event to happen - - if (pl_iterator == 0) { - // Test the "data ready" event with the IRQ pin - - Serial.println(F("\nConfiguring IRQ pin to ignore the 'data sent' event")); - radio.maskIRQ(true, false, false); // args = "data_sent", "data_fail", "data_ready" - Serial.println(F(" Pinging RX node for 'data ready' event...")); - - } else if (pl_iterator == 1) { - // Test the "data sent" event with the IRQ pin - - Serial.println(F("\nConfiguring IRQ pin to ignore the 'data ready' event")); - radio.maskIRQ(false, false, true); // args = "data_sent", "data_fail", "data_ready" - Serial.println(F(" Pinging RX node for 'data sent' event...")); - - } else if (pl_iterator == 2) { - // Use this iteration to fill the RX node's FIFO which sets us up for the next test. - - // write() uses virtual interrupt flags that work despite the masking of the IRQ pin - radio.maskIRQ(1, 1, 1); // disable IRQ masking for this step - - Serial.println(F("\nSending 1 payload to fill RX node's FIFO. IRQ pin is neglected.")); - // write() will call flush_tx() on 'data fail' events - if (radio.write(&tx_payloads[pl_iterator], tx_pl_size)) { - if (radio.rxFifoFull()) { - Serial.println(F("RX node's FIFO is full; it is not listening any more")); - } else { - Serial.println("Transmission successful, but the RX node might still be listening."); - } - } else { - Serial.println(F("Transmission failed or timed out. Continuing anyway.")); - radio.flush_tx(); // discard payload(s) that failed to transmit - } - - } else if (pl_iterator == 3) { - // test the "data fail" event with the IRQ pin - - Serial.println(F("\nConfiguring IRQ pin to reflect all events")); - radio.maskIRQ(0, 0, 0); // args = "data_sent", "data_fail", "data_ready" - Serial.println(F(" Pinging inactive RX node for 'data fail' event...")); - } - - if (pl_iterator < 4 && pl_iterator != 2) { - - // IRQ pin is LOW when activated. Otherwise it is always HIGH - // Wait until IRQ pin is activated. - wait_for_event = true; - - // use the non-blocking call to write a payload and begin transmission - // the "false" argument means we are expecting an ACK packet response - radio.startFastWrite(tx_payloads[pl_iterator++], tx_pl_size, false); - - // In this example, the "data fail" event is always configured to - // trigger the IRQ pin active. Because the auto-ACK feature is on by - // default, we don't need a timeout check to prevent an infinite loop. - - } else if (pl_iterator == 4) { - // all IRQ tests are done; flush_tx() and print the ACK payloads for fun - - // CE pin is still HIGH which consumes more power. Example is now idling so... - radio.stopListening(); // ensure CE pin is LOW - // stopListening() also calls flush_tx() when ACK payloads are enabled - - printRxFifo(); - pl_iterator++; - - - // inform user what to do next - Serial.println(F("\n*** PRESS 'T' to restart the transmissions")); - Serial.println(F("*** PRESS 'R' to change to Receive role\n")); - - - } else if (pl_iterator == 2) { - pl_iterator++; // proceed from step 3 to last step (stop at step 4 for readability) - } - - } else if (!role) { - // This device is a RX node - - if (radio.rxFifoFull()) { - // wait until RX FIFO is full then stop listening - - delay(100); // let ACK payload finish transmitting - radio.stopListening(); // also discards unused ACK payloads - printRxFifo(); // flush the RX FIFO - - // Fill the TX FIFO with 3 ACK payloads for the first 3 received - // transmissions on pipe 1. - radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); - - delay(100); // let TX node finish its role - radio.startListening(); // We're ready to start over. Begin listening. - } - - } // role - - if (Serial.available()) { - // change the role via the serial monitor - - char c = toupper(Serial.read()); - if (c == 'T') { - // Become the TX node - if (!role) - Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); - else - Serial.println(F("*** RESTARTING IRQ PIN TEST ***")); - - role = true; - wait_for_event = false; - pl_iterator = 0; // reset the iterator - radio.flush_tx(); // discard any payloads in the TX FIFO - - // startListening() clears the IRQ masks also. This is required for - // continued TX operations when a transmission fails. - radio.stopListening(); // this also discards any unused ACK payloads - - } else if (c == 'R' && role) { - // Become the RX node - Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); - - role = false; - - radio.maskIRQ(0, 0, 0); // the IRQ pin should only trigger on "data ready" event - - // Fill the TX FIFO with 3 ACK payloads for the first 3 received - // transmissions on pipe 1 - radio.flush_tx(); // make sure there is room for 3 new ACK payloads - radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); - radio.startListening(); - } - } // Serial.available() -} // loop - - -/** - * when the IRQ pin goes active LOW, call this fuction print out why - */ -void interruptHandler() { - // print IRQ status and all masking flags' states - - Serial.println(F("\tIRQ pin is actively LOW")); // show that this function was called - delayMicroseconds(250); - bool tx_ds, tx_df, rx_dr; // declare variables for IRQ masks - radio.whatHappened(tx_ds, tx_df, rx_dr); // get values for IRQ masks - // whatHappened() clears the IRQ masks also. This is required for - // continued TX operations when a transmission fails. - // clearing the IRQ masks resets the IRQ pin to its inactive state (HIGH) - - Serial.print(F("\tdata_sent: ")); - Serial.print(tx_ds); // print "data sent" mask state - Serial.print(F(", data_fail: ")); - Serial.print(tx_df); // print "data fail" mask state - Serial.print(F(", data_ready: ")); - Serial.println(rx_dr); // print "data ready" mask state - - if (tx_df) // if TX payload failed - radio.flush_tx(); // clear all payloads from the TX FIFO - - // print if test passed or failed. Unintentional fails mean the RX node was not listening. - // pl_iterator has already been incremented by now - if (pl_iterator <= 1) { - Serial.print(F(" 'Data Ready' event test ")); - Serial.println(rx_dr ? F("passed") : F("failed")); - } else if (pl_iterator == 2) { - Serial.print(F(" 'Data Sent' event test ")); - Serial.println(tx_ds ? F("passed") : F("failed")); - } else if (pl_iterator == 4) { - Serial.print(F(" 'Data Fail' event test ")); - Serial.println(tx_df ? F("passed") : F("failed")); - } - wait_for_event = false; // ready to continue with loop() operations -} // interruptHandler - - -/** - * Print the entire RX FIFO with one buffer. This will also flush the RX FIFO. - * Remember that the payload sizes are declared as tx_pl_size and ack_pl_size. - */ -void printRxFifo() { - if (radio.available()) { // if there is data in the RX FIFO - // to flush the data from the RX FIFO, we'll fetch it all using 1 buffer - - uint8_t pl_size = !role ? tx_pl_size : ack_pl_size; - char rx_fifo[pl_size * 3 + 1]; // RX FIFO is full & we know ACK payloads' size - if (radio.rxFifoFull()) { - rx_fifo[pl_size * 3] = 0; // add a NULL terminating char to use as a c-string - radio.read(&rx_fifo, pl_size * 3); // this clears the RX FIFO (for this example) - } else { - uint8_t i = 0; - while (radio.available()) { - radio.read(&rx_fifo + (i * pl_size), pl_size); - i++; - } - rx_fifo[i * pl_size] = 0; // add a NULL terminating char to use as a c-string - } - Serial.print(F("Complete RX FIFO: ")); - Serial.println(rx_fifo); // print the entire RX FIFO with 1 buffer - } -} diff --git a/RF24/examples/ManualAcknowledgements/ManualAcknowledgements.ino b/RF24/examples/ManualAcknowledgements/ManualAcknowledgements.ino deleted file mode 100644 index b036a8b97a60b0996713a0877e012b1682d7dc5e..0000000000000000000000000000000000000000 --- a/RF24/examples/ManualAcknowledgements/ManualAcknowledgements.ino +++ /dev/null @@ -1,220 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. - * This example still uses ACK packets, but they have no payloads. Instead the - * acknowledging response is sent with `write()`. This tactic allows for more - * updated acknowledgement payload data, where actual ACK payloads' data are - * outdated by 1 transmission because they have to loaded before receiving a - * transmission. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ -#include <SPI.h> -#include "printf.h" -#include "RF24.h" - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin - -// Let these addresses be used for the pair -uint8_t address[][6] = { "1Node", "2Node" }; -// It is very helpful to think of an address as a path instead of as -// an identifying device destination - -// to use different addresses on a pair of radios, we need a variable to -// uniquely identify which address this radio will use to transmit -bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX node, false = RX node - -// For this example, we'll be using a payload containing -// a string & an integer number that will be incremented -// on every successful transmission. -// Make a data structure to store the entire payload of different datatypes -struct PayloadStruct { - char message[7]; // only using 6 characters for TX & RX payloads - uint8_t counter; -}; -PayloadStruct payload; - -void setup() { - - // append a NULL terminating character for printing as a c-string - payload.message[6] = 0; - - Serial.begin(115200); - while (!Serial) { - // some boards need to wait to ensure access to serial over USB - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - Serial.println(F("radio hardware is not responding!!")); - while (1) {} // hold in infinite loop - } - - // print example's introductory prompt - Serial.println(F("RF24/examples/ManualAcknowledgements")); - - // To set the radioNumber via the Serial monitor on startup - Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'")); - while (!Serial.available()) { - // wait for user input - } - char input = Serial.parseInt(); - radioNumber = input == 1; - Serial.print(F("radioNumber = ")); - Serial.println((int)radioNumber); - - // role variable is hardcoded to RX behavior, inform the user of this - Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - if (role) { - // setup the TX node - - memcpy(payload.message, "Hello ", 6); // set the outgoing message - radio.stopListening(); // put radio in TX mode - } else { - // setup the RX node - - memcpy(payload.message, "World ", 6); // set the outgoing message - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - -} // setup() - -void loop() { - - if (role) { - // This device is a TX node - - unsigned long start_timer = micros(); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - - if (report) { - // transmission successful; wait for response and print results - - radio.startListening(); // put in RX mode - unsigned long start_timeout = millis(); // timer to detect timeout - while (!radio.available()) { // wait for response - if (millis() - start_timeout > 200) // only wait 200 ms - break; - } - unsigned long end_timer = micros(); // end the timer - radio.stopListening(); // put back in TX mode - - // print summary of transactions - Serial.print(F("Transmission successful!")); // payload was delivered - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload received - Serial.print(F(" Round-trip delay: ")); - Serial.print(end_timer - start_timer); // print the timer result - Serial.print(F(" us. Sent: ")); - Serial.print(payload.message); // print the outgoing payload's message - Serial.print(payload.counter); // print outgoing payload's counter - PayloadStruct received; - radio.read(&received, sizeof(received)); // get payload from RX FIFO - Serial.print(F(" Received ")); - Serial.print(radio.getPayloadSize()); // print the size of the payload - Serial.print(F(" bytes on pipe ")); - Serial.print(pipe); // print the pipe number - Serial.print(F(": ")); - Serial.print(received.message); // print the incoming payload's message - Serial.println(received.counter); // print the incoming payload's counter - payload.counter = received.counter; // save incoming counter for next outgoing counter - } else { - Serial.println(F(" Recieved no response.")); // no response received - } - } else { - Serial.println(F("Transmission failed or timed out")); // payload was not delivered - } // report - - // to make this example readable in the serial monitor - delay(1000); // slow transmissions down by 1 second - - } else { - // This device is a RX node - - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming payload - payload.counter = received.counter + 1; // increment incoming counter for next outgoing response - - // transmit response & save result to `report` - radio.stopListening(); // put in TX mode - - radio.writeFast(&payload, sizeof(payload)); // load response to TX FIFO - bool report = radio.txStandBy(150); // keep retrying for 150 ms - - radio.startListening(); // put back in RX mode - - // print summary of transactions - Serial.print(F("Received ")); - Serial.print(radio.getPayloadSize()); // print the size of the payload - Serial.print(F(" bytes on pipe ")); - Serial.print(pipe); // print the pipe number - Serial.print(F(": ")); - Serial.print(received.message); // print incoming message - Serial.print(received.counter); // print incoming counter - - if (report) { - Serial.print(F(" Sent: ")); - Serial.print(payload.message); // print outgoing message - Serial.println(payload.counter); // print outgoing counter - } else { - Serial.println(" Response failed."); // failed to send response - } - } - } // role - - if (Serial.available()) { - // change the role via the serial monitor - - char c = toupper(Serial.read()); - if (c == 'T' && !role) { - // Become the TX node - - role = true; - memcpy(payload.message, "Hello ", 6); // set the outgoing message - Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); - radio.stopListening(); // put in TX mode - - } else if (c == 'R' && role) { - // Become the RX node - - role = false; - memcpy(payload.message, "World ", 6); // set the response message - Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); - radio.startListening(); // put in RX mode - } - } -} // loop diff --git a/RF24/examples/MulticeiverDemo/MulticeiverDemo.ino b/RF24/examples/MulticeiverDemo/MulticeiverDemo.ino deleted file mode 100644 index 797d6bec31c70f483275ff0d8823fba454f5dce0..0000000000000000000000000000000000000000 --- a/RF24/examples/MulticeiverDemo/MulticeiverDemo.ino +++ /dev/null @@ -1,196 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty 2bndy5 - */ - -/** - * A simple example of sending data from as many as 6 nRF24L01 transceivers to - * 1 receiving transceiver. This technique is trademarked by - * Nordic Semiconductors as "MultiCeiver". - * - * This example was written to be used on up to 6 devices acting as TX nodes & - * only 1 device acting as the RX node (that's a maximum of 7 devices). - * Use the Serial Monitor to change each node's behavior. - */ -#include <SPI.h> -#include "printf.h" -#include "RF24.h" - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin - -// For this example, we'll be using 6 addresses; 1 for each TX node -// It is very helpful to think of an address as a path instead of as -// an identifying device destination -// Notice that the last byte is the only byte that changes in the last 5 -// addresses. This is a limitation of the nRF24L01 transceiver for pipes 2-5 -// because they use the same first 4 bytes from pipe 1. -uint64_t address[6] = { 0x7878787878LL, - 0xB3B4B5B6F1LL, - 0xB3B4B5B6CDLL, - 0xB3B4B5B6A3LL, - 0xB3B4B5B60FLL, - 0xB3B4B5B605LL }; - -// Because this example allow up to 6 nodes (specified by numbers 0-5) to -// transmit and only 1 node to receive, we will use a negative value in our -// role variable to signify this node is a receiver. -// role variable is used to control whether this node is sending or receiving -char role = 'R'; // integers 0-5 = TX node; character 'R' or integer 82 = RX node - -// For this example, we'll be using a payload containing -// a node ID number and a single integer number that will be incremented -// on every successful transmission. -// Make a data structure to use as a payload. -struct PayloadStruct { - unsigned long nodeID; - unsigned long payloadID; -}; -PayloadStruct payload; - -// This example uses all 6 pipes to receive while TX nodes only use 2 pipes -// To make this easier we'll use a function to manage the addresses, and the -// payload's nodeID -void setRole(); // declare a prototype; definition is found after the loop() - -void setup() { - - Serial.begin(115200); - while (!Serial) { - // some boards need to wait to ensure access to serial over USB - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - Serial.println(F("radio hardware is not responding!!")); - while (1) {} // hold in infinite loop - } - - // print example's introductory prompt - Serial.println(F("RF24/examples/MulticeiverDemo")); - Serial.println(F("*** Enter a number between 0 and 5 (inclusive) to change")); - Serial.println(F(" the identifying node number that transmits.")); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity of - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // 2x int datatype occupy 8 bytes - - // Set the pipe addresses accordingly. This function additionally also - // calls startListening() or stopListening() and sets the payload's nodeID - setRole(); - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - -} // setup() - -void loop() { - - if (role <= 53) { - // This device is a TX node - - unsigned long start_timer = micros(); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - unsigned long end_timer = micros(); // end the timer - - if (report) { - // payload was delivered - - Serial.print(F("Transmission of payloadID ")); - Serial.print(payload.payloadID); // print payloadID - Serial.print(F(" as node ")); - Serial.print(payload.nodeID); // print nodeID - Serial.print(F(" successful!")); - Serial.print(F(" Time to transmit: ")); - Serial.print(end_timer - start_timer); // print the timer result - Serial.println(F(" us")); - } else { - Serial.println(F("Transmission failed or timed out")); // payload was not delivered - } - payload.payloadID++; // increment payload number - - // to make this example readable in the serial monitor - delay(1000); // slow transmissions down by 1 second - - } else if (role == 'R') { - // This device is the RX node - - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getPayloadSize(); // get the size of the payload - radio.read(&payload, bytes); // fetch payload from FIFO - Serial.print(F("Received ")); - Serial.print(bytes); // print the size of the payload - Serial.print(F(" bytes on pipe ")); - Serial.print(pipe); // print the pipe number - Serial.print(F(" from node ")); - Serial.print(payload.nodeID); // print the payload's origin - Serial.print(F(". PayloadID: ")); - Serial.println(payload.payloadID); // print the payload's number - } - } // role - - if (Serial.available()) { - // change the role via the serial monitor - - char c = Serial.read(); - if (toupper(c) == 'R' && role <= 53) { - // Become the RX node - - role = 'R'; - Serial.println(F("*** CHANGING ROLE TO RECEIVER ***")); - Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to act as")); - Serial.println(F(" a unique node number that transmits to the RX node.")); - setRole(); // change address on all pipes to TX nodes - - } else if (c >= 48 && c <= 53 && c != role) { - // Become a TX node with identifier 'c' - - role = c - 48; - Serial.print(F("*** CHANGING ROLE TO NODE ")); - Serial.print(c); - Serial.println(F(" ***")); - Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to change")); - Serial.println(F(" the identifying node number that transmits.")); - Serial.println(F("--- PRESS 'R' to act as the RX node.")); - setRole(); // change address on pipe 0 to the RX node - } - } - -} // loop - -void setRole() { - if (role == 'R') { - // For the RX node - - // Set the addresses for all pipes to TX nodes - for (uint8_t i = 0; i < 6; ++i) - radio.openReadingPipe(i, address[i]); - - radio.startListening(); // put radio in RX mode - - } else { - // For the TX node - - // set the payload's nodeID & reset the payload's identifying number - payload.nodeID = role; - payload.payloadID = 0; - - // Set the address on pipe 0 to the RX node. - radio.stopListening(); // put radio in TX mode - radio.openWritingPipe(address[role]); - - // According to the datasheet, the auto-retry features's delay value should - // be "skewed" to allow the RX node to receive 1 transmission at a time. - // So, use varying delay between retry attempts and 15 (at most) retry attempts - radio.setRetries(((role * 3) % 12) + 3, 15); // maximum value is 15 for both args - } -} // setRole diff --git a/RF24/examples/StreamingData/StreamingData.ino b/RF24/examples/StreamingData/StreamingData.ino deleted file mode 100644 index 5c5903df15c42b5452f89936e237c33425f674a2..0000000000000000000000000000000000000000 --- a/RF24/examples/StreamingData/StreamingData.ino +++ /dev/null @@ -1,185 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty 2bndy5 - */ - -/** - * A simple example of streaming data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Monitor to change each node's behavior. - */ -#include <SPI.h> -#include "printf.h" -#include "RF24.h" - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin - -// Let these addresses be used for the pair -uint8_t address[][6] = { "1Node", "2Node" }; -// It is very helpful to think of an address as a path instead of as -// an identifying device destination - -// to use different addresses on a pair of radios, we need a variable to -// uniquely identify which address this radio will use to transmit -bool radioNumber; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX node, false = RX node - -// For this example, we'll be sending 32 payloads each containing -// 32 bytes of data that looks like ASCII art when printed to the serial -// monitor. The TX node and RX node needs only a single 32 byte buffer. -#define SIZE 32 // this is the maximum for this example. (minimum is 1) -char buffer[SIZE + 1]; // for the RX node -uint8_t counter = 0; // for counting the number of received payloads -void makePayload(uint8_t); // prototype to construct a payload dynamically - - -void setup() { - - buffer[SIZE] = 0; // add a NULL terminating character (for easy printing) - - Serial.begin(115200); - while (!Serial) { - // some boards need to wait to ensure access to serial over USB - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - Serial.println(F("radio hardware is not responding!!")); - while (1) {} // hold in infinite loop - } - - // print example's introductory prompt - Serial.println(F("RF24/examples/StreamingData")); - - // To set the radioNumber via the Serial monitor on startup - Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'")); - while (!Serial.available()) { - // wait for user input - } - char input = Serial.parseInt(); - radioNumber = input == 1; - Serial.print(F("radioNumber = ")); - Serial.println((int)radioNumber); - - // role variable is hardcoded to RX behavior, inform the user of this - Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit - radio.setPayloadSize(SIZE); // default value is the maximum 32 bytes - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // additional setup specific to the node's role - if (role) { - radio.stopListening(); // put radio in TX mode - } else { - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - -} // setup() - - -void loop() { - - if (role) { - // This device is a TX node - - radio.flush_tx(); - uint8_t i = 0; - uint8_t failures = 0; - unsigned long start_timer = micros(); // start the timer - while (i < SIZE) { - makePayload(i); // make the payload - if (!radio.writeFast(&buffer, SIZE)) { - failures++; - radio.reUseTX(); - } else { - i++; - } - - if (failures >= 100) { - Serial.print(F("Too many failures detected. Aborting at payload ")); - Serial.println(buffer[0]); - break; - } - } - unsigned long end_timer = micros(); // end the timer - - Serial.print(F("Time to transmit = ")); - Serial.print(end_timer - start_timer); // print the timer result - Serial.print(F(" us with ")); - Serial.print(failures); // print failures detected - Serial.println(F(" failures detected")); - - // to make this example readable in the serial monitor - delay(1000); // slow transmissions down by 1 second - - } else { - // This device is a RX node - - if (radio.available()) { // is there a payload? - radio.read(&buffer, SIZE); // fetch payload from FIFO - Serial.print(F("Received: ")); - Serial.print(buffer); // print the payload's value - Serial.print(F(" - ")); - Serial.println(counter++); // print the received counter - } - } // role - - if (Serial.available()) { - // change the role via the serial monitor - - char c = toupper(Serial.read()); - if (c == 'T' && !role) { - // Become the TX node - - role = true; - counter = 0; //reset the RX node's counter - Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); - radio.stopListening(); - - } else if (c == 'R' && role) { - // Become the RX node - - role = false; - Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); - radio.startListening(); - } - } - -} // loop - - -void makePayload(uint8_t i) { - // Make a single payload based on position in stream. - // This example employs function to save memory on certain boards. - - // let the first character be an identifying alphanumeric prefix - // this lets us see which payload didn't get received - buffer[0] = i + (i < 26 ? 65 : 71); - for (uint8_t j = 0; j < SIZE - 1; ++j) { - char chr = j >= (SIZE - 1) / 2 + abs((SIZE - 1) / 2 - i); - chr |= j < (SIZE - 1) / 2 - abs((SIZE - 1) / 2 - i); - buffer[j + 1] = chr + 48; - } -} diff --git a/RF24/examples/encodeRadioDetails/encodeRadioDetails.ino b/RF24/examples/encodeRadioDetails/encodeRadioDetails.ino deleted file mode 100644 index 1cfcf090a108b98715d7817a2c06c87bda1c794e..0000000000000000000000000000000000000000 --- a/RF24/examples/encodeRadioDetails/encodeRadioDetails.ino +++ /dev/null @@ -1,121 +0,0 @@ -/* - See documentation at https://nRF24.github.io/RF24 - See License information at root directory of this library - Authors: Brendan Doherty (2bndy5), Douglas Quigg (dstroy0) -*/ - -/** - A simple example of getting debug info from the nRF24L01 transceiver. - - This example was written to demonstrate alternative methods to get debugging data. - 1. radio.encodeRadioDetails() will provide a data dump of all the nRF24L01's registers. - 2. radio.sprintfPrettyDetails() will behave similarly to printPrettyDetails(), but it - outputs to a char buffer that can be printed to any Serial (or other output) stream. - - Additionally, this example will show all default configuration values. -*/ -#include <SPI.h> -#include "RF24.h" - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin - -/* - For this example, we'll be using a data buffer containing - radio details encoded with RF24::encodeRadioDetails(). - It is meant to be decoded by an external program. - - There is a python script located in this example's folder that - will take a space-delimited string of hexadecimal characters and - decode then print it out as human readable information. -*/ -uint8_t encoded_details[43] = { 0 }; - -// Use this function to print out the encoded_details as a -// space-delimited string of hexadecimal characters. -void dumpRegData() { - for (uint8_t i = 0; i < 43; ++i) { - Serial.print(encoded_details[i], HEX); - if (i < 42) - Serial.print(F(" ")); - } -} - -void setup() { - - Serial.begin(115200); - while (!Serial) { - // some boards need to wait to ensure access to serial over USB - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - Serial.println(F("radio hardware is not responding!!")); - while (1) {} // hold in infinite loop - } - - // print example's introductory prompt - Serial.println(F("RF24/examples/encodedRadioDetails")); - - Serial.println(F("Press any key to show debugging information")); - while (!Serial.available()) { - // wait for user input - } - - // For debugging info - char *debug_info = new char[870]; - uint16_t str_len = radio.sprintfPrettyDetails(debug_info); - Serial.println(debug_info); - Serial.print(F("\nThe above output used ")); - Serial.print(str_len); - Serial.println(F(" characters.")); - - // encoded_details is NOT human readable. - // encodeRadioDetails() is very small when used on its own because it puts debugging information into a byte array - // No printf() support needed because it doesn't use an output stream. - radio.encodeRadioDetails(encoded_details); - Serial.println(F("\nhexadecimal dump of all registers:")); - dumpRegData(); - - Serial.println(F("\n\nCopy the above string of hexadecimal characters (including spaces).")); - Serial.print(F("Then paste it into a terminal using the print_details.py located in")); - Serial.print(F(" this example's folder. Like so:\npython print_details.py \"")); - dumpRegData(); - Serial.println(F("\"\n***You may need to use 'python3' (without quotes) on Linux")); -} // setup - -/* Registers correspnding to index of encoded_details array - 0: NRF_CONFIG - 1: EN_AA - 2: EN_RXADDR - 3: SETUP_AW - 4: SETUP_RETR - 5: RF_CH - 6: RF_SETUP - 7: NRF_STATUS - 8: OBSERVE_TX - 9: CD (aka RPD) - 10-14: RX_ADDR_P0 - 15-19: RX_ADDR_P1 - 20: RX_ADDR_P2 - 21: RX_ADDR_P3 - 22: RX_ADDR_P4 - 23: RX_ADDR_P5 - 24-28: TX_ADDR - 29: RX_PW_P0 - 30: RX_PW_P1 - 31: RX_PW_P2 - 32: RX_PW_P3 - 33: RX_PW_P4 - 34: RX_PW_P5 - 35: FIFO_STATUS - 36: DYNPD - 37: FEATURE - 38-39: ce_pin - 40-41: csn_pin - 42: SPI speed MHz | (isPlusVariant << 4) -*/ - -void loop() { - // Nothing to do here. We did it all at the end of setup() -} diff --git a/RF24/examples/encodeRadioDetails/print_details.py b/RF24/examples/encodeRadioDetails/print_details.py deleted file mode 100644 index 8dee9bf66800030f13c6dca8e7b571291466ea7d..0000000000000000000000000000000000000000 --- a/RF24/examples/encodeRadioDetails/print_details.py +++ /dev/null @@ -1,196 +0,0 @@ -"""A simple script to take all data dumped from the nRF24L01 registers and -output it in human readable form. - -Example usage: - print_details.py "0e 3f 02 03 00 02 00 0e" - -Notes: - * The radio's power state is represented under the assumption that - the radio's CE pin is inactive low. -""" -# pylint: disable=consider-using-f-string -import struct -import argparse - - -def hex_str_to_bytes(s_in: str) -> bytes: - """Used to convert a string from CLI to a bytearray object. - - .. warning:: This function assumes that the string consists of only - hexadecimal characters. - """ - return bytes([int(i, 16) for i in s_in.split()]) - - -argparser = argparse.ArgumentParser( - description=__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter, -) -argparser.add_argument( - "buffer", - type=hex_str_to_bytes, - help="The encoded buffer from the Arduino Serial Monitor. The string passed is " - "expected to contain only hexadecimal digits. It should be 38 words long " - "(separated by spaces).", -) - - -def address_repr(buf, reverse: bool = True, delimit: str = "") -> str: - """Convert a buffer into a hexlified string.""" - order = range(len(buf) - 1, -1, -1) if reverse else range(len(buf)) - return delimit.join(["%02X" % buf[byte] for byte in order]) - - -# pylint: disable=too-many-locals,too-many-statements -def print_details(encoded_buf: bytearray): - """This debuggung function outputs all details about the nRF24L01.""" - # declare sequences - pipes = [bytearray(5)] * 2 + [0] * 4 - pl_len = [0] * 6 - - # unpack bytearray - ( - config, # 0x00 - auto_ack, # 0x01 - open_pipes, # 0x02 - addr_len, # 0x03 - retry_setup, # 0x04 - channel, # 0x05 - rf_setup, # 0x06 - status, # 0x07 - observer, # 0x08 - rpd, # 0x09 - ) = struct.unpack("10B", encoded_buf[:10]) - pipes[0] = encoded_buf[10:15] # 0x0A - pipes[1] = encoded_buf[15:20] # 0x0B - ( - pipes[2], # 0x0C - pipes[3], # 0x0D - pipes[4], # 0x0E - pipes[5], # 0x0F - ) = struct.unpack("4B", encoded_buf[20:24]) - tx_address = encoded_buf[24:29] # 0x10 - ( - pl_len[0], # 0x11 - pl_len[1], # 0x12 - pl_len[2], # 0x13 - pl_len[3], # 0x14 - pl_len[4], # 0x15 - pl_len[5], # 0x16 - fifo, # 0x17 - dyn_pl, # 0x1C - features, # 0x1D - ) = struct.unpack("9B", encoded_buf[29:38]) - ce_pin, csn_pin, spi_speed = struct.unpack(">2H1B", encoded_buf[38:44]) - - # do some deciphering arithmetic - addr_len += 2 - crc = (2 if config & 4 else 1) if auto_ack else max(0, ((config & 0x0C) >> 2) - 1) - d_rate = rf_setup & 0x28 - d_rate = (2 if d_rate == 8 else 250) if d_rate else 1 - pa_level = (3 - ((rf_setup & 6) >> 1)) * -6 - pa_level = ( - "MIN" - if pa_level == -18 - else ("LOW" if pa_level == -12 else ("HIGH" if pa_level == -6 else "MAX")) - ) - dyn_p = ( - ("_Enabled" if dyn_pl else "Disabled") - if dyn_pl == 0x3F or not dyn_pl - else "0b" + "0" * (8 - len(bin(dyn_pl))) + bin(dyn_pl)[2:] - ) - auto_ack = ( - ("Enabled" if auto_ack else "Disabled") - if auto_ack == 0x3F or not auto_ack - else "0b" + "0" * (8 - len(bin(auto_ack))) + bin(auto_ack)[2:] - ) - pwr = "Standby" if config & 2 else "Off" - is_plus_variant = bool(spi_speed >> 4) - spi_speed = spi_speed & 0xF - - # print it all out - print("CE pin____________________{}".format(ce_pin)) - print("CSN pin___________________{}".format(csn_pin)) - print("SPI speed_________________{} MHz".format(spi_speed)) - print("Is a plus variant_________{}".format(is_plus_variant)) - print( - "Channel___________________{}".format(channel), - "~ {} GHz".format((channel + 2400) / 1000), - ) - print( - "RF Data Rate______________{}".format(d_rate), - "Mbps" if d_rate != 250 else "Kbps", - ) - print("RF Power Amplifier________PA_{}".format(pa_level)) - print( - "RF Low Noise Amplifier____{}abled".format( - "En" if bool(rf_setup & 1) else "Dis" - ) - ) - print("CRC Length________________{} bits".format(crc * 8)) - print("Address length____________{} bytes".format(addr_len)) - print("TX Payload lengths________{} bytes".format(pl_len[0])) - print( - "Auto retry delay__________{} microseconds".format( - ((retry_setup & 0xF0) >> 4) * 250 + 250 - ) - ) - print("Auto retry attempts_______{} maximum".format(retry_setup & 0x0F)) - print("Re-use TX FIFO____________{}".format(bool(fifo & 64))) - print("Received Power Detected___{}".format(bool(rpd))) - print( - "Packets lost on current channel_____________________{}".format(observer >> 4) - ) - print( - "Retry attempts made for last transmission___________{}".format(observer & 0xF) - ) - print( - "IRQ on Data Ready__{}abled".format("Dis" if config & 64 else "_En"), - " Data Ready___________{}".format(bool(status & 0x40)), - ) - print( - "IRQ on Data Sent___{}abled".format("Dis" if config & 32 else "_En"), - " Data Sent____________{}".format(bool(status & 0x20)), - ) - print( - "IRQ on Data Fail___{}abled".format("Dis" if config & 16 else "_En"), - " Data Failed__________{}".format(bool(status & 0x10)), - ) - print( - "TX FIFO full__________{}e".format("_Tru" if fifo & 0x20 else "Fals"), - " TX FIFO empty________{}".format(bool(fifo & 0x10)), - ) - print( - "RX FIFO full__________{}e".format("_Tru" if fifo & 2 else "Fals"), - " RX FIFO empty________{}".format(bool(fifo & 1)), - ) - print( - "Multicast__________{}ed Custom ACK Payload___{}abled".format( - "_Allow" if features & 1 else "Disabl", - "En" if features & 2 else "Dis", - ), - ) - print("Dynamic Payloads___{} Auto Acknowledgment__{}".format(dyn_p, auto_ack)) - print( - "Primary Mode_____________{}X".format("R" if config & 1 else "T"), - " Power Mode___________{}".format(pwr), - ) - print("TX address____________ 0x{}".format(address_repr(tx_address))) - for i in range(6): - is_open = open_pipes & (1 << i) - address = pipes[i] if i < 2 else bytes([pipes[i]]) + pipes[1][1:] - print( - "Pipe {} ({}) bound: 0x{}".format( - i, " open " if is_open else "closed", address_repr(address) - ), - ) - if is_open and not dyn_pl & (1 << i): - print("\t\texpecting {} byte static payloads".format(pl_len[i])) - - -# pylint: enable=too-many-locals,too-many-statements - - -if __name__ == "__main__": - args = argparser.parse_args() - print_details(args.buffer) diff --git a/RF24/examples/old_backups/GettingStarted_HandlingFailures/GettingStarted_HandlingFailures.ino b/RF24/examples/old_backups/GettingStarted_HandlingFailures/GettingStarted_HandlingFailures.ino deleted file mode 100644 index d6d2c4cc0717fc68dd71daaf171dd389395fd79b..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/GettingStarted_HandlingFailures/GettingStarted_HandlingFailures.ino +++ /dev/null @@ -1,217 +0,0 @@ - -/* - Getting Started example sketch for nRF24L01+ radios - This is a very basic example of how to send data from one node to another - but modified to include failure handling. - - The nrf24l01+ radios are fairly reliable devices, but on breadboards etc, with inconsistent wiring, failures may - occur randomly after many hours to days or weeks. This sketch demonstrates how to handle the various failures and - keep the radio operational. - - The three main failure modes of the radio include: - Writing to radio: Radio unresponsive - Fixed internally by adding a timeout to the internal write functions in RF24 (failure handling) - Reading from radio: Available returns true always - Fixed by adding a timeout to available functions by the user. This is implemented internally in RF24Network. - Radio configuration settings are lost - Fixed by monitoring a value that is different from the default, and re-configuring the radio if this setting reverts to the default. - - The printDetails output should appear as follows for radio #0: - - STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0 - RX_ADDR_P0-1 = 0x65646f4e31 0x65646f4e32 - RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6 - TX_ADDR = 0x65646f4e31 - RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00 - EN_AA = 0x3f - EN_RXADDR = 0x02 - RF_CH = 0x4c - RF_SETUP = 0x03 - CONFIG = 0x0f - DYNPD/FEATURE = 0x00 0x00 - Data Rate = 1MBPS - Model = nRF24L01+ - CRC Length = 16 bits - PA Power = PA_LOW - - Users can use this sketch to troubleshoot radio module wiring etc. as it makes the radios hot-swapable - - Updated: 2019 by TMRh20 -*/ - -#include <SPI.h> -#include "RF24.h" -#include "printf.h" - -/****************** User Config ***************************/ -/*** Set this radio as radio number 0 or 1 ***/ -bool radioNumber = 0; - -/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */ -RF24 radio(7, 8); -/**********************************************************/ - -byte addresses[][6] = { "1Node", "2Node" }; - -// Used to control whether this node is sending or receiving -bool role = 0; - - -/**********************************************************/ -//Function to configure the radio -void configureRadio() { - - radio.begin(); - - // Set the PA Level low to prevent power supply related issues since this is a - // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default. - radio.setPALevel(RF24_PA_LOW); - - // Open a writing and reading pipe on each radio, with opposite addresses - if (radioNumber) { - radio.openWritingPipe(addresses[1]); - radio.openReadingPipe(1, addresses[0]); - } else { - radio.openWritingPipe(addresses[0]); - radio.openReadingPipe(1, addresses[1]); - } - - // Start the radio listening for data - radio.startListening(); - radio.printDetails(); -} - - -/**********************************************************/ - -void setup() { - Serial.begin(115200); - Serial.println(F("RF24/examples/GettingStarted")); - Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); - - printf_begin(); - - configureRadio(); -} - -uint32_t configTimer = millis(); - -void loop() { - - if (radio.failureDetected) { - radio.failureDetected = false; - delay(250); - Serial.println("Radio failure detected, restarting radio"); - configureRadio(); - } - // Every 5 seconds, verify the configuration of the radio. This can be - // done using any setting that is different from the radio defaults. - if (millis() - configTimer > 5000) { - configTimer = millis(); - if (radio.getDataRate() != RF24_1MBPS) { - radio.failureDetected = true; - Serial.print("Radio configuration error detected"); - } - } - - - /****************** Ping Out Role ***************************/ - - if (role == 1) { - - radio.stopListening(); // First, stop listening so we can talk. - - Serial.println(F("Now sending")); - - unsigned long start_time = micros(); // Take the time, and send it. This will block until complete - if (!radio.write(&start_time, sizeof(unsigned long))) { - Serial.println(F("failed")); - } - - radio.startListening(); // Now, continue listening - - unsigned long started_waiting_at = micros(); // Set up a timeout period, get the current microseconds - bool timeout = false; // Set up a variable to indicate if a response was received or not - - while (!radio.available()) // While nothing is received - { - if (micros() - started_waiting_at > 200000) // If waited longer than 200ms, indicate timeout and exit while loop - { - timeout = true; - break; - } - } - - if (timeout) { - // Describe the results - Serial.println(F("Failed, response timed out.")); - } else { - // Grab the response, compare, and send to debugging spew - - unsigned long got_time; // Variable for the received timestamp - - // Failure Handling - uint32_t failTimer = millis(); - while (radio.available()) // If available() always returns true, there is a problem - { - if (millis() - failTimer > 250) { - radio.failureDetected = true; - Serial.println("Radio available failure detected"); - break; - } - radio.read(&got_time, sizeof(unsigned long)); - } - unsigned long end_time = micros(); - - // Spew it - Serial.print(F("Sent ")); - Serial.print(start_time); - Serial.print(F(", Got response ")); - Serial.print(got_time); - Serial.print(F(", Round-trip delay ")); - Serial.print(end_time - start_time); - Serial.println(F(" microseconds")); - } - - delay(1000); // Try again 1s later - } - - - /****************** Pong Back Role ***************************/ - - if (role == 0) { - unsigned long got_time; // Variable for the received timestamp - - if (radio.available()) { - uint32_t failTimer = millis(); - - while (radio.available()) // While there is data ready - { - if (millis() - failTimer > 500) { - Serial.println("Radio available failure detected"); - radio.failureDetected = true; - break; - } - radio.read(&got_time, sizeof(unsigned long)); // Get the payload - } - - radio.stopListening(); // First, stop listening so we can talk - radio.write(&got_time, sizeof(unsigned long)); // Send the final one back. - radio.startListening(); // Now, resume listening so we catch the next packets. - Serial.print(F("Sent response ")); - Serial.println(got_time); - } - } - - - /****************** Change Roles via Serial Commands ***************************/ - - if (Serial.available()) { - char c = toupper(Serial.read()); - if (c == 'T' && role == 0) { - Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); - role = 1; // Become the primary transmitter (ping out) - } else if (c == 'R' && role == 1) { - Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); - role = 0; // Become the primary receiver (pong back) - radio.startListening(); - } - } -} // Loop diff --git a/RF24/examples/old_backups/TransferTimeouts/TransferTimeouts.ino b/RF24/examples/old_backups/TransferTimeouts/TransferTimeouts.ino deleted file mode 100644 index 026f541f56ce3c2a59aa2ada1be5511241f9ffdd..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/TransferTimeouts/TransferTimeouts.ino +++ /dev/null @@ -1,185 +0,0 @@ -/* - TMRh20 2014 - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. -*/ - -/** - Reliably transmitting large volumes of data with a low signal or in noisy environments - This example demonstrates data transfer functionality with the use of auto-retry - and auto-reUse functionality enabled. This sketch demonstrates how a user can extend - the auto-retry functionality to any chosen time period, preventing data loss and ensuring - the consistency of data. - - This sketh demonstrates use of the writeBlocking() functionality, and extends the standard - retry functionality of the radio. Payloads will be auto-retried until successful or the - extended timeout period is reached. -*/ - - - -#include <SPI.h> -#include "nRF24L01.h" -#include "RF24.h" -#include "printf.h" - -/************* USER Configuration *****************************/ - -RF24 radio(7, 8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8 -unsigned long timeoutPeriod = 3000; // Set a user-defined timeout period. With auto-retransmit set to (15,15) retransmission will take up to 60ms and as little as 7.5ms with it set to (1,15). -// With a timeout period of 1000, the radio will retry each payload for up to 1 second before giving up on the transmission and starting over - -/***************************************************************/ - -const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // Radio pipe addresses for the 2 nodes to communicate. - -byte data[32]; //Data buffer - -volatile unsigned long counter; -unsigned long rxTimer, startTime, stopTime, payloads = 0; -bool tx = 1, rx = 0, role = 0, transferInProgress = 0; - - -void setup(void) { - - Serial.begin(115200); - printf_begin(); - - radio.begin(); // Setup and configure rf radio - radio.setChannel(1); // Set the channel - radio.setPALevel(RF24_PA_LOW); // Set PA LOW for this demonstration. We want the radio to be as lossy as possible for this example. - radio.setDataRate(RF24_1MBPS); // Raise the data rate to reduce transmission distance and increase lossiness - radio.setAutoAck(1); // Ensure autoACK is enabled - radio.setRetries(2, 15); // Optionally, increase the delay between retries. Want the number of auto-retries as high as possible (15) - radio.setCRCLength(RF24_CRC_16); // Set CRC length to 16-bit to ensure quality of data - radio.openWritingPipe(pipes[0]); // Open the default reading and writing pipe - radio.openReadingPipe(1, pipes[1]); - - radio.startListening(); // Start listening - radio.printDetails(); // Dump the configuration of the rf unit for debugging - - printf("\n\rRF24/examples/Transfer Rates/\n\r"); - printf("*** PRESS 'T' to begin transmitting to the other node\n\r"); - - randomSeed(analogRead(0)); //Seed for random number generation - for (int i = 0; i < 32; i++) { - data[i] = random(255); //Load the buffer with random data - } - radio.powerUp(); //Power up the radio -} - - - -void loop(void) { - - - if (role == tx) { - delay(2000); // Pause for a couple seconds between transfers - printf("Initiating Extended Timeout Data Transfer\n\r"); - - unsigned long cycles = 1000; // Change this to a higher or lower number. This is the number of payloads that will be sent. - - unsigned long transferCMD[] = { 'H', 'S', cycles }; // Indicate to the other radio that we are starting, and provide the number of payloads that will be sent - radio.writeFast(&transferCMD, 12); // Send the transfer command - if (radio.txStandBy(timeoutPeriod)) { // If transfer initiation was successful, do the following - - startTime = millis(); // For calculating transfer rate - boolean timedOut = 0; // Boolean for keeping track of failures - - for (unsigned long i = 0; i < cycles; i++) // Loop through a number of cycles - { - data[0] = i; // Change the first byte of the payload for identification - - if (!radio.writeBlocking(&data, 32, timeoutPeriod)) { // If retries are failing and the user defined timeout is exceeded - timedOut = 1; // Indicate failure - counter = cycles; // Set the fail count to maximum - break; // Break out of the for loop - } - } - - - stopTime = millis(); // Capture the time of completion or failure - - //This should be called to wait for completion and put the radio in standby mode after transmission, returns 0 if data still in FIFO (timed out), 1 if success - if (timedOut) { - radio.txStandBy(); //Partially blocking standby, blocks until success or max retries. FIFO flushed if auto timeout reached - } else { - radio.txStandBy(timeoutPeriod); //Standby, block until FIFO empty (sent) or user specified timeout reached. FIFO flushed if user timeout reached. - } - - } else { - Serial.println("Communication not established"); //If unsuccessful initiating transfer, exit and retry later - } - - float rate = cycles * 32 / (stopTime - startTime); //Display results: - - Serial.print("Transfer complete at "); - Serial.print(rate); - Serial.println(" KB/s"); - Serial.print(counter); - Serial.print(" of "); - Serial.print(cycles); - Serial.println(" Packets Failed to Send"); - counter = 0; - } - - - - if (role == rx) { - - if (!transferInProgress) { // If a bulk data transfer has not been started - if (radio.available()) { - radio.read(&data, 32); //Read any available payloads for analysis - - if (data[0] == 'H' && data[4] == 'S') { // If a bulk data transfer command has been received - payloads = data[8]; // Read the first two bytes of the unsigned long. Need to read the 3rd and 4th if sending more than 65535 payloads - payloads |= data[9] << 8; // This is the number of payloads that will be sent - counter = 0; // Reset the payload counter to 0 - transferInProgress = 1; // Indicate it has started - startTime = rxTimer = millis(); // Capture the start time to measure transfer rate and calculate timeouts - } - } - } else { - if (radio.available()) { // If in bulk transfer mode, and a payload is available - radio.read(&data, 32); // Read the payload - rxTimer = millis(); // Reset the timeout timer - counter++; // Keep a count of received payloads - } else if (millis() - rxTimer > timeoutPeriod) { // If no data available, check the timeout period - Serial.println("Transfer Failed"); // If per-payload timeout exceeeded, end the transfer - transferInProgress = 0; - } else if (counter >= payloads) { // If the specified number of payloads is reached, transfer is completed - startTime = millis() - startTime; // Calculate the total time spent during transfer - float numBytes = counter * 32; // Calculate the number of bytes transferred - Serial.print("Rate: "); // Print the transfer rate and number of payloads - Serial.print(numBytes / startTime); - Serial.println(" KB/s"); - Serial.print("Payload Count: "); - Serial.println(counter); - transferInProgress = 0; // End the transfer as complete - } - } - } - - // - // Change roles - // - - if (Serial.available()) { - char c = toupper(Serial.read()); - if (c == 'T' && role == rx) { - printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r"); - radio.openWritingPipe(pipes[1]); - radio.openReadingPipe(1, pipes[0]); - radio.stopListening(); - role = tx; // Become the primary transmitter (ping out) - } else if (c == 'R' && role == tx) { - radio.openWritingPipe(pipes[0]); - radio.openReadingPipe(1, pipes[1]); - radio.startListening(); - printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r"); - role = rx; // Become the primary receiver (pong back) - } - } -} diff --git a/RF24/examples/old_backups/pingpair_dyn/pingpair_dyn.ino b/RF24/examples/old_backups/pingpair_dyn/pingpair_dyn.ino deleted file mode 100644 index a27cbd39d7148ef260f57022fd3bde4322af79bf..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/pingpair_dyn/pingpair_dyn.ino +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ - -/** - * Example using Dynamic Payloads - * - * This is an example of how to use payloads of a varying (dynamic) size. - */ - -#include <SPI.h> -#include "nRF24L01.h" -#include "RF24.h" -#include "printf.h" - -// Hardware configuration -RF24 radio(7, 8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8 - -// Radio pipe addresses for the 2 nodes to communicate. -const uint64_t addresses[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; - -/************************* Role management ****************************/ -// Set up role. This sketch uses the same software for all the nodes in this -// system. Doing so greatly simplifies testing. - -// The role_pin is a digital input pin used to set the role of this radio. -// Connect the role_pin to GND to be the 'pong' receiver -// Leave the role_pin open to be the 'ping' transmitter -const short role_pin = 5; // use pin 5 -typedef enum { role_ping_out = 1, - role_pong_back } role_e; // The various roles supported by this sketch -const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back" }; // The debug-friendly names of those roles -role_e role; // The role of the current running sketch - - -// variables used for changing the payload size dynamically (used when role == role_ping_out) -const int min_payload_size = 4; -const int max_payload_size = 32; -const int payload_size_increment = 1; -int send_payload_size = min_payload_size; - -char receive_payload[max_payload_size + 1]; // +1 to allow room for a terminating NULL char - -void setup(void) { - pinMode(role_pin, INPUT); // set up the role pin - digitalWrite(role_pin, HIGH); - delay(20); // Just to get a solid reading on the role pin - - // read the role_pin, establish our role - if (digitalRead(role_pin)) { - role = role_ping_out; - } else { - role = role_pong_back; - } - - Serial.begin(115200); - printf_begin(); // needed for printDetails() - - // Print preamble - Serial.println(F("RF24/examples/pingpair_dyn/")); - Serial.print(F("ROLE: ")); - Serial.println(role_friendly_name[role]); - - // Setup and configure rf radio - radio.begin(); - radio.enableDynamicPayloads(); // Enable dynamic payloads - radio.setRetries(5, 15); // delay between retries = 5 * 250 + 250 = 1500 microseconds, number of retries = 15 - - // Open a writing and reading pipe on each radio, with opposite addresses - if (role == role_ping_out) { - radio.openWritingPipe(addresses[0]); - radio.openReadingPipe(1, addresses[1]); - } else { - radio.openWritingPipe(addresses[1]); - radio.openReadingPipe(1, addresses[0]); - } - - radio.startListening(); // Start listening - radio.printDetails(); // Dump the configuration of the rf unit for debugging -} - -void loop() { - - - /****************** Ping Out Role ***************************/ - - if (role == role_ping_out) { - // The payload will always be the same, what will change is how much of it we send. - static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012"; - - radio.stopListening(); // First, stop listening so we can talk. - - // Send the payload - Serial.print(F("Now sending length ")); - Serial.println(send_payload_size); - radio.write(send_payload, send_payload_size); // This will block until complete - - radio.startListening(); // Now, continue listening - - unsigned long started_waiting_at = millis(); // Start a timer for measuring timout - bool timeout = false; - while (!radio.available() && !timeout) // Wait until we get a response or timeout is reached - { - if (millis() - started_waiting_at > 500) // Only wait for 500 milliseconds - timeout = true; - } - - // Describe the results - if (timeout) { - Serial.println(F("Failed, response timed out.")); - } else { - // Grab the response and print it - - uint8_t len = radio.getDynamicPayloadSize(); // get payload's length - - // If an illegal payload size was detected, all RX payloads will be flushed - if (!len) - return; - - radio.read(receive_payload, len); - - // Use payload as a C-string (for easy printing) - receive_payload[len] = 0; // put a NULL terminating zero at the end - - // Spew it - Serial.print(F("Got response size=")); - Serial.print(len); - Serial.print(F(" value=")); - Serial.println(receive_payload); - } - - send_payload_size += payload_size_increment; // Update size for next time. - if (send_payload_size > max_payload_size) // if payload length is larger than the radio can handle - send_payload_size = min_payload_size; // reset the payload length - - delay(1000); // Try again 1s later - } - - - /****************** Pong Back Role ***************************/ - // Receive each packet, send it back, and dump it out - - if (role == role_pong_back) { - while (radio.available()) // if there is data ready - { - - uint8_t len = radio.getDynamicPayloadSize(); // Fetch the the payload size - - // If an illegal payload size was detected, all RX payloads will be flushed - if (!len) - continue; - - radio.read(receive_payload, len); - - // Use payload as a C-string (for easy printing) - receive_payload[len] = 0; // put a NULL terminating zero at the end - - // Spew it - Serial.print(F("Got response size=")); - Serial.print(len); - Serial.print(F(" value=")); - Serial.println(receive_payload); - - radio.stopListening(); // First, stop listening so we can talk - - // Send a reply that the packet was received - // - // You will have better luck delivering your message if - // you wait for the other node to start listening first - delay(20); - radio.write(receive_payload, len); - Serial.println(F("Sent response.")); - - radio.startListening(); // Now, resume listening so we catch the next packets. - } - } -} // loop -// vim:cin:ai:sts=2 sw=2 ft=cpp diff --git a/RF24/examples/old_backups/pingpair_irq/pingpair_irq.ino b/RF24/examples/old_backups/pingpair_irq/pingpair_irq.ino deleted file mode 100644 index 19623cc4dca4c56614ddaa033c4bcca4a5eee546..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/pingpair_irq/pingpair_irq.ino +++ /dev/null @@ -1,173 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - - Update 2014 - TMRh20 -*/ - -/** - Example of using interrupts - - This is an example of how to user interrupts to interact with the radio, and a demonstration - of how to use them to sleep when receiving, and not miss any payloads. - The pingpair_sleepy example expands on sleep functionality with a timed sleep option for the transmitter. - Sleep functionality is built directly into my fork of the RF24Network library -*/ - -#include <SPI.h> -#include "nRF24L01.h" -#include "RF24.h" -#include "printf.h" - -// Hardware configuration -RF24 radio(7, 8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8 - -// Our ACK payload will simply be 4 bytes containing the number of payloads received -static uint32_t message_count = 1; // start counting at 1 - -// Demonstrates another method of setting up the addresses -byte address[][5] = { 0xCC, 0xCE, 0xCC, 0xCE, 0xCC, 0xCE, 0xCC, 0xCE, 0xCC, 0xCE }; - -/************************* Role management ****************************/ -// Set up role. This sketch uses the same software for all the nodes in this -// system. Doing so greatly simplifies testing. - -// The role_pin is a digital input pin used to set the role of this radio. -// Connect the role_pin to GND to be the 'pong' receiver -// Leave the role_pin open to be the 'ping' transmitter -const short role_pin = 5; // use pin 5 -typedef enum { role_sender = 1, - role_receiver } role_e; // The various roles supported by this sketch -const char* role_friendly_name[] = { "invalid", "Sender", "Receiver" }; // The debug-friendly names of those roles -role_e role; // The role of the current running sketch - - -void setup() { - - pinMode(role_pin, INPUT); // set up the role pin - digitalWrite(role_pin, HIGH); // Change this to LOW/HIGH instead of using an external pin - delay(20); // Just to get a solid reading on the role pin - - if (digitalRead(role_pin)) // read the role_pin pin to establish our role - role = role_sender; - else - role = role_receiver; - - - Serial.begin(115200); - printf_begin(); // needed for printDetails() - - // print introduction - Serial.print(F("\n\rRF24/examples/pingpair_irq\n\rROLE: ")); - Serial.println(role_friendly_name[role]); - - - /********************** Setup and configure rf radio *********************/ - radio.begin(); - - // Examples are usually run with both radios in close proximity to each other - radio.setPALevel(RF24_PA_LOW); // defaults to RF24_PA_MAX - radio.enableAckPayload(); // We will be using the ACK Payload feature which is not enabled by default - radio.enableDynamicPayloads(); // Ack payloads are dynamic payloads - - // Open a writing and reading pipe on each radio, with opposite addresses - if (role == role_sender) { - radio.openWritingPipe(address[0]); - radio.openReadingPipe(1, address[1]); - } else { - radio.openWritingPipe(address[1]); - radio.openReadingPipe(1, address[0]); - radio.startListening(); // First we need to start listening - - // Add an ACK payload for the first time around; 1 is the pipe number to acknowledge - radio.writeAckPayload(1, &message_count, sizeof(message_count)); - ++message_count; // increment counter by 1 for next ACK payload - } - - radio.printDetails(); // Dump the configuration of the rf unit for debugging - delay(50); - - // Attach interrupt handler to interrupt #0 (using pin 2) on BOTH the sender and receiver - attachInterrupt(0, check_radio, LOW); -} // setup - - -void loop() { - - - /****************** Ping Out Role ***************************/ - - if (role == role_sender) { - // Repeatedly send the current time - - unsigned long time = millis(); // Take the time - Serial.print(F("Now sending ")); - Serial.println(time); - radio.startWrite(&time, sizeof(unsigned long), 0); // Send the time - delay(2000); // Try again soon (in 2 seconds) - } - - - /****************** Pong Back Role ***************************/ - // Receiver does nothing! All the work is in Interrupt Handler - - if (role == role_receiver) {} - -} // loop - - -/********************** Interrupt Handler *********************/ - -void check_radio(void) { - - bool tx, fail, rx; // declare variables to store IRQ flags - radio.whatHappened(tx, fail, rx); // What happened? - - if (tx) { // Have we successfully transmitted? - if (role == role_sender) - Serial.println(F("Send:OK")); - if (role == role_receiver) - Serial.println(F("Ack Payload:Sent")); - } - - if (fail) { // Have we failed to transmit? - if (role == role_sender) - Serial.println(F("Send:Failed")); - if (role == role_receiver) - Serial.println(F("Ack Payload:Failed")); - } - - if (rx || radio.available()) { // Did we receive a message? - - - - - /**************** Ping Out Role (about received ACK payload) ************************/ - // If we're the sender, we've received an ack payload - if (role == role_sender) { - // Get the payload and dump it - radio.read(&message_count, sizeof(message_count)); - Serial.print(F("Ack: ")); - Serial.println(message_count); - } - - - /****************** Pong Back Role ***************************/ - // If we're the receiver, we've received a time message - if (role == role_receiver) { - // Get the payload and dump it - - static unsigned long got_time; // variable to hold the received time - radio.read(&got_time, sizeof(got_time)); // get the payload - Serial.print(F("Got payload ")); - Serial.println(got_time); - - // Add an ACK payload for the next time around; 1 is the pipe number to acknowledge - radio.writeAckPayload(1, &message_count, sizeof(message_count)); - ++message_count; // increment packet counter - } - } -} // check_radio diff --git a/RF24/examples/old_backups/pingpair_multi_dyn/pingpair_multi_dyn.ino b/RF24/examples/old_backups/pingpair_multi_dyn/pingpair_multi_dyn.ino deleted file mode 100644 index 8e328795bef64b3575b42da583f1cef323ec35eb..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/pingpair_multi_dyn/pingpair_multi_dyn.ino +++ /dev/null @@ -1,252 +0,0 @@ -/* - Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. -*/ - -/** - Example using Dynamic Payloads - - This is an example of how to use payloads of a varying (dynamic) size. -*/ - -#include <SPI.h> -#include "RF24.h" - -// -// Hardware configuration -// - -// Set up nRF24L01 radio on SPI bus plus pins 8 & 9 -RF24 radio(7, 8); - -// Use multicast? -// sets the multicast behavior this unit in hardware. Connect to GND to use unicast -// Leave open (default) to use multicast. -const int multicast_pin = 6; - -// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver -// Leave open to be the 'ping' transmitter -const int role_pin = 5; -bool multicast = true; - -// -// Topology -// - -// Radio pipe addresses for the 2 nodes to communicate. -const uint64_t pipes[2] = { 0xEEFAFDFDEELL, 0xEEFDFAF50DFLL }; - -// -// Role management -// -// Set up role. This sketch uses the same software for all the nodes -// in this system. Doing so greatly simplifies testing. The hardware itself specifies -// which node it is. -// -// This is done through the role_pin -// - -// The various roles supported by this sketch -typedef enum { role_ping_out = 1, - role_pong_back } role_e; - -// The debug-friendly names of those roles -const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back" }; - -// The role of the current running sketch -role_e role; - -// -// Payload -// - -const int min_payload_size = 1; -const int max_payload_size = 32; -const int payload_size_increments_by = 1; -int next_payload_size = min_payload_size; - -char receive_payload[max_payload_size + 1]; // +1 to allow room for a terminating NULL char - -void setup(void) { - // - // Multicast - // - pinMode(multicast_pin, INPUT); - digitalWrite(multicast_pin, HIGH); - delay(20); - - // read multicast role, LOW for unicast - if (digitalRead(multicast_pin)) - multicast = true; - else - multicast = false; - - - // - // Role - // - - // set up the role pin - pinMode(role_pin, INPUT); - digitalWrite(role_pin, HIGH); - delay(20); // Just to get a solid reading on the role pin - - // read the address pin, establish our role - if (digitalRead(role_pin)) - role = role_ping_out; - else - role = role_pong_back; - - // - // Print preamble - // - - Serial.begin(115200); - - Serial.println(F("RF24/examples/pingpair_multi_dyn/")); - Serial.print(F("ROLE: ")); - Serial.println(role_friendly_name[role]); - - Serial.print(F("MULTICAST: ")); - Serial.println(multicast ? F("true (unreliable)") : F("false (reliable)")); - - // - // Setup and configure rf radio - // - - radio.begin(); - - // enable dynamic payloads - radio.enableDynamicPayloads(); - radio.setCRCLength(RF24_CRC_16); - - // optionally, increase the delay between retries & # of retries - radio.setRetries(15, 5); - radio.setAutoAck(true); - //radio.setPALevel( RF24_PA_LOW ) ; - - // - // Open pipes to other nodes for communication - // - - // This simple sketch opens two pipes for these two nodes to communicate - // back and forth. - // Open 'our' pipe for writing - // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) - - if (role == role_ping_out) { - radio.openWritingPipe(pipes[0]); - radio.openReadingPipe(1, pipes[1]); - } else { - radio.openWritingPipe(pipes[1]); - radio.openReadingPipe(1, pipes[0]); - } - - // - // Start listening - // - radio.powerUp(); - radio.startListening(); - - // - // Dump the configuration of the rf unit for debugging - // - - radio.printDetails(); -} - -void loop(void) { - // - // Ping out role. Repeatedly send the current time - // - - if (role == role_ping_out) { - // The payload will always be the same, what will change is how much of it we send. - static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012"; - - // First, stop listening so we can talk. - radio.stopListening(); - - // Take the time, and send it. This will block until complete - Serial.print(F("Now sending length ")); - Serial.println(next_payload_size); - radio.write(send_payload, next_payload_size, multicast); - - // Now, continue listening - radio.startListening(); - - // Wait here until we get a response, or timeout - unsigned long started_waiting_at = millis(); - bool timeout = false; - while (!radio.available() && !timeout) - if (millis() - started_waiting_at > 500) - timeout = true; - - // Describe the results - if (timeout) { - Serial.println(F("Failed, response timed out.")); - } else { - // Grab the response, compare, and send to debugging spew - uint8_t len = radio.getDynamicPayloadSize(); - radio.read(receive_payload, len); - - // Put a zero at the end for easy printing - receive_payload[len] = 0; - - // Spew it - Serial.print(F("Got response size=")); - Serial.print(len); - Serial.print(F(" value=")); - Serial.println(receive_payload); - } - - // Update size for next time. - next_payload_size += payload_size_increments_by; - if (next_payload_size > max_payload_size) - next_payload_size = min_payload_size; - - // Try again 1s later - delay(250); - } - - // - // Pong back role. Receive each packet, dump it out, and send it back - // - - if (role == role_pong_back) { - // if there is data ready - if (radio.available()) { - // Dump the payloads until we've gotten everything - uint8_t len; - bool done = false; - while (radio.available()) { - // Fetch the payload, and see if this was the last one. - len = radio.getDynamicPayloadSize(); - radio.read(receive_payload, len); - - // Put a zero at the end for easy printing - receive_payload[len] = 0; - - // Spew it - Serial.print(F("Got response size=")); - Serial.print(len); - Serial.print(F(" value=")); - Serial.println(receive_payload); - } - - // First, stop listening so we can talk - radio.stopListening(); - - // Send the final one back. - radio.write(receive_payload, len, multicast); - Serial.println(F("Sent response.")); - - // Now, resume listening so we catch the next packets. - radio.startListening(); - } - } -} -// vim:cin:ai:sts=2 sw=2 ft=cpp diff --git a/RF24/examples/old_backups/pingpair_sleepy/pingpair_sleepy.ino b/RF24/examples/old_backups/pingpair_sleepy/pingpair_sleepy.ino deleted file mode 100644 index c3beec8cd0909a7ce204927d3bb88172f51738ce..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/pingpair_sleepy/pingpair_sleepy.ino +++ /dev/null @@ -1,231 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - - TMRh20 2014 - Updates to the library allow sleeping both in TX and RX modes: - TX Mode: The radio can be powered down (.9uA current) and the Arduino slept using the watchdog timer - RX Mode: The radio can be left in standby mode (22uA current) and the Arduino slept using an interrupt pin -*/ - -/** - Example RF Radio Ping Pair which Sleeps between Sends - - This is an example of how to use the RF24 class to create a battery- - efficient system. It is just like the GettingStarted_CallResponse example, but the - ping node powers down the radio and sleeps the MCU after every - ping/pong cycle, and the receiver sleeps between payloads. - - Write this sketch to two different nodes, - connect the role_pin to ground on one. The ping node sends the current - time to the pong node, which responds by sending the value back. The ping - node can then see how long the whole cycle took. -*/ - -#include <SPI.h> -#include <avr/sleep.h> -#include <avr/power.h> -#include "nRF24L01.h" -#include "RF24.h" -#include "printf.h" - - -// Set up nRF24L01 radio on SPI bus plus pins 7 & 8 -RF24 radio(7, 8); - -// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver -// Leave open to be the 'ping' transmitter -const int role_pin = 5; - -const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; // Radio pipe addresses for the 2 nodes to communicate. - -// Role management -// Set up role. This sketch uses the same software for all the nodes -// in this system. Doing so greatly simplifies testing. The hardware itself specifies -// which node it is. - -// The various roles supported by this sketch -typedef enum { role_ping_out = 1, - role_pong_back } role_e; - -// The debug-friendly names of those roles -const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back" }; - -// The role of the current running sketch -role_e role; - - -// Sleep declarations -typedef enum { wdt_16ms = 0, - wdt_32ms, - wdt_64ms, - wdt_128ms, - wdt_250ms, - wdt_500ms, - wdt_1s, - wdt_2s, - wdt_4s, - wdt_8s } wdt_prescalar_e; - -void setup_watchdog(uint8_t prescalar); -void do_sleep(void); - -const short sleep_cycles_per_transmission = 4; -volatile short sleep_cycles_remaining = sleep_cycles_per_transmission; - - - -void setup() { - - // set up the role pin - pinMode(role_pin, INPUT); - digitalWrite(role_pin, HIGH); - delay(20); // Just to get a solid reading on the role pin - - // read the address pin, establish our role - if (digitalRead(role_pin)) - role = role_ping_out; - else - role = role_pong_back; - - Serial.begin(115200); - printf_begin(); - Serial.print(F("\n\rRF24/examples/pingpair_sleepy/\n\rROLE: ")); - Serial.println(role_friendly_name[role]); - - // Prepare sleep parameters - // Only the ping out role uses WDT. Wake up every 4s to send a ping - //if ( role == role_ping_out ) - setup_watchdog(wdt_4s); - - // Setup and configure rf radio - - radio.begin(); - - // Open pipes to other nodes for communication - - // This simple sketch opens two pipes for these two nodes to communicate - // back and forth. - // Open 'our' pipe for writing - // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) - - if (role == role_ping_out) { - radio.openWritingPipe(pipes[0]); - radio.openReadingPipe(1, pipes[1]); - } else { - radio.openWritingPipe(pipes[1]); - radio.openReadingPipe(1, pipes[0]); - } - - // Start listening - radio.startListening(); - - // Dump the configuration of the rf unit for debugging - //radio.printDetails(); -} - -void loop() { - - - if (role == role_ping_out) { // Ping out role. Repeatedly send the current time - radio.powerUp(); // Power up the radio after sleeping - radio.stopListening(); // First, stop listening so we can talk. - - unsigned long time = millis(); // Take the time, and send it. - Serial.print(F("Now sending... ")); - Serial.println(time); - - radio.write(&time, sizeof(unsigned long)); - - radio.startListening(); // Now, continue listening - - unsigned long started_waiting_at = millis(); // Wait here until we get a response, or timeout (250ms) - bool timeout = false; - while (!radio.available()) { - if (millis() - started_waiting_at > 250) { // Break out of the while loop if nothing available - timeout = true; - break; - } - } - - if (timeout) { // Describe the results - Serial.println(F("Failed, response timed out.")); - } else { - unsigned long got_time; // Grab the response, compare, and send to debugging spew - radio.read(&got_time, sizeof(unsigned long)); - - printf("Got response %lu, round-trip delay: %lu\n\r", got_time, millis() - got_time); - } - - // Shut down the system - delay(500); // Experiment with some delay here to see if it has an effect - // Power down the radio. - radio.powerDown(); // NOTE: The radio MUST be powered back up again manually - - // Sleep the MCU. - do_sleep(); - } - - - // Pong back role. Receive each packet, dump it out, and send it back - if (role == role_pong_back) { - - if (radio.available()) { // if there is data ready - - unsigned long got_time; - while (radio.available()) { // Dump the payloads until we've gotten everything - radio.read(&got_time, sizeof(unsigned long)); // Get the payload, and see if this was the last one. - // Spew it. Include our time, because the ping_out millis counter is unreliable - printf("Got payload %lu @ %lu...", got_time, millis()); // due to it sleeping - } - - radio.stopListening(); // First, stop listening so we can talk - radio.write(&got_time, sizeof(unsigned long)); // Send the final one back. - Serial.println(F("Sent response.")); - radio.startListening(); // Now, resume listening so we catch the next packets. - } else { - Serial.println(F("Sleeping")); - delay(50); // Delay so the serial data can print out - do_sleep(); - } - } -} - -void wakeUp() { - sleep_disable(); -} - -// Sleep helpers - -//Prescaler values -// 0=16ms, 1=32ms,2=64ms,3=125ms,4=250ms,5=500ms -// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec - -void setup_watchdog(uint8_t prescalar) { - - uint8_t wdtcsr = prescalar & 7; - if (prescalar & 8) - wdtcsr |= _BV(WDP3); - MCUSR &= ~_BV(WDRF); // Clear the WD System Reset Flag - WDTCSR = _BV(WDCE) | _BV(WDE); // Write the WD Change enable bit to enable changing the prescaler and enable system reset - WDTCSR = _BV(WDCE) | wdtcsr | _BV(WDIE); // Write the prescalar bits (how long to sleep, enable the interrupt to wake the MCU -} - -ISR(WDT_vect) { - //--sleep_cycles_remaining; - Serial.println(F("WDT")); -} - -void do_sleep(void) { - set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here - sleep_enable(); - attachInterrupt(0, wakeUp, LOW); - WDTCSR |= _BV(WDIE); - sleep_mode(); // System sleeps here - // The WDT_vect interrupt wakes the MCU from here - sleep_disable(); // System continues execution here when watchdog timed out - detachInterrupt(0); - WDTCSR &= ~_BV(WDIE); -} diff --git a/RF24/examples/old_backups/recipes/led_remote/led_remote.ino b/RF24/examples/old_backups/recipes/led_remote/led_remote.ino deleted file mode 100644 index 6ec865e9c95aa9781edd09dd6623bf456b9b9651..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/recipes/led_remote/led_remote.ino +++ /dev/null @@ -1,236 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. -*/ - -/** - Example LED Remote - - This is an example of how to use the RF24 class to control a remote - bank of LED's using buttons on a remote control. - - On the 'remote', connect any number of buttons or switches from - an arduino pin to ground. Update 'button_pins' to reflect the - pins used. - - On the 'led' board, connect the same number of LED's from an - arduino pin to a resistor to ground. Update 'led_pins' to reflect - the pins used. Also connect a separate pin to ground and change - the 'role_pin'. This tells the sketch it's running on the LED board. - - Every time the buttons change on the remote, the entire state of - buttons is send to the led board, which displays the state. -*/ - -#include <SPI.h> -#include "nRF24L01.h" -#include "RF24.h" -#include "printf.h" - -// -// Hardware configuration -// - -// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 (CE & CS) - -RF24 radio(9, 10); - -// sets the role of this unit in hardware. Connect to GND to be the 'led' board receiver -// Leave open to be the 'remote' transmitter -const int role_pin = A4; - -// Pins on the remote for buttons -const uint8_t button_pins[] = { 2, 3, 4, 5, 6, 7 }; -const uint8_t num_button_pins = sizeof(button_pins); - -// Pins on the LED board for LED's -const uint8_t led_pins[] = { 2, 3, 4, 5, 6, 7 }; -const uint8_t num_led_pins = sizeof(led_pins); - -// -// Topology -// - -// Single radio pipe address for the 2 nodes to communicate. -const uint64_t pipe = 0xE8E8F0F0E1LL; - -// -// Role management -// -// Set up role. This sketch uses the same software for all the nodes in this -// system. Doing so greatly simplifies testing. The hardware itself specifies -// which node it is. -// -// This is done through the role_pin -// - -// The various roles supported by this sketch -typedef enum { role_remote = 1, - role_led } role_e; - -// The debug-friendly names of those roles -const char* role_friendly_name[] = { "invalid", "Remote", "LED Board" }; - -// The role of the current running sketch -role_e role; - -// -// Payload -// - -uint8_t button_states[num_button_pins]; -uint8_t led_states[num_led_pins]; - -// -// Setup -// - -void setup(void) { - // - // Role - // - - // set up the role pin - pinMode(role_pin, INPUT); - digitalWrite(role_pin, HIGH); - delay(20); // Just to get a solid reading on the role pin - - // read the address pin, establish our role - if (digitalRead(role_pin)) - role = role_remote; - else - role = role_led; - - // - // Print preamble - // - - Serial.begin(115200); - printf_begin(); - printf("\n\rRF24/examples/led_remote/\n\r"); - printf("ROLE: %s\n\r", role_friendly_name[role]); - - // - // Setup and configure rf radio - // - - radio.begin(); - - // - // Open pipes to other nodes for communication - // - - // This simple sketch opens a single pipes for these two nodes to communicate - // back and forth. One listens on it, the other talks to it. - - if (role == role_remote) { - radio.openWritingPipe(pipe); - } else { - radio.openReadingPipe(1, pipe); - } - - // - // Start listening - // - - if (role == role_led) - radio.startListening(); - - // - // Dump the configuration of the rf unit for debugging - // - - radio.printDetails(); - - // - // Set up buttons / LED's - // - - // Set pull-up resistors for all buttons - if (role == role_remote) { - int i = num_button_pins; - while (i--) { - pinMode(button_pins[i], INPUT); - digitalWrite(button_pins[i], HIGH); - } - } - - // Turn LED's ON until we start getting keys - if (role == role_led) { - int i = num_led_pins; - while (i--) { - pinMode(led_pins[i], OUTPUT); - led_states[i] = HIGH; - digitalWrite(led_pins[i], led_states[i]); - } - } -} - -// -// Loop -// - -void loop(void) { - // - // Remote role. If the state of any button has changed, send the whole state of - // all buttons. - // - - if (role == role_remote) { - // Get the current state of buttons, and - // Test if the current state is different from the last state we sent - int i = num_button_pins; - bool different = false; - while (i--) { - uint8_t state = !digitalRead(button_pins[i]); - if (state != button_states[i]) { - different = true; - button_states[i] = state; - } - } - - // Send the state of the buttons to the LED board - if (different) { - printf("Now sending..."); - bool ok = radio.write(button_states, num_button_pins); - if (ok) - printf("ok\n\r"); - else - printf("failed\n\r"); - } - - // Try again in a short while - delay(20); - } - - // - // LED role. Receive the state of all buttons, and reflect that in the LEDs - // - - if (role == role_led) { - // if there is data ready - if (radio.available()) { - // Dump the payloads until we've gotten everything - while (radio.available()) { - // Fetch the payload, and see if this was the last one. - radio.read(button_states, num_button_pins); - - // Spew it - printf("Got buttons\n\r"); - - // For each button, if the button now on, then toggle the LED - int i = num_led_pins; - while (i--) { - if (button_states[i]) { - led_states[i] ^= HIGH; - digitalWrite(led_pins[i], led_states[i]); - } - } - } - } - } -} -// vim:ai:cin:sts=2 sw=2 ft=cpp diff --git a/RF24/examples/old_backups/recipes/nordic_fob/nordic_fob.ino b/RF24/examples/old_backups/recipes/nordic_fob/nordic_fob.ino deleted file mode 100644 index 894d9266ab42dc0c647569e65337aa9ee481d8bc..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/recipes/nordic_fob/nordic_fob.ino +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright (C) 2012 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. -*/ - -/** - Example Nordic FOB Receiver - - This is an example of how to use the RF24 class to receive signals from the - Sparkfun Nordic FOB. Thanks to Kirk Mower for providing test hardware. - - See blog post at http://maniacbug.wordpress.com/2012/01/08/nordic-fob/ -*/ - -#include <SPI.h> -#include <RF24.h> -#include "nRF24L01.h" -#include "printf.h" - -// -// Hardware configuration -// - -// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 - -RF24 radio(9, 10); - -// -// Payload -// - -struct payload_t { - uint8_t buttons; - uint16_t id; - uint8_t empty; -}; - -const char* button_names[] = { "Up", "Down", "Left", "Right", "Center" }; -const int num_buttons = 5; - -// -// Forward declarations -// - -uint16_t flip_endian(uint16_t in); - -// -// Setup -// - -void setup(void) { - // - // Print preamble - // - - Serial.begin(115200); - printf_begin(); - printf("\r\nRF24/examples/nordic_fob/\r\n"); - - // - // Setup and configure rf radio according to the built-in parameters - // of the FOB. - // - - radio.begin(); - radio.setChannel(2); - radio.setPayloadSize(4); - radio.setAutoAck(false); - radio.setCRCLength(RF24_CRC_8); - radio.openReadingPipe(1, 0xE7E7E7E7E7LL); - - // - // Start listening - // - - radio.startListening(); - - // - // Dump the configuration of the rf unit for debugging - // - - radio.printDetails(); -} - -// -// Loop -// - -void loop(void) { - // - // Receive each packet, dump it out - // - - // if there is data ready - if (radio.available()) { - // Get the packet from the radio - payload_t payload; - radio.read(&payload, sizeof(payload)); - - // Print the ID of this message. Note that the message - // is sent 'big-endian', so we have to flip it. - printf("#%05u Buttons ", flip_endian(payload.id)); - - // Print the name of each button - int i = num_buttons; - while (i--) { - if (!(payload.buttons & _BV(i))) { - printf("%s ", button_names[i]); - } - } - - // If no buttons, print None - if (payload.buttons == _BV(num_buttons) - 1) - printf("None"); - - printf("\r\n"); - } -} - -// -// Helper functions -// - -// Change a big-endian word into a little-endian -uint16_t flip_endian(uint16_t in) { - uint16_t low = in >> 8; - uint16_t high = in << 8; - - return high | low; -} - -// vim:cin:ai:sts=2 sw=2 ft=cpp diff --git a/RF24/examples/old_backups/recipes/pingpair_maple/main.cpp b/RF24/examples/old_backups/recipes/pingpair_maple/main.cpp deleted file mode 100644 index be3ea983a712a45be508ccb91910831404f76223..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/recipes/pingpair_maple/main.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifdef MAPLE_IDE - -#include <stdio.h> -#include "wirish.h" - -extern void setup(void); -extern void loop(void); - -void board_start(const char* program_name) { - // Set up the LED to steady on - pinMode(BOARD_LED_PIN, OUTPUT); - digitalWrite(BOARD_LED_PIN, HIGH); - - // Setup the button as input - pinMode(BOARD_BUTTON_PIN, INPUT); - digitalWrite(BOARD_BUTTON_PIN, HIGH); - - SerialUSB.begin(); - SerialUSB.println("Press BUT"); - - // Wait for button press - while (!isButtonPressed()) { - } - - SerialUSB.println("Welcome!"); - SerialUSB.println(program_name); - - int i = 11; - while (i--) { - toggleLED(); - delay(50); - } -} - -/** - Custom version of _write, which will print to the USB. - In order to use it you MUST ADD __attribute__((weak)) - to _write in libmaple/syscalls.c -*/ -extern "C" int _write(int file, char* ptr, int len) { - if ((file != 1) && (file != 2)) - return 0; - else - SerialUSB.write(ptr, len); - return len; -} - -/** - Re-entrant version of _write. Yagarto and Devkit now use - the re-entrant newlib, so these get called instead of the - non_r versions. -*/ -extern "C" int _write_r(void*, int file, char* ptr, int len) { - return _write(file, ptr, len); -} - -__attribute__((constructor)) __attribute__((weak)) void premain() { - init(); -} - -__attribute__((weak)) void setup(void) { - board_start("No program defined"); -} - -__attribute__((weak)) void loop(void) { -} - -__attribute__((weak)) int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} -#endif // ifdef MAPLE_IDE -// vim:cin:ai:sts=2 sw=2 ft=cpp diff --git a/RF24/examples/old_backups/recipes/pingpair_maple/pingpair_maple.ino b/RF24/examples/old_backups/recipes/pingpair_maple/pingpair_maple.ino deleted file mode 100644 index e1b0511ec85e48cc21d3cdf74de7ede5bc055f11..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/recipes/pingpair_maple/pingpair_maple.ino +++ /dev/null @@ -1,231 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. -*/ - -/** - Example RF Radio Ping Pair ... for Maple - - This is an example of how to use the RF24 class. Write this sketch to two different nodes, - connect the role_pin to ground on one. The ping node sends the current time to the pong node, - which responds by sending the value back. The ping node can then see how long the whole cycle - took. -*/ - -#include "WProgram.h" -#include <SPI.h> -#include "nRF24L01.h" -#include "RF24.h" - -// -// Maple specific setup. Other than this section, the sketch is the same on Maple as on -// Arduino -// - -#ifdef MAPLE_IDE - -// External startup function -extern void board_start(const char* program_name); - -// Use SPI #2. -HardwareSPI SPI(2); - -#else -#define board_startup printf -#define toggleLED(x) (x) -#endif - -// -// Hardware configuration -// - -// Set up nRF24L01 radio on SPI bus plus pins 7 & 6 -// (This works for the Getting Started board plugged into the -// Maple Native backwards.) - -RF24 radio(7, 6); - -// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver -// Leave open to be the 'ping' transmitter -const int role_pin = 10; - -// -// Topology -// - -// Radio pipe addresses for the 2 nodes to communicate. -const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; - -// -// Role management -// -// Set up role. This sketch uses the same software for all the nodes -// in this system. Doing so greatly simplifies testing. The hardware itself specifies -// which node it is. -// -// This is done through the role_pin -// - -// The various roles supported by this sketch -typedef enum { role_ping_out = 1, - role_pong_back } role_e; - -// The debug-friendly names of those roles -const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back" }; - -// The role of the current running sketch -role_e role; - -void setup(void) { - // - // Role - // - - // set up the role pin - pinMode(role_pin, INPUT); - digitalWrite(role_pin, HIGH); - delay(20); // Just to get a solid reading on the role pin - - // read the address pin, establish our role - if (digitalRead(role_pin)) - role = role_ping_out; - else - role = role_pong_back; - - // - // Print preamble - // - - board_start("\n\rRF24/examples/pingpair/\n\r"); - printf("ROLE: %s\n\r", role_friendly_name[role]); - - // - // Setup and configure rf radio - // - - radio.begin(); - - // optionally, increase the delay between retries & # of retries - radio.setRetries(15, 15); - - // optionally, reduce the payload size. seems to - // improve reliability - radio.setPayloadSize(8); - - // - // Open pipes to other nodes for communication - // - - // This simple sketch opens two pipes for these two nodes to communicate - // back and forth. - // Open 'our' pipe for writing - // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) - - if (role == role_ping_out) { - radio.openWritingPipe(pipes[0]); - radio.openReadingPipe(1, pipes[1]); - } else { - radio.openWritingPipe(pipes[1]); - radio.openReadingPipe(1, pipes[0]); - } - - // - // Start listening - // - - radio.startListening(); - - // - // Dump the configuration of the rf unit for debugging - // - - radio.printDetails(); -} - -void loop(void) { - // - // Ping out role. Repeatedly send the current time - // - - if (role == role_ping_out) { - toggleLED(); - - // First, stop listening so we can talk. - radio.stopListening(); - - // Take the time, and send it. This will block until complete - unsigned long time = millis(); - printf("Now sending %lu...", time); - bool ok = radio.write(&time, sizeof(unsigned long)); - - if (ok) - printf("ok...\r\n"); - else - printf("failed.\r\n"); - - // Now, continue listening - radio.startListening(); - - // Wait here until we get a response, or timeout (250ms) - unsigned long started_waiting_at = millis(); - bool timeout = false; - while (!radio.available() && !timeout) - if (millis() - started_waiting_at > 200) - timeout = true; - - // Describe the results - if (timeout) { - printf("Failed, response timed out.\r\n"); - } else { - // Grab the response, compare, and send to debugging spew - unsigned long got_time; - radio.read(&got_time, sizeof(unsigned long)); - - // Spew it - printf("Got response %lu, round-trip delay: %lu\r\n", got_time, millis() - got_time); - } - - toggleLED(); - - // Try again 1s later - delay(1000); - } - - // - // Pong back role. Receive each packet, dump it out, and send it back - // - - if (role == role_pong_back) { - // if there is data ready - if (radio.available()) { - // Dump the payloads until we've gotten everything - unsigned long got_time; - bool done = false; - while (!done) { - // Fetch the payload, and see if this was the last one. - done = radio.read(&got_time, sizeof(unsigned long)); - - // Spew it - printf("Got payload %lu...", got_time); - - // Delay just a little bit to let the other unit - // make the transition to receiver - delay(20); - } - - // First, stop listening so we can talk - radio.stopListening(); - - // Send the final one back. - radio.write(&got_time, sizeof(unsigned long)); - printf("Sent response.\r\n"); - - // Now, resume listening so we catch the next packets. - radio.startListening(); - } - } -} -// vim:cin:ai:sts=2 sw=2 ft=cpp diff --git a/RF24/examples/old_backups/recipes/readme.md b/RF24/examples/old_backups/recipes/readme.md deleted file mode 100644 index 76c42736a4216c0695b37a9d3fed6102b4c81b3f..0000000000000000000000000000000000000000 --- a/RF24/examples/old_backups/recipes/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -Note: These recipe examples may have not been maintained with library updates, and are provided as-is for reference purposes. -Warning: These are recipe examples are intended for specific hardware usage. \ No newline at end of file diff --git a/RF24/examples/rf24_ATTiny/rf24ping85/rf24ping85.ino b/RF24/examples/rf24_ATTiny/rf24ping85/rf24ping85.ino deleted file mode 100644 index 4c5faf388b81319d295b6f86d6a3c85203f29d9a..0000000000000000000000000000000000000000 --- a/RF24/examples/rf24_ATTiny/rf24ping85/rf24ping85.ino +++ /dev/null @@ -1,204 +0,0 @@ -/** - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * written in 2014 by tong67 (https://github.com/tong67) - * Updated 2020 by 2bndy5 (http://github.com/2bndy5) for the - * SpenceKonde ATTinyCore (https://github.com/SpenceKonde/ATTinyCore) - */ - -/** - * The RF24 library uses the [ATTinyCore by - * SpenceKonde](https://github.com/SpenceKonde/ATTinyCore) - * - * This sketch is a duplicate of the ManualAcknowledgements.ino example - * (without all the Serial input/output code), and it demonstrates - * a ATTiny25/45/85 or ATTiny24/44/84 driving the nRF24L01 transceiver using - * the RF24 class to communicate with another node. - * - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. - * This example still uses ACK packets, but they have no payloads. Instead the - * acknowledging response is sent with `write()`. This tactic allows for more - * updated acknowledgement payload data, where actual ACK payloads' data are - * outdated by 1 transmission because they have to loaded before receiving a - * transmission. - * - * This example was written to be used on 2 devices acting as "nodes". - */ - -/* - * ********** Hardware configuration (& schematics) ******************* - * - * When direct use of 3V does not work (UNO boards tend to have poor 3V supply), - * use 5V with LED (1.8V ~ 2.2V drop) instead. - * For low power consumption solutions floating pins (SCK and MOSI) should be - * pulled HIGH or LOW with 10K resistors. - * - * ATTiny25/45/85 Pin map with CE_PIN 3 and CSN_PIN 4 - * ^^ - * +-\/-+ // - * PB5 1|o |8 Vcc --- nRF24L01 VCC --- |<|--- 5V - * nRF24L01 CE --- PB3 2| |7 PB2 --- nRF24L01 SCK LED - * nRF24L01 CSN --- PB4 3| |6 PB1 --- nRF24L01 MOSI - * nRF24L01 GND --- GND 4| |5 PB0 --- nRF24L01 MISO - * +----+ - * - * ATTiny25/45/85 Pin map with CE_PIN 3 and CSN_PIN 3 => PB3 and PB4 are - * free to use for other purposes. This "3 pin solution" is from - * Ralph Doncaster (AKA NerdRalph) which is outlined on his blog at - * http://nerdralph.blogspot.ca/2014/01/nrf24l01-control-with-3-attiny85-pins.html - * Original RC combination was 1K/100nF. 22K/10nF combination worked better. - * - * For best settle time delay value to use for RF24::csDelay in RF24::csn(), use - * the examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino sketch. - * - * This configuration is enabled in the RF24 library when CE_PIN and - * CSN_PIN parameters to the constructor are equal. Notice (in the schematic - * below) that these pins aren't directly to the ATTiny85. Because the CE pin - * is always HIGH, the power consumption is higher than it would be for the - * typical 5 pins solution. - * ^^ - * +-\/-+ nRF24L01 CE --------| // - * PB5 1|o |8 Vcc --- nRF24L01 VCC -------x----------x--|<|-- 5V - * PB3 2| |7 PB2 --- nRF24L01 SCK ---|<|---x-[22k]--| LED - * PB4 3| |6 PB1 --- nRF24L01 MOSI 1n4148 | - * nRF24L01 GND -x- GND 4| |5 PB0 --- nRF24L01 MISO | - * | +----+ | - * |-----------------------------------------||----x-- nRF24L01 CSN - * 10nF - * - * ATTiny24/44/84 Pin map with CE_PIN 8 and CSN_PIN 7 & assuming 1.9V to 3V on VCC - * Schematic provided and successfully tested by - * Carmine Pastore (https://github.com/Carminepz) - * - * +-\/-+ - * nRF24L01 VCC ---- VCC 1|o |14 GND --- nRF24L01 GND - * PB0 2| |13 AREF - * PB1 3| |12 PA1 - * PB3 4| |11 PA2 --- nRF24L01 CE - * PB2 5| |10 PA3 --- nRF24L01 CSN - * PA7 6| |9 PA4 --- nRF24L01 SCK - * nRF24L01 MOSI --- PA6 7| |8 PA5 --- nRF24L01 MISO - * +----+ - */ - -#include "SPI.h" -#include "RF24.h" - -// CE and CSN are configurable, specified values for ATTiny85 as connected above -#define CE_PIN 3 -#define CSN_PIN 4 -//#define CSN_PIN 3 // uncomment for ATTiny85 3 pins solution - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(CE_PIN, CSN_PIN); - -// Let these addresses be used for the pair -uint8_t address[][6] = { "1Node", "2Node" }; -// It is very helpful to think of an address as a path instead of as -// an identifying device destination - -// to use different addresses on a pair of radios, we need a variable to -// uniquely identify which address this radio will use to transmit -bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX node, false = RX node - -// For this example, we'll be using a payload containing -// a string & an integer number that will be incremented -// on every successful transmission. -// Make a data structure to store the entire payload of different datatypes -struct PayloadStruct { - char message[7]; // only using 6 characters for TX & RX payloads - uint8_t counter; -}; -PayloadStruct payload; - -void setup() { - - // append a NULL terminating character for printing as a c-string - payload.message[6] = 0; - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - while (1) {} // hold in infinite loop - } - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - if (role) { - // setup the TX node - - memcpy(payload.message, "Hello ", 6); // set the outgoing message - radio.stopListening(); // put radio in TX mode - } else { - // setup the RX node - - memcpy(payload.message, "World ", 6); // set the outgoing message - radio.startListening(); // put radio in RX mode - } -} // setup() - -void loop() { - - if (role) { - // This device is a TX node - - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - - if (report) { - // transmission successful; wait for response and print results - - radio.startListening(); // put in RX mode - unsigned long start_timeout = millis(); // timer to detect no response - while (!radio.available()) { // wait for response or timeout - if (millis() - start_timeout > 200) // only wait 200 ms - break; - } - radio.stopListening(); // put back in TX mode - - // print summary of transactions - if (radio.available()) { // is there a payload received? - - PayloadStruct received; - radio.read(&received, sizeof(received)); // get payload from RX FIFO - payload.counter = received.counter; // save incoming counter for next outgoing counter - } - } // report - - // to make this example readable in the serial monitor - delay(1000); // slow transmissions down by 1 second - - } else { - // This device is a RX node - - if (radio.available()) { // is there a payload? - - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming payload - payload.counter = received.counter + 1; // increment incoming counter for next outgoing response - - // transmit response & save result to `report` - radio.stopListening(); // put in TX mode - - radio.writeFast(&payload, sizeof(payload)); // load response to TX FIFO - radio.txStandBy(150); // keep retrying for 150 ms - - radio.startListening(); // put back in RX mode - } - } // role -} // loop diff --git a/RF24/examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino b/RF24/examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino deleted file mode 100644 index a7299bb828c17a27091ed86073086afe84d0b811..0000000000000000000000000000000000000000 --- a/RF24/examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino +++ /dev/null @@ -1,207 +0,0 @@ -/** - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * written by tong67 (https://github.com/tong67) - * edited by 2bndy5 (http://github.com/2bndy5) for compatibility with SpenceKonde's ATTinyCore - */ - -/* - * This sketch can determine the best settle time values to use for - * macros, defined as RF24_CSN_SETTLE_HIGH_DELAY and RF24_CSN_SETTLE_LOW_DELAY, - * in RF24::csn(). - * The settle time values used here are 100/20. However, these values depend - * on the actual used RC combiniation and voltage drop by LED. The - * intermediate results are written to TX (PB3, pin 2 -- using Serial). - * - * For schematic details, see introductory comment block in the - * examples/rf24_ATTiny/rf24ping85/rf24ping85.ino sketch. - */ - -#include <stdio.h> -#include <SPI.h> -#include <Arduino.h> -#include <nRF24L01.h> - - -#if defined(ARDUINO) && !defined(__arm__) -#if defined(__AVR_ATtinyX5__) || defined(__AVR_ATtinyX4__) -#define RF24_TINY -#endif -#endif - -/****************************************************************************/ - -#if defined(RF24_TINY) - -// when Attiny84 or Attiny85 is detected -#define CE_PIN 3 /** "Chip Enable" pin, activates the RX or TX role */ -#define CSN_PIN 3 /** SPI Chip Select Not */ - -#else -// when not running on an ATTiny84 or ATTiny85 -#define CE_PIN 7 /** "Chip Enable" pin, activates the RX or TX role */ -#define CSN_PIN 8 /** SPI Chip Select Not */ - -#endif - -#define MAX_HIGH 100 -#define MAX_LOW 100 -#define MINIMAL 8 - -// Use these adjustable variables to test for best configuration to be used on -// the ATTiny chips. These variables are defined as macros in the library's -// RF24/utility/ATTiny/RF24_arch_config.h file. To change them, simply define -// the corresponding macro(s) before #include <RF24> in your sketch. -uint8_t csnHighSettle = MAX_HIGH; // defined as RF24_CSN_SETTLE_HIGH_DELAY -uint8_t csnLowSettle = MAX_LOW; // defined as RF24_CSN_SETTLE_LOW_DELAY - -/****************************************************************************/ -void ce(bool level) { - if (CE_PIN != CSN_PIN) digitalWrite(CE_PIN, level); -} - -/****************************************************************************/ -void csn(bool mode) { - if (CE_PIN != CSN_PIN) { - digitalWrite(CSN_PIN, mode); - } else { - // digitalWrite(SCK, mode); - if (mode == HIGH) { - PORTB |= (1 << PINB2); // SCK->CSN HIGH - delayMicroseconds(csnHighSettle); // allow csn to settle - } else { - PORTB &= ~(1 << PINB2); // SCK->CSN LOW - delayMicroseconds(csnLowSettle); // allow csn to settle - } - } -} - -/****************************************************************************/ -uint8_t read_register(uint8_t reg) { - csn(LOW); - SPI.transfer(R_REGISTER | reg); - uint8_t result = SPI.transfer(0xff); - csn(HIGH); - return result; -} - -/****************************************************************************/ -void write_register(uint8_t reg, uint8_t value) { - csn(LOW); - SPI.transfer(W_REGISTER | reg); - SPI.transfer(value); - csn(HIGH); -} - -/****************************************************************************/ -void setup(void) { - -#ifndef __AVR_ATtinyX313__ - // not enough memory on ATTiny4313 or ATTint2313(a) to use Serial I/O for this sketch - - // start serial port and SPI - Serial.begin(115200); - SPI.begin(); - // configure CE and CSN as output when used - pinMode(CE_PIN, OUTPUT); - if (CSN_PIN != CE_PIN) - pinMode(CSN_PIN, OUTPUT); - - // csn is used in SPI transfers. Set to LOW at start and HIGH after transfer. Set to HIGH to reflect no transfer active - // SPI command are accepted in Power Down state. - // CE pin represent PRX (LOW) or PTX (HIGH) mode apart from register settings. Start in PRX mode. - ce(LOW); - csn(HIGH); - - // nRF24L01 goes from to Power Down state 100ms after Power on Reset ( Vdd > 1.9V) or when PWR_UP is 0 in config register - // Goto Power Down state (Powerup or force) and set in transmit mode - write_register(NRF_CONFIG, read_register(NRF_CONFIG) & ~_BV(PWR_UP) & ~_BV(PRIM_RX)); - delay(100); - - // Goto Standby-I - // Technically we require 4.5ms Tpd2stby+ 14us as a worst case. We'll just call it 5ms for good measure. - // WARNING: Delay is based on P-variant whereby non-P *may* require different timing. - write_register(NRF_CONFIG, read_register(NRF_CONFIG) | _BV(PWR_UP)); - delay(5); - - // Goto Standby-II - ce(HIGH); - Serial.print("Scanning for optimal setting time for csn"); - - - /************************** Main program *********************************/ - - uint8_t result; // used to compare read/write results with read/write cmds - bool success = true; - uint8_t bottom_success; - bool bottom_found; - uint8_t value[] = { 5, 10 }; - uint8_t limit[] = { MAX_HIGH, MAX_LOW }; - uint8_t advice[] = { MAX_HIGH, MAX_LOW }; - - // check max values give correct behavior - for (uint8_t k = 0; k < 2; k++) { - bottom_found = false; - bottom_success = 0; - while (bottom_success < 255) { - csnHighSettle = limit[0]; - csnLowSettle = limit[1]; - // check current values - uint8_t i = 0; - while (i < 255 && success) { - for (uint8_t j = 0; j < 2; j++) { - write_register(EN_AA, value[j]); - result = read_register(EN_AA); - if (value[j] != result) { - success = false; - } - } - i++; - } - // process result of current values - if (!success) { - Serial.print("Settle Not OK. csnHigh="); - Serial.print(limit[0], DEC); - Serial.print(" csnLow="); - Serial.println(limit[1], DEC); - limit[k]++; - bottom_found = true; - bottom_success = 0; - success = true; - } else { - Serial.print("Settle OK. csnHigh="); - Serial.print(limit[0], DEC); - Serial.print(" csnLow="); - Serial.println(limit[1], DEC); - if (!bottom_found) { - limit[k]--; - if (limit[k] == MINIMAL) { - bottom_found = true; - bottom_success = 0; - success = true; - } - } else { - bottom_success++; - } - } - } // while (bottom_success < 255) - Serial.print("Settle value found for "); - if (k == 0) { - Serial.print("csnHigh: "); - } else { - Serial.print("csnLow: "); - } - Serial.println(limit[k], DEC); - advice[k] = limit[k] + (limit[k] / 10); - limit[k] = 100; - } // for (uint8_t k = 0; k < 2; k++) - Serial.print("Advised Settle times are: csnHigh="); - Serial.print(advice[0], DEC); - Serial.print(" csnLow="); - Serial.println(advice[1], DEC); - -#endif // not defined __AVR_ATtinyX313__ -} - - -void loop(void) {} // this program runs only once, thus it resides in setup() diff --git a/RF24/examples/scanner/scanner.ino b/RF24/examples/scanner/scanner.ino deleted file mode 100644 index 79dabd9f718b263264b9688f0012a01acdd7fc32..0000000000000000000000000000000000000000 --- a/RF24/examples/scanner/scanner.ino +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - * Updated 2020 TMRh20 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ - -/** - * Channel scanner and Continuous Carrier Wave Output - * - * Example to detect interference on the various channels available. - * This is a good diagnostic tool to check whether you're picking a - * good channel for your application. - * - * Run this sketch on two devices. On one device, start CCW output by sending a 'g' - * character over Serial. The other device scanning should detect the output of the sending - * device on the given channel. Adjust channel and output power of CCW below. - * - * Inspired by cpixip. - * See http://arduino.cc/forum/index.php/topic,54795.0.html - */ - -#include "RF24.h" -#include "printf.h" - -// -// Hardware configuration -// - -// Set up nRF24L01 radio on SPI bus plus pins 7 & 8 - -RF24 radio(7, 8); - -// -// Channel info -// - -const uint8_t num_channels = 126; -uint8_t values[num_channels]; - -// -// Setup -// - -void setup(void) { - // - // Print preamble - // - - Serial.begin(115200); - printf_begin(); - Serial.println(F("\n\rRF24/examples/scanner/")); - - // - // Setup and configure rf radio - // - - radio.begin(); - radio.setAutoAck(false); - - // Get into standby mode - radio.startListening(); - radio.stopListening(); - radio.printDetails(); - - //delay(1000); - // Print out header, high then low digit - int i = 0; - while (i < num_channels) { - Serial.print(i >> 4, HEX); - ++i; - } - Serial.println(); - i = 0; - while (i < num_channels) { - Serial.print(i & 0xf, HEX); - ++i; - } - Serial.println(); - //delay(1000); -} - -// -// Loop -// - -const int num_reps = 100; -bool constCarrierMode = 0; - -void loop(void) { - /****************************************/ - // Send g over Serial to begin CCW output - // Configure the channel and power level below - if (Serial.available()) { - char c = Serial.read(); - if (c == 'g') { - constCarrierMode = 1; - radio.stopListening(); - delay(2); - Serial.println("Starting Carrier Out"); - radio.startConstCarrier(RF24_PA_LOW, 40); - } else if (c == 'e') { - constCarrierMode = 0; - radio.stopConstCarrier(); - Serial.println("Stopping Carrier Out"); - } - } - /****************************************/ - - if (constCarrierMode == 0) { - // Clear measurement values - memset(values, 0, sizeof(values)); - - // Scan all channels num_reps times - int rep_counter = num_reps; - while (rep_counter--) { - int i = num_channels; - while (i--) { - // Select this channel - radio.setChannel(i); - - // Listen for a little - radio.startListening(); - delayMicroseconds(128); - radio.stopListening(); - - // Did we get a carrier? - if (radio.testCarrier()) { - ++values[i]; - } - } - } - - - // Print out channel measurements, clamped to a single hex digit - int i = 0; - while (i < num_channels) { - if (values[i]) - Serial.print(min(0xf, values[i]), HEX); - else - Serial.print(F("-")); - - ++i; - } - Serial.println(); - - } //If constCarrierMode == 0 -} diff --git a/RF24/examples_linux/CMakeLists.txt b/RF24/examples_linux/CMakeLists.txt deleted file mode 100644 index 2a46b61f1817eba64515933b9a41061b5fe91283..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -# iterate over a list of examples by filename -set(EXAMPLES_LIST - gettingstarted - acknowledgementPayloads - manualAcknowledgements - streamingData - multiceiverDemo - scanner -) - -project(RF24Examples CXX) -add_compile_options(-Ofast -Wall) # passing the compiler a `-pthread` flag doesn't work here - -# detect the CPU make and type -include(../cmake/detectCPU.cmake) # sets the variable SOC accordingly - -# auto-detect what driver to use -# auto-detect can be overriden using `cmake .. -D RF24_DRIVER=<supported driver>` -include(../cmake/AutoConfig_RF24_DRIVER.cmake) - -find_library(RF24 rf24 REQUIRED) -message(STATUS "using RF24 library: ${RF24}") - -# conditionally append "interruptConfigure" to the EXAMPLES_LIST -if("${RF24_DRIVER}" STREQUAL "MRAA" OR "${RF24_DRIVER}" STREQUAL "wiringPi" OR "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND") - message(STATUS "Skipping interruptConfigure.cpp example as it is incompatible with selected driver library") -else() # not using MRAA or wiringPi drivers (or pigpio lib was found) - list(APPEND EXAMPLES_LIST interruptConfigure) -endif() - -foreach(example ${EXAMPLES_LIST}) - #make a target - add_executable(${example} ${example}.cpp) - - # avoid including interrupt.h when pigpio is not available - if("${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND") - target_compile_definitions(${example} PUBLIC RF24_NO_INTERRUPT) - endif() - - # link the RF24 lib to the target. Notice we specify pthread as a linked lib here - if("${RF24_DRIVER}" STREQUAL "MRAA") - target_link_libraries(${example} PUBLIC ${RF24} pthread ${LibMRAA}) - elseif("${RF24_DRIVER}" STREQUAL "wiringPi") - # wiringPi additionally needs to link to crypt and shm_open libraries - target_link_libraries(${example} PUBLIC ${RF24} pthread ${LibWiringPi} crypt rt) - elseif("${RF24_DRIVER}" STREQUAL "pigpio" OR NOT "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND") - # linking to pigpio requires pthread to be listed as last linked lib - target_link_libraries(${example} PUBLIC ${RF24} ${LibPIGPIO} pthread) - else() # not using MRAA or wiringPi drivers - target_link_libraries(${example} PUBLIC ${RF24} pthread) - endif() -endforeach() diff --git a/RF24/examples_linux/Makefile b/RF24/examples_linux/Makefile deleted file mode 100644 index bd9a7128718143ecbe1eadab9f8b16d31d502561..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -############################################################################# -# -# Makefile for librf24 examples on Linux -# -# License: GPL (General Public License) -# Author: gnulnulf <arco@appeltaart.mine.nu> -# Date: 2013/02/07 (version 1.0) -# -# Description: -# ------------ -# use make all and make install to install the examples -# - -ifeq ($(wildcard ../Makefile.inc), ) - $(error Configuration not found. Run ./configure first) -endif - -include ../Makefile.inc - -# define all programs -PROGRAMS = gettingstarted acknowledgementPayloads manualAcknowledgements streamingData multiceiverDemo scanner -ifneq (,$(findstring -lpigpio,$(SHARED_LINKER_LIBS))) -PROGRAMS+=interruptConfigure -endif - -include Makefile.examples diff --git a/RF24/examples_linux/Makefile.examples b/RF24/examples_linux/Makefile.examples deleted file mode 100644 index a03483e1084e248cf4beeeca5d67031cfbeee24d..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/Makefile.examples +++ /dev/null @@ -1,52 +0,0 @@ -############################################################################# -# -# Makefile for librf24 examples on Linux -# -# License: GPL (General Public License) -# Author: gnulnulf <arco@appeltaart.mine.nu> -# Date: 2013/02/07 (version 1.0) -# -# Description: -# ------------ -# use make all and make install to install the examples -# - -BINARY_PREFIX = rf24 -SOURCES = $(PROGRAMS:=.cpp) - -LIBS=-l$(LIB) -ifeq ($(DRIVER), LittleWire) - LIBS+= -llittlewire-spi -endif - -all: $(PROGRAMS) - -$(PROGRAMS): $(SOURCES) - $(CXX) $(CFLAGS) -I$(HEADER_DIR)/.. -I.. -L$(LIB_DIR) $@.cpp $(LIBS) -o $@ - -clean: - @echo "[Cleaning]" - rm -rf $(PROGRAMS) - -install: all - @echo "[Installing examples to $(EXAMPLES_DIR)]" - @mkdir -p $(EXAMPLES_DIR) - @for prog in $(PROGRAMS); do \ - install -m 0755 $${prog} $(EXAMPLES_DIR)/$(BINARY_PREFIX)-$${prog}; \ - done - -upload: all - @echo "[Uploading examples to $(REMOTE):$(REMOTE_EXAMPLES_DIR)]" -ifeq ($(REMOTE),) - @echo "[ERROR] Remote machine not configured. Run configure with respective arguments." - @exit 1 -endif - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "mkdir -p $(REMOTE_EXAMPLES_DIR)" - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "mkdir -p /tmp/RF24_examples" - @scp -q -P $(REMOTE_PORT) $(PROGRAMS) $(REMOTE):/tmp/RF24_examples - @for prog in $(PROGRAMS); do \ - ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "sudo install -m 0755 /tmp/RF24_examples/$${prog} $(REMOTE_EXAMPLES_DIR)/$(BINARY_PREFIX)-$${prog}"; \ - done - @ssh -q -t -p $(REMOTE_PORT) $(REMOTE) "rm -rf /tmp/RF24_examples" - -.PHONY: install upload diff --git a/RF24/examples_linux/acknowledgementPayloads.cpp b/RF24/examples_linux/acknowledgementPayloads.cpp deleted file mode 100644 index f81c8b8d50a17a1bdb0ae09b7b8a094507aef787..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/acknowledgementPayloads.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with Acknowledgement (ACK) payloads attached to ACK packets. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ -#include <ctime> // time() -#include <iostream> // cin, cout, endl -#include <string> // string, getline() -#include <time.h> // CLOCK_MONOTONIC_RAW, timespec, clock_gettime() -#include <RF24/RF24.h> // RF24, RF24_PA_LOW, delay() - -using namespace std; - -/****************** Linux ***********************/ -// Radio CE Pin, CSN Pin, SPI Speed -// CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use their own pin numbering -// CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -// ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -// Generic: -RF24 radio(22, 0); -/****************** Linux (BBB,x86,etc) ***********************/ -// See http://nRF24.github.io/RF24/pages.html for more information on usage -// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV - -// For this example, we'll be using a payload containing -// a string & an integer number that will be incremented -// on every successful transmission. -// Make a data structure to store the entire payload of different datatypes -struct PayloadStruct -{ - char message[7]; // only using 6 characters for TX & ACK payloads - uint8_t counter; -}; -PayloadStruct payload; - -void setRole(); // prototype to set the node's role -void master(); // prototype of the TX node's behavior -void slave(); // prototype of the RX node's behavior - -// custom defined timer for evaluating transmission time in microseconds -struct timespec startTimer, endTimer; -uint32_t getMicros(); // prototype to get ellapsed time in microseconds - -int main(int argc, char** argv) -{ - // perform hardware check - if (!radio.begin()) { - cout << "radio hardware is not responding!!" << endl; - return 0; // quit now - } - - // Let these addresses be used for the pair - uint8_t address[2][6] = {"1Node", "2Node"}; - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // print example's name - cout << argv[0] << endl; - - // Set the radioNumber via the terminal on startup - cout << "Which radio is this? Enter '0' or '1'. Defaults to '0' "; - string input; - getline(cin, input); - radioNumber = input.length() > 0 && (uint8_t)input[0] == 49; - - // to use ACK payloads, we need to enable dynamic payload lengths - radio.enableDynamicPayloads(); // ACK payloads are dynamically sized - - // Acknowledgement packets have no payloads by default. We need to enable - // this feature for all nodes (TX & RX) to use ACK payloads. - radio.enableAckPayload(); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // ready to execute program now - setRole(); // calls master() or slave() based on user input - return 0; -} - -/** - * set this node's role from stdin stream. - * this only considers the first char as input. - */ -void setRole() -{ - string input = ""; - while (!input.length()) { - cout << "*** PRESS 'T' to begin transmitting to the other node\n"; - cout << "*** PRESS 'R' to begin receiving from the other node\n"; - cout << "*** PRESS 'Q' to exit" << endl; - getline(cin, input); - if (input.length() >= 1) { - if (input[0] == 'T' || input[0] == 't') - master(); - else if (input[0] == 'R' || input[0] == 'r') - slave(); - else if (input[0] == 'Q' || input[0] == 'q') - break; - else - cout << input[0] << " is an invalid input. Please try again." << endl; - } - input = ""; // stay in the while loop - } // while -} // setRole() - -/** - * make this node act as the transmitter - */ -void master() -{ - memcpy(payload.message, "Hello ", 6); // set the payload message - radio.stopListening(); // put radio in TX mode - - unsigned int failures = 0; // keep track of failures - while (failures < 6) { - clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - uint32_t timerEllapsed = getMicros(); // end the timer - - if (report) { - // payload was delivered - cout << "Transmission successful! Time to transmit = "; - cout << timerEllapsed; // print the timer result - cout << " us. Sent: "; - cout << payload.message; // print outgoing message - cout << (unsigned int)payload.counter; // print outgoing counter counter - - uint8_t pipe; - if (radio.available(&pipe)) { - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming ACK payload - cout << " Received "; - cout << (unsigned int)radio.getDynamicPayloadSize(); // print incoming payload size - cout << " bytes on pipe " << (unsigned int)pipe; // print pipe that received it - cout << ": " << received.message; // print incoming message - cout << (unsigned int)received.counter << endl; // print incoming counter - payload.counter = received.counter + 1; // save incoming counter & increment for next outgoing - } // if got an ACK payload - else { - cout << " Received an empty ACK packet." << endl; // ACK had no payload - } - } // if delivered - else { - cout << "Transmission failed or timed out" << endl; // payload was not delivered - failures++; // increment failures - } - - // to make this example readable in the terminal - delay(1000); // slow transmissions down by 1 second - } // while - cout << failures << " failures detected. Leaving TX role." << endl; -} // master - -/** - * make this node act as the receiver - */ -void slave() -{ - memcpy(payload.message, "World ", 6); // set the payload message - - // load the payload for the first received transmission on pipe 0 - radio.writeAckPayload(1, &payload, sizeof(payload)); - - radio.startListening(); // put radio in RX mode - time_t startTimer = time(nullptr); // start a timer - while (time(nullptr) - startTimer < 6) { // use 6 second timeout - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getDynamicPayloadSize(); // get the size of the payload - PayloadStruct received; - radio.read(&received, sizeof(received)); // fetch payload from RX FIFO - cout << "Received " << (unsigned int)bytes; // print the size of the payload - cout << " bytes on pipe " << (unsigned int)pipe; // print the pipe number - cout << ": " << received.message; - cout << (unsigned int)received.counter; // print received payload - cout << " Sent: "; - cout << payload.message; - cout << (unsigned int)payload.counter << endl; // print ACK payload sent - startTimer = time(nullptr); // reset timer - - // save incoming counter & increment for next outgoing - payload.counter = received.counter + 1; - // load the payload for the first received transmission on pipe 0 - radio.writeAckPayload(1, &payload, sizeof(payload)); - } // if received something - } // while - cout << "Nothing received in 6 seconds. Leaving RX role." << endl; - radio.stopListening(); // recommended idle behavior is TX mode -} // slave - -/** - * Calculate the ellapsed time in microseconds - */ -uint32_t getMicros() -{ - // this function assumes that the timer was started using - // `clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer);` - - clock_gettime(CLOCK_MONOTONIC_RAW, &endTimer); - uint32_t seconds = endTimer.tv_sec - startTimer.tv_sec; - uint32_t useconds = (endTimer.tv_nsec - startTimer.tv_nsec) / 1000; - - return ((seconds)*1000 + useconds) + 0.5; -} diff --git a/RF24/examples_linux/acknowledgement_payloads.py b/RF24/examples_linux/acknowledgement_payloads.py deleted file mode 100644 index a5b28ebbc692bd386aa8475acb87d251e253e469..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/acknowledgement_payloads.py +++ /dev/null @@ -1,228 +0,0 @@ -""" -A simple example of sending data from 1 nRF24L01 transceiver to another -with Acknowledgement (ACK) payloads attached to ACK packets. - -This example was written to be used on 2 devices acting as 'nodes'. -""" -import sys -import argparse -import time -from RF24 import RF24, RF24_PA_LOW - - -parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter -) -parser.add_argument( - "-n", - "--node", - type=int, - choices=range(2), - help="the identifying radio number (or node ID number)", -) -parser.add_argument( - "-r", - "--role", - type=int, - choices=range(2), - help="'1' specifies the TX role. '0' specifies the RX role.", -) - -########### USER CONFIGURATION ########### -# See https://github.com/TMRh20/RF24/blob/master/pyRF24/readme.md -# Radio CE Pin, CSN Pin, SPI Speed -# CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use -# their own pin numbering -# CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -# ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -# Generic: -radio = RF24(22, 0) -################## Linux (BBB,x86,etc) ######################### -# See http://nRF24.github.io/RF24/pages.html for more information on usage -# See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -# See https://www.kernel.org/doc/Documentation/spi/spidev for more -# information on SPIDEV - -# using the python keyword global is bad practice. Instead we'll use a -# 1 item list to store our integer number for the payloads' counter -counter = [0] - - -def master(): - """Transmits a message and an incrementing integer every second.""" - radio.stopListening() # put radio in TX mode - failures = 0 - while failures < 6: - # construct a payload to send - buffer = b"Hello \x00" + bytes(counter) - - # send the payload and prompt - start_timer = time.monotonic_ns() # start timer - result = radio.write(buffer) # save the report - end_timer = time.monotonic_ns() # stop timer - if result: - # print timer results upon transmission success - decoded = buffer[:6].decode("utf-8") - print( - "Transmission successful! Time to transmit:", - f"{int((end_timer - start_timer) / 1000)} us.", - f"Sent: {decoded}{counter[0]}", - end=" ", - ) - has_payload, pipe_number = radio.available_pipe() - if has_payload: - # print the received ACK that was automatically sent - length = radio.getDynamicPayloadSize() - response = radio.read(length) - decoded = bytes(response[:6]).decode("utf-8") - print( - f"Received {length} on pipe {pipe_number}:", - f"{decoded}{response[7:8][0]}", - ) - # increment counter from received payload - if response[7:8][0] < 255: - counter[0] = response[7:8][0] + 1 - else: - counter[0] = 0 - else: - print("Received an empty ACK packet") - else: - failures += 1 - print("Transmission failed or timed out") - time.sleep(1) # let the RX node prepare a new ACK payload - print(failures, "failures detected. Leaving TX role.") - - -def slave(timeout: int = 6): - """Listen for any payloads and print the transaction - - :param int timeout: The number of seconds to wait (with no transmission) - until exiting function. - """ - radio.startListening() # put radio in RX mode - - # setup the first transmission's ACK payload - buffer = b"World \x00" + bytes(counter) - # we must set the ACK payload data and corresponding - # pipe number [0,5] - radio.writeAckPayload(1, buffer) # load ACK for first response - - start_timer = time.monotonic() # start timer - while (time.monotonic() - start_timer) < timeout: - has_payload, pipe_number = radio.available_pipe() - if has_payload: - length = radio.getDynamicPayloadSize() # grab the payload length - received = radio.read(length) # fetch 1 payload from RX FIFO - # increment counter from received payload - counter[0] = received[7:8][0] + 1 if received[7:8][0] < 255 else 0 - decoded = [bytes(received[:6]).decode("utf-8")] - decoded.append(buffer[:6].decode("utf-8")) - print( - f"Received {length} bytes on pipe {pipe_number}:", - f"{decoded[0]}{received[7:8][0]}", - f"Sent: {decoded[1]}{buffer[7:8][0]}", - ) - buffer = b"World \x00" + bytes(counter) # build a new ACK payload - radio.writeAckPayload(1, buffer) # load ACK for next response - start_timer = time.monotonic() # reset timer - - print("Nothing received in", timeout, "seconds. Leaving RX role") - # recommended behavior is to keep in TX mode while idle - radio.stopListening() # put radio in TX mode & flush unused ACK payloads - - -def set_role() -> bool: - """Set the role using stdin stream. Timeout arg for slave() can be - specified using a space delimiter (e.g. 'R 10' calls `slave(10)`) - - :return: - - True when role is complete & app should continue running. - - False when app should exit - """ - user_input = ( - input( - "*** Enter 'R' for receiver role.\n" - "*** Enter 'T' for transmitter role.\n" - "*** Enter 'Q' to quit example.\n" - ) - or "?" - ) - user_input = user_input.split() - if user_input[0].upper().startswith("R"): - if len(user_input) > 1: - slave(int(user_input[1])) - else: - slave() - return True - if user_input[0].upper().startswith("T"): - master() - return True - if user_input[0].upper().startswith("Q"): - radio.powerDown() - return False - print(user_input[0], "is an unrecognized input. Please try again.") - return set_role() - - -if __name__ == "__main__": - - args = parser.parse_args() # parse any CLI args - - # initialize the nRF24L01 on the spi bus - if not radio.begin(): - raise RuntimeError("radio hardware is not responding") - - # For this example, we will use different addresses - # An address need to be a buffer protocol object (bytearray) - address = [b"1Node", b"2Node"] - # It is very helpful to think of an address as a path instead of as - # an identifying device destination - - print(sys.argv[0]) # print example name - - # to use different addresses on a pair of radios, we need a variable to - # uniquely identify which address this radio will use to transmit - # 0 uses address[0] to transmit, 1 uses address[1] to transmit - radio_number = args.node # uses default value from `parser` - if args.node is None: # if '--node' arg wasn't specified - radio_number = bool( - int(input("Which radio is this? Enter '0' or '1'. Defaults to '0' ") or 0) - ) - - # ACK payloads are dynamically sized. - radio.enableDynamicPayloads() # to use ACK payloads - - # to enable the custom ACK payload feature - radio.enableAckPayload() - - # set the Power Amplifier level to -12 dBm since this test example is - # usually run with nRF24L01 transceivers in close proximity of each other - radio.setPALevel(RF24_PA_LOW) # RF24_PA_MAX is default - - # set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radio_number]) # always uses pipe 0 - - # set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[not radio_number]) # using pipe 1 - - # for debugging, we have 2 options that print a large block of details - # (smaller) function that prints raw register values - # radio.printDetails() - # (larger) function that prints human readable data - # radio.printPrettyDetails() - - try: - if args.role is None: # if not specified with CLI arg '-r' - while set_role(): - pass # continue example until 'Q' is entered - else: # if role was set using CLI args - # run role once and exit - if bool(args.role): - master() - else: - slave() - except KeyboardInterrupt: - print(" Keyboard Interrupt detected. Exiting...") - radio.powerDown() - sys.exit() diff --git a/RF24/examples_linux/extra/Makefile b/RF24/examples_linux/extra/Makefile deleted file mode 100644 index de7ba5b656c6f5c702d2692b1f57882648bb5173..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/extra/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################# -# -# Makefile for librf24 examples on Raspberry Pi -# -# License: GPL (General Public License) -# Author: gnulnulf <arco@appeltaart.mine.nu> -# Date: 2013/02/07 (version 1.0) -# -# Description: -# ------------ -# use make all and make install to install the examples -# You can change the install directory by editing the prefix line -# - -ifeq ($(wildcard ../../Makefile.inc), ) - $(error Configuration not found. Run ./configure first) -endif - -include ../../Makefile.inc - -# define all programs -PROGRAMS = rpi-hub - -include ../Makefile.examples diff --git a/RF24/examples_linux/extra/rpi-hub.cpp b/RF24/examples_linux/extra/rpi-hub.cpp deleted file mode 100644 index 0363666df8edfaaef75e430397009d34f21675aa..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/extra/rpi-hub.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * - * Filename : rpi-hub.cpp - * - * This program makes the RPi as a hub listening to all six pipes from the remote sensor nodes ( usually Arduino ) - * and will return the packet back to the sensor on pipe0 so that the sender can calculate the round trip delays - * when the payload matches. - * - * I encounter that at times, it also receive from pipe7 ( or pipe0 ) with content of FFFFFFFFF that I will not sent - * back to the sender - * - * Refer to RF24/examples/rpi_hub_arduino/ for the corresponding Arduino sketches to work with this code. - * - * - * CE is not used and CSN is GPIO25 (not pinout) - * - * Refer to RPi docs for GPIO numbers - * - * Author : Stanley Seow - * e-mail : stanleyseow@gmail.com - * date : 6th Mar 2013 - * - * 03/17/2013 : Charles-Henri Hallard (http://hallard.me) - * Modified to use with Arduipi board http://hallard.me/arduipi - * Changed to use modified bcm2835 and RF24 library - * - * - */ - -#include <cstdlib> -#include <iostream> -#include <RF24/RF24.h> - -using namespace std; - -// Radio pipe addresses for the 2 nodes to communicate. -// First pipe is for writing, 2nd, 3rd, 4th, 5th & 6th is for reading... -const uint64_t pipes[6] = {0xF0F0F0F0D2LL, 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL, 0xF0F0F0F0F1, 0xF0F0F0F0F2}; - -// CE Pin, CSN Pin, SPI Speed - -// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz -//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ); - -// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz -//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ); - -// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz -RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ); - -int main(int argc, char** argv) -{ - uint8_t len; - - // Refer to RF24.h or nRF24L01 DS for settings - radio.begin(); - radio.enableDynamicPayloads(); - radio.setAutoAck(1); - radio.setRetries(15, 15); - radio.setDataRate(RF24_1MBPS); - radio.setPALevel(RF24_PA_MAX); - radio.setChannel(76); - radio.setCRCLength(RF24_CRC_16); - - // Open 6 pipes for readings ( 5 plus pipe0, also can be used for reading ) - radio.openWritingPipe(pipes[0]); - radio.openReadingPipe(1, pipes[1]); - radio.openReadingPipe(2, pipes[2]); - radio.openReadingPipe(3, pipes[3]); - radio.openReadingPipe(4, pipes[4]); - radio.openReadingPipe(5, pipes[5]); - - // - // Start listening - // - radio.startListening(); - - // - // Dump the configuration of the rf unit for debugging - // - radio.printDetails(); - - printf("Output below : \n"); - delay(1); - - while (1) { - char receivePayload[32]; - uint8_t pipe = 1; - - // Start listening - radio.startListening(); - - while (radio.available(&pipe)) { - len = radio.getDynamicPayloadSize(); - radio.read(receivePayload, len); - - // Display it on screen - printf("Recv: size=%i payload=%s pipe=%i", len, receivePayload, pipe); - - // Send back payload to sender - radio.stopListening(); - - // if pipe is 7, do not send it back - if (pipe != 7) { - radio.write(receivePayload, len); - receivePayload[len] = 0; - printf("\t Send: size=%i payload=%s pipe:%i\n", len, receivePayload, pipe); - } - else { - printf("\n"); - } - - pipe++; - - // reset pipe to 0 - if (pipe > 6) { - pipe = 0; - } - } - - delayMicroseconds(20); - } - - return 0; -} diff --git a/RF24/examples_linux/getting_started.py b/RF24/examples_linux/getting_started.py deleted file mode 100644 index c9695e7fd32e7a8e818899c2aa7a20269f9dd8f0..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/getting_started.py +++ /dev/null @@ -1,197 +0,0 @@ -""" -A simple example of sending data from 1 nRF24L01 transceiver to another. -This example was written to be used on 2 devices acting as 'nodes'. -""" -import sys -import argparse -import time -import struct -from RF24 import RF24, RF24_PA_LOW - - -parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter -) -parser.add_argument( - "-n", - "--node", - type=int, - choices=range(2), - help="the identifying radio number (or node ID number)", -) -parser.add_argument( - "-r", - "--role", - type=int, - choices=range(2), - help="'1' specifies the TX role. '0' specifies the RX role.", -) - - -########### USER CONFIGURATION ########### -# See https://github.com/TMRh20/RF24/blob/master/pyRF24/readme.md -# Radio CE Pin, CSN Pin, SPI Speed -# CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use -# their own pin numbering -# CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -# ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -# Generic: -radio = RF24(22, 0) -################## Linux (BBB,x86,etc) ######################### -# See http://nRF24.github.io/RF24/pages.html for more information on usage -# See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -# See https://www.kernel.org/doc/Documentation/spi/spidev for more -# information on SPIDEV - -# using the python keyword global is bad practice. Instead we'll use a 1 item -# list to store our float number for the payloads sent/received -payload = [0.0] - - -def master(): - """Transmits an incrementing float every second""" - radio.stopListening() # put radio in TX mode - failures = 0 - while failures < 6: - # use struct.pack() to packet your data into the payload - # "<f" means a single little endian (4 byte) float value. - buffer = struct.pack("<f", payload[0]) - start_timer = time.monotonic_ns() # start timer - result = radio.write(buffer) - end_timer = time.monotonic_ns() # end timer - if not result: - print("Transmission failed or timed out") - failures += 1 - else: - print( - "Transmission successful! Time to Transmit:", - f"{(end_timer - start_timer) / 1000} us. Sent: {payload[0]}", - ) - payload[0] += 0.01 - time.sleep(1) - print(failures, "failures detected. Leaving TX role.") - - -def slave(timeout=6): - """Listen for any payloads and print the transaction - - :param int timeout: The number of seconds to wait (with no transmission) - until exiting function. - """ - radio.startListening() # put radio in RX mode - - start_timer = time.monotonic() - while (time.monotonic() - start_timer) < timeout: - has_payload, pipe_number = radio.available_pipe() - if has_payload: - # fetch 1 payload from RX FIFO - buffer = radio.read(radio.payloadSize) - # use struct.unpack() to convert the buffer into usable data - # expecting a little endian float, thus the format string "<f" - # buffer[:4] truncates padded 0s in case payloadSize was not set - payload[0] = struct.unpack("<f", buffer[:4])[0] - # print details about the received packet - print( - f"Received {radio.payloadSize} bytes", - f"on pipe {pipe_number}: {payload[0]}", - ) - start_timer = time.monotonic() # reset the timeout timer - - print("Nothing received in", timeout, "seconds. Leaving RX role") - # recommended behavior is to keep in TX mode while idle - radio.stopListening() # put the radio in TX mode - - -def set_role() -> bool: - """Set the role using stdin stream. Timeout arg for slave() can be - specified using a space delimiter (e.g. 'R 10' calls `slave(10)`) - - :return: - - True when role is complete & app should continue running. - - False when app should exit - """ - user_input = ( - input( - "*** Enter 'R' for receiver role.\n" - "*** Enter 'T' for transmitter role.\n" - "*** Enter 'Q' to quit example.\n" - ) - or "?" - ) - user_input = user_input.split() - if user_input[0].upper().startswith("R"): - if len(user_input) > 1: - slave(int(user_input[1])) - else: - slave() - return True - if user_input[0].upper().startswith("T"): - master() - return True - if user_input[0].upper().startswith("Q"): - radio.powerDown() - return False - print(user_input[0], "is an unrecognized input. Please try again.") - return set_role() - - -if __name__ == "__main__": - - args = parser.parse_args() # parse any CLI args - - # initialize the nRF24L01 on the spi bus - if not radio.begin(): - raise RuntimeError("radio hardware is not responding") - - # For this example, we will use different addresses - # An address need to be a buffer protocol object (bytearray) - address = [b"1Node", b"2Node"] - # It is very helpful to think of an address as a path instead of as - # an identifying device destination - - print(sys.argv[0]) # print example name - - # to use different addresses on a pair of radios, we need a variable to - # uniquely identify which address this radio will use to transmit - # 0 uses address[0] to transmit, 1 uses address[1] to transmit - radio_number = args.node # uses default value from `parser` - if args.node is None: # if '--node' arg wasn't specified - radio_number = bool( - int(input("Which radio is this? Enter '0' or '1'. Defaults to '0' ") or 0) - ) - - # set the Power Amplifier level to -12 dBm since this test example is - # usually run with nRF24L01 transceivers in close proximity of each other - radio.setPALevel(RF24_PA_LOW) # RF24_PA_MAX is default - - # set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radio_number]) # always uses pipe 0 - - # set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[not radio_number]) # using pipe 1 - - # To save time during transmission, we'll set the payload size to be only - # what we need. A float value occupies 4 bytes in memory using - # struct.pack(); "f" means an unsigned float - radio.payloadSize = struct.calcsize("f") - - # for debugging, we have 2 options that print a large block of details - # (smaller) function that prints raw register values - # radio.printDetails() - # (larger) function that prints human readable data - # radio.printPrettyDetails() - - try: - if args.role is None: # if not specified with CLI arg '-r' - while set_role(): - pass # continue example until 'Q' is entered - else: # if role was set using CLI args - # run role once and exit - if bool(args.role): - master() - else: - slave() - except KeyboardInterrupt: - print(" Keyboard Interrupt detected. Powering down radio.") - radio.powerDown() diff --git a/RF24/examples_linux/gettingstarted.cpp b/RF24/examples_linux/gettingstarted.cpp deleted file mode 100644 index 019a018e82be775590aa4801a9a9144f58d42e62..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/gettingstarted.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ -#include <ctime> // time() -#include <iostream> // cin, cout, endl -#include <string> // string, getline() -#include <time.h> // CLOCK_MONOTONIC_RAW, timespec, clock_gettime() -#include <RF24/RF24.h> // RF24, RF24_PA_LOW, delay() - -using namespace std; - -/****************** Linux ***********************/ -// Radio CE Pin, CSN Pin, SPI Speed -// CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use their own pin numbering -// CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -// ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -// Generic: -RF24 radio(22, 0); -/****************** Linux (BBB,x86,etc) ***********************/ -// See http://nRF24.github.io/RF24/pages.html for more information on usage -// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV - -// For this example, we'll be using a payload containing -// a single float number that will be incremented -// on every successful transmission -float payload = 0.0; - -void setRole(); // prototype to set the node's role -void master(); // prototype of the TX node's behavior -void slave(); // prototype of the RX node's behavior - -// custom defined timer for evaluating transmission time in microseconds -struct timespec startTimer, endTimer; -uint32_t getMicros(); // prototype to get ellapsed time in microseconds - -int main(int argc, char** argv) -{ - - // perform hardware check - if (!radio.begin()) { - cout << "radio hardware is not responding!!" << endl; - return 0; // quit now - } - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // print example's name - cout << argv[0] << endl; - - // Let these addresses be used for the pair - uint8_t address[2][6] = {"1Node", "2Node"}; - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // Set the radioNumber via the terminal on startup - cout << "Which radio is this? Enter '0' or '1'. Defaults to '0' "; - string input; - getline(cin, input); - radioNumber = input.length() > 0 && (uint8_t)input[0] == 49; - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // float datatype occupies 4 bytes - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // ready to execute program now - setRole(); // calls master() or slave() based on user input - return 0; -} - -/** - * set this node's role from stdin stream. - * this only considers the first char as input. - */ -void setRole() -{ - string input = ""; - while (!input.length()) { - cout << "*** PRESS 'T' to begin transmitting to the other node\n"; - cout << "*** PRESS 'R' to begin receiving from the other node\n"; - cout << "*** PRESS 'Q' to exit" << endl; - getline(cin, input); - if (input.length() >= 1) { - if (input[0] == 'T' || input[0] == 't') - master(); - else if (input[0] == 'R' || input[0] == 'r') - slave(); - else if (input[0] == 'Q' || input[0] == 'q') - break; - else - cout << input[0] << " is an invalid input. Please try again." << endl; - } - input = ""; // stay in the while loop - } // while -} // setRole() - -/** - * make this node act as the transmitter - */ -void master() -{ - radio.stopListening(); // put radio in TX mode - - unsigned int failure = 0; // keep track of failures - while (failure < 6) { - clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer); // start the timer - bool report = radio.write(&payload, sizeof(float)); // transmit & save the report - uint32_t timerEllapsed = getMicros(); // end the timer - - if (report) { - // payload was delivered - cout << "Transmission successful! Time to transmit = "; - cout << timerEllapsed; // print the timer result - cout << " us. Sent: " << payload << endl; // print payload sent - payload += 0.01; // increment float payload - } - else { - // payload was not delivered - cout << "Transmission failed or timed out" << endl; - failure++; - } - - // to make this example readable in the terminal - delay(1000); // slow transmissions down by 1 second - } - cout << failure << " failures detected. Leaving TX role." << endl; -} - -/** - * make this node act as the receiver - */ -void slave() -{ - - radio.startListening(); // put radio in RX mode - - time_t startTimer = time(nullptr); // start a timer - while (time(nullptr) - startTimer < 6) { // use 6 second timeout - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getPayloadSize(); // get the size of the payload - radio.read(&payload, bytes); // fetch payload from FIFO - cout << "Received " << (unsigned int)bytes; // print the size of the payload - cout << " bytes on pipe " << (unsigned int)pipe; // print the pipe number - cout << ": " << payload << endl; // print the payload's value - startTimer = time(nullptr); // reset timer - } - } - cout << "Nothing received in 6 seconds. Leaving RX role." << endl; - radio.stopListening(); -} - -/** - * Calculate the ellapsed time in microseconds - */ -uint32_t getMicros() -{ - // this function assumes that the timer was started using - // `clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer);` - - clock_gettime(CLOCK_MONOTONIC_RAW, &endTimer); - uint32_t seconds = endTimer.tv_sec - startTimer.tv_sec; - uint32_t useconds = (endTimer.tv_nsec - startTimer.tv_nsec) / 1000; - - return ((seconds)*1000 + useconds) + 0.5; -} diff --git a/RF24/examples_linux/interruptConfigure.cpp b/RF24/examples_linux/interruptConfigure.cpp deleted file mode 100644 index 46e94a7f6d5b545d3d53f7a5d3b22a0dc59103ed..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/interruptConfigure.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * This example uses Acknowledgement (ACK) payloads attached to ACK packets to - * demonstrate how the nRF24L01's IRQ (Interrupt Request) pin can be - * configured to detect when data is received, or when data has transmitted - * successfully, or when data has failed to transmit. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ -#include <ctime> // time() -#include <iostream> // cin, cout, endl -#include <string> // string, getline() -#include <time.h> // CLOCK_MONOTONIC_RAW, timespec, clock_gettime() -#include <RF24/RF24.h> // RF24, RF24_PA_LOW, delay(), pinMode(), INPUT, attachInterrupt(), INT_EDGE_FALLING - -using namespace std; - -// We will be using the nRF24L01's IRQ pin for this example -#define IRQ_PIN 12 // this needs to be a digital input capable pin - -// this example is a sequential program. so we need to wait for the event to be handled -volatile bool wait_for_event = false; // used to signify that the event is handled - -/****************** Linux ***********************/ -// Radio CE Pin, CSN Pin, SPI Speed -// CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use their own pin numbering -// CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -// ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -// Generic: -RF24 radio(22, 0); -/****************** Linux (BBB,x86,etc) ***********************/ -// See http://nRF24.github.io/RF24/pages.html for more information on usage -// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV - -// For this example, we'll be using a payload containing -// a string that changes on every transmission. (successful or not) -// Make a couple arrays of payloads & an iterator to traverse them -const uint8_t tx_pl_size = 5; -const uint8_t ack_pl_size = 4; -uint8_t pl_iterator = 0; -// The " + 1" compensates for the c-string's NULL terminating 0 -char tx_payloads[4][tx_pl_size + 1] = {"Ping ", "Pong ", "Radio", "1FAIL"}; -char ack_payloads[3][ack_pl_size + 1] = {"Yak ", "Back", " ACK"}; - -void interruptHandler(); // prototype to handle the interrupt request (IRQ) pin -void setRole(); // prototype to set the node's role -void master(); // prototype of the TX node's behavior -void slave(); // prototype of the RX node's behavior -void ping_n_wait(); // prototype that sends a payload and waits for the IRQ pin to get triggered -void printRxFifo(const uint8_t); // prototype to print entire contents of RX FIFO with 1 buffer - -int main(int argc, char** argv) -{ - - // perform hardware check - if (!radio.begin()) { - cout << "radio hardware is not responding!!" << endl; - return 0; // quit now - } - - // Let these addresses be used for the pair - uint8_t address[2][6] = {"1Node", "2Node"}; - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // print example's name - cout << argv[0] << endl; - - // Set the radioNumber via the terminal on startup - cout << "Which radio is this? Enter '0' or '1'. Defaults to '0' "; - string input; - getline(cin, input); - radioNumber = input.length() > 0 && (uint8_t)input[0] == 49; - - // to use ACK payloads, we need to enable dynamic payload lengths - radio.enableDynamicPayloads(); // ACK payloads are dynamically sized - - // Acknowledgement packets have no payloads by default. We need to enable - // this feature for all nodes (TX & RX) to use ACK payloads. - radio.enableAckPayload(); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // setup the digital input pin connected to the nRF24L01's IRQ pin - pinMode(IRQ_PIN, INPUT); - - // register the interrupt request (IRQ) to call our - // Interrupt Service Routine (ISR) callback function interruptHandler() - attachInterrupt(IRQ_PIN, INT_EDGE_FALLING, &interruptHandler); - // IMPORTANT: do not call radio.available() before calling - // radio.whatHappened() when the interruptHandler() is triggered by the - // IRQ pin FALLING event. According to the datasheet, the pipe information - // is unreliable during the IRQ pin FALLING transition. - - // ready to execute program now - setRole(); // calls master() or slave() based on user input - return 0; -} // main - -/** - * set this node's role from stdin stream. - * this only considers the first char as input. - */ -void setRole() -{ - string input = ""; - while (!input.length()) { - cout << "*** PRESS 'T' to begin transmitting to the other node\n"; - cout << "*** PRESS 'R' to begin receiving from the other node\n"; - cout << "*** PRESS 'Q' to exit" << endl; - getline(cin, input); - if (input.length() >= 1) { - if (input[0] == 'T' || input[0] == 't') - master(); - else if (input[0] == 'R' || input[0] == 'r') - slave(); - else if (input[0] == 'Q' || input[0] == 'q') - break; - else - cout << input[0] << " is an invalid input. Please try again." << endl; - } - input = ""; // stay in the while loop - } // while -} // setRole - -/** - * act as the transmitter to show 3 different IRQ events by sending 4 payloads: - * 1. Successfully receive ACK payload first - * 2. Successfully transmit on second - * 3. Send a third payload to fill RX node's RX FIFO (supposedly making RX node unresponsive) - * 4. intentionally fail transmit on the fourth - */ -void master() -{ - pl_iterator = 0; // reset the iterator for the following tests done in master() - - // Test the "data ready" event with the IRQ pin - cout << "\nConfiguring IRQ pin to ignore the 'data sent' event\n"; - radio.maskIRQ(true, false, false); // args = "data_sent", "data_fail", "data_ready" - cout << " Pinging RX node for 'data ready' event..."; - ping_n_wait(); // transmit a payload and detect the IRQ pin - pl_iterator++; // increment iterator for next test - - // Test the "data sent" event with the IRQ pin - cout << "\nConfiguring IRQ pin to ignore the 'data ready' event\n"; - radio.maskIRQ(false, false, true); // args = "data_sent", "data_fail", "data_ready" - cout << " Pinging RX node for 'data sent' event..."; - radio.flush_tx(); // flush payloads from any failed prior test - ping_n_wait(); // transmit a payload and detect the IRQ pin - pl_iterator++; // increment iterator for next test - - // Use this iteration to fill the RX node's FIFO which sets us up for the next test. - // write() uses virtual interrupt flags that work despite the masking of the IRQ pin - radio.maskIRQ(1, 1, 1); // disable IRQ masking for this step - - cout << "\nSending 1 payload to fill RX node's FIFO. IRQ pin is neglected.\n"; - // write() will call flush_tx() on 'data fail' events - if (radio.write(&tx_payloads[pl_iterator], tx_pl_size)) - cout << "RX node's FIFO is full; it is not listening any more" << endl; - else { - cout << "Transmission failed or timed out. Continuing anyway." << endl; - radio.flush_tx(); - } - pl_iterator++; // increment iterator for next test - - // test the "data fail" event with the IRQ pin - cout << "\nConfiguring IRQ pin to reflect all events\n"; - radio.maskIRQ(0, 0, 0); // args = "data_sent", "data_fail", "data_ready" - cout << " Pinging inactive RX node for 'data fail' event..."; - ping_n_wait(); // transmit a payload and detect the IRQ pin - - // CE pin is still HIGH which consumes more power. Example is now idling so... - radio.stopListening(); // ensure CE pin is LOW - // stopListening() also calls flush_tx() when ACK payloads are enabled - - if (radio.available()) { - printRxFifo(ack_pl_size); // doing this will flush the RX FIFO - } -} // master - -/** - * act as the receiver - */ -void slave() -{ - - // let IRQ pin only trigger on "data_ready" event in RX mode - radio.maskIRQ(1, 1, 0); // args = "data_sent", "data_fail", "data_ready" - - // Fill the TX FIFO with 3 ACK payloads for the first 3 received - // transmissions on pipe 0. - radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); - - radio.startListening(); // put radio in RX mode - time_t startTimer = time(nullptr); // start a timer - while (time(nullptr) - startTimer < 6 && !radio.rxFifoFull()) { - // use 6 second timeout & wait till RX FIFO is full - } - delay(100); // wait for ACK payload to finish transmitting - radio.stopListening(); // also discards unused ACK payloads - - if (radio.available()) { - printRxFifo(tx_pl_size); - } - else { - cout << "Timeout was reached. Going back to setRole()" << endl; - } -} // slave - -/** - * pings the receiver with a non-blocking startWrite(), then waits till - * the IRQ pin is triggered - */ -void ping_n_wait() -{ - // use the non-blocking call to write a payload and begin transmission - // the "false" argument means we are expecting an ACK packet response - radio.startFastWrite(tx_payloads[pl_iterator], tx_pl_size, false); - - wait_for_event = true; - while (wait_for_event) { - /* - * IRQ pin is LOW when activated. Otherwise it is always HIGH - * Wait in this empty loop until IRQ pin is activated. - * - * In this example, the "data fail" event is always configured to - * trigger the IRQ pin active. Because the auto-ACK feature is on by - * default, we don't need a timeout check to prevent an infinite loop. - */ - } -} - -/** - * when the IRQ pin goes active LOW, call this fuction print out why - */ -void interruptHandler() -{ - // print IRQ status and all masking flags' states - - cout << "\tIRQ pin is actively LOW" << endl; // show that this function was called - - bool tx_ds, tx_df, rx_dr; // declare variables for IRQ masks - radio.whatHappened(tx_ds, tx_df, rx_dr); // get values for IRQ masks - // whatHappened() clears the IRQ masks also. This is required for - // continued TX operations when a transmission fails. - // clearing the IRQ masks resets the IRQ pin to its inactive state (HIGH) - - cout << "\tdata_sent: " << tx_ds; // print "data sent" mask state - cout << ", data_fail: " << tx_df; // print "data fail" mask state - cout << ", data_ready: " << rx_dr << endl; // print "data ready" mask state - - if (tx_df) // if TX payload failed - radio.flush_tx(); // clear all payloads from the TX FIFO - - // print if test passed or failed. Unintentional fails mean the RX node was not listening. - if (pl_iterator == 0) - cout << " 'Data Ready' event test " << (rx_dr ? "passed" : "failed") << endl; - else if (pl_iterator == 1) - cout << " 'Data Sent' event test " << (tx_ds ? "passed" : "failed") << endl; - else if (pl_iterator == 3) - cout << " 'Data Fail' event test " << (tx_df ? "passed" : "failed") << endl; - - wait_for_event = false; // ready to continue -} // interruptHandler - -/** - * Print the entire RX FIFO with one buffer. This will also flush the RX FIFO. - * @param pl_size used to determine received payload size. Remember that the - * payload sizes are declared as tx_pl_size and ack_pl_size. - */ -void printRxFifo(const uint8_t pl_size) -{ - char rx_fifo[pl_size * 3 + 1]; // assuming RX FIFO is full; declare a buffer to hold it all - if (radio.rxFifoFull()) { - rx_fifo[pl_size * 3] = 0; // add a NULL terminating char to use as a c-string - radio.read(&rx_fifo, pl_size * 3); // this clears the RX FIFO (for this example) - } - else { - uint8_t i = 0; - while (radio.available()) { - radio.read(&rx_fifo + (i * pl_size), pl_size); - i++; - } - rx_fifo[i * pl_size] = 0; // add a NULL terminating char to use as a c-string - } - - // print the entire RX FIFO with 1 buffer - cout << "Complete RX FIFO: " << rx_fifo << endl; -} diff --git a/RF24/examples_linux/interrupt_configure.py b/RF24/examples_linux/interrupt_configure.py deleted file mode 100644 index 9c031ba7cf618ee98c3e2cb4046d3279a485339e..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/interrupt_configure.py +++ /dev/null @@ -1,283 +0,0 @@ -""" -This example uses Acknowledgement (ACK) payloads attached to ACK packets to -demonstrate how the nRF24L01's IRQ (Interrupt Request) pin can be -configured to detect when data is received, or when data has transmitted -successfully, or when data has failed to transmit. - -This example was written to be used on 2 devices acting as "nodes". -""" -import sys -import argparse -import time -import RPi.GPIO as GPIO -from RF24 import RF24, RF24_PA_LOW - - -parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter -) -parser.add_argument( - "-n", - "--node", - type=int, - choices=range(2), - help="the identifying radio number (or node ID number)", -) -parser.add_argument( - "-r", - "--role", - type=int, - choices=range(2), - help="'1' specifies the TX role. '0' specifies the RX role.", -) - -########### USER CONFIGURATION ########### -# See https://github.com/TMRh20/RF24/blob/master/pyRF24/readme.md -# Radio CE Pin, CSN Pin, SPI Speed -# CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use -# their own pin numbering -# CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -# ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -# Generic: -radio = RF24(22, 0) -################## Linux (BBB,x86,etc) ######################### -# See http://nRF24.github.io/RF24/pages.html for more information on usage -# See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -# See https://www.kernel.org/doc/Documentation/spi/spidev for more -# information on SPIDEV - -# select your digital input pin that's connected to the IRQ pin on the nRF24L01 -IRQ_PIN = 12 - -# For this example, we'll be using a payload containing -# a string that changes on every transmission. (successful or not) -# Make a couple tuples of payloads & an iterator to traverse them -pl_iterator = [0] # use a 1-item list instead of python's global keyword -tx_payloads = (b"Ping ", b"Pong ", b"Radio", b"1FAIL") -ack_payloads = (b"Yak ", b"Back", b" ACK") - - -def interrupt_handler(channel): - """This function is called when IRQ pin is detected active LOW""" - print("IRQ pin", channel, "went active LOW.") - tx_ds, tx_df, rx_dr = radio.whatHappened() # get IRQ status flags - if tx_df: - radio.flush_tx() - print(f"\ttx_ds: {tx_ds}, tx_df: {tx_df}, rx_dr: {rx_dr}") - if pl_iterator[0] == 0: - print(" 'data ready' event test", ("passed" if rx_dr else "failed")) - elif pl_iterator[0] == 1: - print(" 'data sent' event test", ("passed" if tx_ds else "failed")) - elif pl_iterator[0] == 3: - print(" 'data fail' event test", ("passed" if tx_df else "failed")) - - -# setup IRQ GPIO pin -GPIO.setmode(GPIO.BCM) -GPIO.setup(IRQ_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) -GPIO.add_event_detect(IRQ_PIN, GPIO.FALLING, callback=interrupt_handler) -# IMPORTANT: do not call radio.available() before calling -# radio.whatHappened() when the interruptHandler() is triggered by the -# IRQ pin FALLING event. According to the datasheet, the pipe information -# is unreliable during the IRQ pin FALLING transition. - - -def _ping_n_wait(pl_iter): - """private function to ping RX node and wait for IRQ pin to be handled - - :param int pl_iter: The index of the buffer in `tx_payloads` tuple to - send. This number is also used to determine if event test was - successful or not. - """ - # set pl_iterator[0] so interrupt_handler() can determine if test was - # successful or not - pl_iterator[0] = pl_iter - # the following False parameter means we're expecting an ACK packet - radio.startFastWrite(tx_payloads[pl_iter], False) - time.sleep(0.1) # wait 100 ms for interrupt_handler() to complete - - -def print_rx_fifo(pl_size: int): - """Flush RX FIFO by printing all available payloads with 1 buffer - - :param int pl_size: the expected size of each payload - """ - if radio.rxFifoFull(): - # all 3 payloads received were 5 bytes each, and RX FIFO is full - # so, fetching 15 bytes from the RX FIFO also flushes RX FIFO - print("Complete RX FIFO:", radio.read(pl_size * 3).decode("utf-8")) - else: - buffer = bytearray() - while radio.available(): - buffer += radio.read(pl_size) - if buffer: # if any payloads were read from the RX FIFO - print("Complete RX FIFO:", buffer.decode("utf-8")) - - -def master(): - """Transmits 4 times and reports results - - 1. successfully receive ACK payload first - 2. successfully transmit on second - 3. send a third payload to fill RX node's RX FIFO - (supposedly making RX node unresponsive) - 4. intentionally fail transmit on the fourth - """ - radio.stopListening() # put radio in TX mode - - # on data ready test - print("\nConfiguring IRQ pin to only ignore 'on data sent' event") - radio.maskIRQ(True, False, False) # args = tx_ds, tx_df, rx_dr - print(" Pinging slave node for an ACK payload...", end=" ") - _ping_n_wait(0) - - # on "data sent" test - print("\nConfiguring IRQ pin to only ignore 'on data ready' event") - radio.maskIRQ(False, False, True) # args = tx_ds, tx_df, rx_dr - print(" Pinging slave node again... ", end=" ") - _ping_n_wait(1) - - # trigger slave node to stopListening() by filling slave node's RX FIFO - print("\nSending one extra payload to fill RX FIFO on slave node.") - radio.maskIRQ(1, 1, 1) # disable IRQ pin for this step - if radio.write(tx_payloads[2]): - # when send_only parameter is True, send() ignores RX FIFO usage - if radio.rxFifoFull(): - print("RX node's FIFO is full; it is not listening any more") - else: - print( - "Transmission successful, but the RX node might still be listening." - ) - else: - radio.flush_tx() - print("Transmission failed or timed out. Continuing anyway.") - - # on "data fail" test - print("\nConfiguring IRQ pin to go active for all events.") - radio.maskIRQ(False, False, False) # args = tx_ds, tx_df, rx_dr - print(" Sending a ping to inactive slave node...", end=" ") - _ping_n_wait(3) - - # CE pin is still HIGH which consumes more power. Example is now idling so... - radio.stopListening() # ensure CE pin is LOW - # stopListening() also calls flush_tx() when ACK payloads are enabled - - print_rx_fifo(len(ack_payloads[0])) # empty RX FIFO - - -def slave(timeout: int = 6): - """Only listen for 3 payload from the master node - - :param int timeout: The number of seconds to wait (with no transmission) - until exiting function. - """ - pl_iterator[0] = 0 # reset this to indicate event is a 'data_ready' event - # setup radio to receive pings, fill TX FIFO with ACK payloads - radio.writeAckPayload(1, ack_payloads[0]) - radio.writeAckPayload(1, ack_payloads[1]) - radio.writeAckPayload(1, ack_payloads[2]) - radio.startListening() # start listening & clear status flags - start_timer = time.monotonic() # start timer now - while not radio.rxFifoFull() and time.monotonic() - start_timer < timeout: - # if RX FIFO is not full and timeout is not reached, then keep waiting - pass - time.sleep(0.1) # wait for last ACK payload to transmit - radio.stopListening() # put radio in TX mode & discard any ACK payloads - print_rx_fifo(len(tx_payloads[0])) - - -def set_role() -> bool: - """Set the role using stdin stream. Timeout arg for slave() can be - specified using a space delimiter (e.g. 'R 10' calls `slave(10)`) - - :return: - - True when role is complete & app should continue running. - - False when app should exit - """ - user_input = ( - input( - "*** Enter 'R' for receiver role.\n" - "*** Enter 'T' for transmitter role.\n" - "*** Enter 'Q' to quit example.\n" - ) - or "?" - ) - user_input = user_input.split() - if user_input[0].upper().startswith("R"): - if len(user_input) > 1: - slave(int(user_input[1])) - else: - slave() - return True - if user_input[0].upper().startswith("T"): - master() - return True - if user_input[0].upper().startswith("Q"): - radio.powerDown() - return False - print(user_input[0], "is an unrecognized input. Please try again.") - return set_role() - - -if __name__ == "__main__": - - args = parser.parse_args() # parse any CLI args - - # initialize the nRF24L01 on the spi bus - if not radio.begin(): - raise RuntimeError("radio hardware is not responding") - - # For this example, we will use different addresses - # An address need to be a buffer protocol object (bytearray) - address = [b"1Node", b"2Node"] - # It is very helpful to think of an address as a path instead of as - # an identifying device destination - - print(sys.argv[0]) # print example name - - # to use different addresses on a pair of radios, we need a variable to - # uniquely identify which address this radio will use to transmit - # 0 uses address[0] to transmit, 1 uses address[1] to transmit - radio_number = args.node # uses default value from `parser` - if args.node is None: # if '--node' arg wasn't specified - radio_number = bool( - int(input("Which radio is this? Enter '0' or '1'. Defaults to '0' ") or 0) - ) - - # set the Power Amplifier level to -12 dBm since this test example is - # usually run with nRF24L01 transceivers in close proximity of each other - radio.setPALevel(RF24_PA_LOW) # RF24_PA_MAX is default - - # ACK payloads are dynamically sized. - radio.enableDynamicPayloads() # to use ACK payloads - - # this example uses the ACK payload to trigger the IRQ pin active for - # the "on data received" event - radio.enableAckPayload() # enable ACK payloads - - # set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radio_number]) # always uses pipe 0 - - # set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[not radio_number]) # using pipe 1 - - # for debugging, we have 2 options that print a large block of details - # (smaller) function that prints raw register values - # radio.printDetails() - # (larger) function that prints human readable data - # radio.printPrettyDetails() - - try: - if args.role is None: # if not specified with CLI arg '-r' - while set_role(): - pass # continue example until 'Q' is entered - else: # if role was set using CLI args - # run role once and exit - if bool(args.role): - master() - else: - slave() - except KeyboardInterrupt: - print(" Keyboard Interrupt detected. Powering down radio.") - radio.powerDown() diff --git a/RF24/examples_linux/interrupts/Makefile b/RF24/examples_linux/interrupts/Makefile deleted file mode 100644 index 2c480971071b0e6cede37710fa1a8a3838563692..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/interrupts/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################# -# -# Makefile for librf24 examples on Raspberry Pi -# -# License: GPL (General Public License) -# Author: gnulnulf <arco@appeltaart.mine.nu> -# Date: 2013/02/07 (version 1.0) -# -# Description: -# ------------ -# use make all and make install to install the examples -# You can change the install directory by editing the prefix line -# - -ifeq ($(wildcard ../../Makefile.inc), ) - $(error Configuration not found. Run ./configure first) -endif - -include ../../Makefile.inc - -# define all programs -PROGRAMS = gettingstarted_call_response_int gettingstarted_call_response_int2 transfer_interrupt pingpair_dyn_int - -include ../Makefile.examples diff --git a/RF24/examples_linux/interrupts/gettingstarted_call_response_int.cpp b/RF24/examples_linux/interrupts/gettingstarted_call_response_int.cpp deleted file mode 100644 index 1362292c3b2ec248efa95abc0fe55310e9134e42..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/interrupts/gettingstarted_call_response_int.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -TMRh20 2014 - Updated to work with optimized RF24 Arduino library -*/ - -/** - * Example for efficient call-response using ack-payloads and interrupts - * - * This example continues to make use of all the normal functionality of the radios including - * the auto-ack and auto-retry features, but allows ack-payloads to be written optionlly as well. - * This allows very fast call-response communication, with the responding radio never having to - * switch out of Primary Receiver mode to send back a payload, but having the option to switch to - * primary transmitter if wanting to initiate communication instead of respond to a commmunication. - */ - -#include <cstdlib> -#include <iostream> -#include <sstream> -#include <string> -#include <unistd.h> -#include <RF24/RF24.h> - -using namespace std; - -// -// Hardware configuration -// Configure the appropriate pins for your connections - -/****************** Raspberry Pi ***********************/ - -RF24 radio(22, 0); //GPIO, SPI-BUS - -/********** User Config *********/ -// Assign a unique identifier for this node, 0 or 1. Arduino example uses radioNumber 0 by default. -bool radioNumber = 1; -int interruptPin = 23; -/********************************/ - -// Radio pipe addresses for the 2 nodes to communicate. -const uint8_t addresses[][6] = {"1Node", "2Node"}; - -volatile bool role_ping_out = 1, role_pong_back = 0, role = 0; -uint8_t counter = 1; // A single byte to keep track of the data being sent back and forth - -volatile bool gotResponse = false; - -void intHandler() -{ - - if (role == role_pong_back) { - uint8_t pipeNo, gotByte; // Declare variables for the pipe and the byte received - if (radio.available(&pipeNo)) { // Read all available payloads - radio.read(&gotByte, 1); - // Since this is a call-response. Respond directly with an ack payload. - gotByte += 1; // Ack payloads are much more efficient than switching to transmit mode to respond to a call - radio.writeAckPayload(pipeNo, &gotByte, 1); // This can be commented out to send empty payloads. - printf("Loaded next response %d \n\r", gotByte); - } - } -} - -int main(int argc, char** argv) -{ - - cout << "RPi/RF24/examples/gettingstarted_call_response_int\n"; - radio.begin(); - radio.enableAckPayload(); // Allow optional ack payloads - radio.enableDynamicPayloads(); // needed for using ACK payloads - radio.printDetails(); // Dump the configuration of the rf unit for debugging - - /********* Role chooser ***********/ - - printf("\n ************ Role Setup ***********\n"); - string input = ""; - char myChar = {0}; - cout << "Choose a role: Enter 0 for pong_back, 1 for ping_out (CTRL+C to exit)\n>"; - getline(cin, input); - - if (input.length() == 1) { - myChar = input[0]; - if (myChar == '0') { - cout << "Role: Pong Back, awaiting transmission " << endl - << endl; - } - else { - cout << "Role: Ping Out, starting transmission " << endl - << endl; - role = role_ping_out; - } - } - - /***********************************/ - // This opens two pipes for these two nodes to communicate - // back and forth. - if (!radioNumber) { - radio.openWritingPipe(addresses[0]); - radio.openReadingPipe(1, addresses[1]); - } - else { - radio.openWritingPipe(addresses[1]); - radio.openReadingPipe(1, addresses[0]); - } - radio.startListening(); - radio.writeAckPayload(1, &counter, 1); - - radio.maskIRQ(1, 1, 0); //Mask tx_ok & tx_fail interrupts - attachInterrupt(interruptPin, INT_EDGE_FALLING, intHandler); //Attach interrupt to bcm pin 23 - - // forever loop - while (1) { - - /****************** Ping Out Role ***************************/ - - if (role == role_ping_out) { // Radio is in ping mode - - uint8_t gotByte; // Initialize a variable for the incoming response - - radio.stopListening(); // First, stop listening so we can talk. - printf("Now sending %d as payload. ", counter); // Use a simple byte counter as payload - unsigned long time = millis(); // Record the current microsecond count - - if (radio.write(&counter, 1)) // Send the counter variable to the other radio - { - if (!radio.available()) { // If nothing in the buffer, we got an ack but it is blank - printf("Got blank response. round-trip delay: %lu ms\n\r", millis() - time); - } - else { - while (radio.available()) // If an ack with payload was received - { - radio.read(&gotByte, 1); // Read it, and display the response time - printf("Got response %d, round-trip delay: %lu ms\n\r", gotByte, millis() - time); - counter++; // Increment the counter variable - } - } - } - else { - printf("Sending failed.\n\r"); // If no ack response, sending failed - } - sleep(1); // Try again later - } - - /****************** Pong Back Role ***************************/ - // This is done using ACK payloads & IRQ - - } //while 1 -} //main diff --git a/RF24/examples_linux/interrupts/gettingstarted_call_response_int2.cpp b/RF24/examples_linux/interrupts/gettingstarted_call_response_int2.cpp deleted file mode 100644 index f7fe2e35df797145cc44269e3e8e705ded2f391b..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/interrupts/gettingstarted_call_response_int2.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* -TMRh20 2014 - Updated to work with optimized RF24 Arduino library -*/ - -/** - * Example for efficient call-response using ack-payloads - * - * This example continues to make use of all the normal functionality of the radios including - * the auto-ack and auto-retry features, but allows ack-payloads to be written optionlly as well. - * This allows very fast call-response communication, with the responding radio never having to - * switch out of Primary Receiver mode to send back a payload, but having the option to switch to - * primary transmitter if wanting to initiate communication instead of respond to a commmunication. - */ - -#include <cstdlib> -#include <iostream> -#include <sstream> -#include <string> -#include <unistd.h> -#include <RF24/RF24.h> - -using namespace std; - -// -// Hardware configuration -// Configure the appropriate pins for your connections - -/****************** Raspberry Pi ***********************/ - -RF24 radio(22, 0); - -/********** User Config *********/ -// Assign a unique identifier for this node, 0 or 1. Arduino example uses radioNumber 0 by default. -bool radioNumber = 1; -int interruptPin = 23; -/********************************/ - -// Radio pipe addresses for the 2 nodes to communicate. -const uint8_t addresses[][6] = {"1Node", "2Node"}; - -bool role_ping_out = 1, role_pong_back = 0, role = 0; -uint8_t counter = 1; // A single byte to keep track of the data being sent back and forth -uint32_t timer = 0; - -void intHandler() -{ - - bool tx_ok, tx_fail, rx; - radio.whatHappened(tx_ok, tx_fail, rx); - - if (tx_fail) { - printf("Sending failed.\n\r"); - } - - if (role == role_ping_out && tx_ok) { - if (!radio.available()) { - printf("Got blank response. round-trip delay: %u ms\n\r", millis() - timer); - } - } - - if (role == role_ping_out) { - while (radio.available()) { - uint8_t gotByte; - radio.read(&gotByte, 1); - printf("Got response %d, round-trip delay: %u ms\n\r", gotByte, millis() - timer); - counter++; - } - } - - if (role == role_pong_back) { - if (tx_ok) { - printf("Ack Payload Sent\n"); - } - uint8_t pipeNo, gotByte; - if (radio.available(&pipeNo)) { - radio.read(&gotByte, 1); - - gotByte += 1; - radio.writeAckPayload(pipeNo, &gotByte, 1); - printf("Loaded next response %d \n\r", gotByte); - } - } -} - -int main(int argc, char** argv) -{ - - cout << "RPi/RF24/examples/gettingstarted_call_response\n"; - radio.begin(); - radio.enableAckPayload(); // Allow optional ack payloads - radio.enableDynamicPayloads(); // needed for using ACK payloads - radio.printDetails(); // Dump the configuration of the rf unit for debugging - - /********* Role chooser ***********/ - - printf("\n ************ Role Setup ***********\n"); - string input = ""; - char myChar = {0}; - cout << "Choose a role: Enter 0 for pong_back, 1 for ping_out (CTRL+C to exit)\n>"; - getline(cin, input); - - if (input.length() == 1) { - myChar = input[0]; - if (myChar == '0') { - cout << "Role: Pong Back, awaiting transmission " << endl - << endl; - } - else { - cout << "Role: Ping Out, starting transmission " << endl - << endl; - role = role_ping_out; - } - } - - /***********************************/ - // This opens two pipes for these two nodes to communicate - // back and forth. - if (!radioNumber) { - radio.openWritingPipe(addresses[0]); - radio.openReadingPipe(1, addresses[1]); - } - else { - radio.openWritingPipe(addresses[1]); - radio.openReadingPipe(1, addresses[0]); - } - radio.startListening(); - radio.writeAckPayload(1, &counter, 1); - - attachInterrupt(interruptPin, INT_EDGE_FALLING, intHandler); //Attach interrupt to bcm pin 23 - - // forever loop - while (1) { - - /****************** Ping Out Role ***************************/ - - if (role == role_ping_out) // Radio is in ping mode - { - //uint8_t gotByte; // Initialize a variable for the incoming response - - radio.stopListening(); // First, stop listening so we can talk. - printf("Now sending %d as payload. ", counter); // Use a simple byte counter as payload - timer = millis(); // Record the current microsecond count - - radio.startWrite(&counter, 1, false); // Send the counter variable to the other radio - sleep(1); // Try again later - } - - /****************** Pong Back Role ***************************/ - // This is done by using ACK payloads & IRQ - - } //while 1 -} //main diff --git a/RF24/examples_linux/interrupts/pingpair_dyn_int.cpp b/RF24/examples_linux/interrupts/pingpair_dyn_int.cpp deleted file mode 100644 index 4c03c5ee712167292b935b63f324e46a64013026..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/interrupts/pingpair_dyn_int.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - TMRh20 2014 - Optimized RF24 Library Fork -*/ - -/** - * Example using Dynamic Payloads - * - * This is an example of how to use payloads of a varying (dynamic) size. - */ - -#include <cstdlib> -#include <iostream> -#include <sstream> -#include <string> -#include <RF24/RF24.h> - -using namespace std; -// -// Hardware configuration -// Configure the appropriate pins for your connections - -/****************** Raspberry Pi ***********************/ - -RF24 radio(22, 0); // CE GPIO, CSN SPI-BUS - -int interruptPin = 23; // GPIO pin for interrupts - -/**************************************************************/ - -// Radio pipe addresses for the 2 nodes to communicate. -const uint64_t pipes[2] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL}; - -const int min_payload_size = 4; -const int max_payload_size = 32; -const int payload_size_increments_by = 1; -int next_payload_size = min_payload_size; - -char receive_payload[max_payload_size + 1]; // +1 to allow room for a terminating NULL char -bool role_ping_out = 1, role_pong_back = 0; -bool role = 0; - -void intHandler() -{ - // - // Pong back role. Receive each packet, dump it out, and send it back - // - - if (role == role_pong_back) { - // if there is data ready - if (radio.available()) { - // Dump the payloads until we've gotten everything - uint8_t len = 0; - - while (radio.available()) { - // Fetch the payload, and see if this was the last one. - len = radio.getDynamicPayloadSize(); - radio.read(receive_payload, len); - - // Put a zero at the end for easy printing - receive_payload[len] = 0; - - // Spew it - printf("Got payload size=%i value=%s\n\r", len, receive_payload); - } - - // First, stop listening so we can talk - radio.stopListening(); - - // Send the final one back. - radio.write(receive_payload, len); - printf("Sent response.\n\r"); - - // Now, resume listening so we catch the next packets. - radio.startListening(); - } - } -} - -int main(int argc, char** argv) -{ - - // Print preamble: - cout << "RF24/examples/pingpair_dyn/\n"; - - // Setup and configure rf radio - radio.begin(); - radio.enableDynamicPayloads(); - radio.setRetries(5, 15); - radio.printDetails(); - - /********* Role chooser ***********/ - - printf("\n ************ Role Setup ***********\n"); - string input = ""; - char myChar = {0}; - cout << "Choose a role: Enter 0 for receiver, 1 for transmitter (CTRL+C to exit) \n>"; - getline(cin, input); - - if (input.length() == 1) { - myChar = input[0]; - if (myChar == '0') { - cout << "Role: Pong Back, awaiting transmission " << endl - << endl; - } - else { - cout << "Role: Ping Out, starting transmission " << endl - << endl; - role = role_ping_out; - } - } - /***********************************/ - - if (role == role_ping_out) { - radio.openWritingPipe(pipes[0]); - radio.openReadingPipe(1, pipes[1]); - } - else { - radio.openWritingPipe(pipes[1]); - radio.openReadingPipe(1, pipes[0]); - radio.startListening(); - } - attachInterrupt(interruptPin, INT_EDGE_FALLING, intHandler); //Attach interrupt to bcm pin 23 - - // forever loop - while (1) { - - if (role == role_ping_out) { - // The payload will always be the same, what will change is how much of it we send. - static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012"; - - // First, stop listening so we can talk. - radio.stopListening(); - - // Take the time, and send it. This will block until complete - printf("Now sending length %i...", next_payload_size); - radio.write(send_payload, next_payload_size); - - // Now, continue listening - radio.startListening(); - - // Wait here until we get a response, or timeout - unsigned long started_waiting_at = millis(); - bool timeout = false; - while (!radio.available() && !timeout) { - if (millis() - started_waiting_at > 500) { - timeout = true; - } - } - - // Describe the results - if (timeout) { - printf("Failed, response timed out.\n\r"); - } - else { - // Grab the response, compare, and send to debugging spew - uint8_t len = radio.getDynamicPayloadSize(); - radio.read(receive_payload, len); - - // Put a zero at the end for easy printing - receive_payload[len] = 0; - - // Spew it - printf("Got response size=%i value=%s\n\r", len, receive_payload); - } - - // Update size for next time. - next_payload_size += payload_size_increments_by; - if (next_payload_size > max_payload_size) { - next_payload_size = min_payload_size; - } - - // Try again 1s later - delay(100); - } - } -} diff --git a/RF24/examples_linux/interrupts/transfer_interrupt.cpp b/RF24/examples_linux/interrupts/transfer_interrupt.cpp deleted file mode 100644 index 46387bf2d57f970b5cbc5533e1cf7faa453c7b43..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/interrupts/transfer_interrupt.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -TMRh20 2014 - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - */ - -/** General Data Transfer Rate Test - * This example demonstrates basic data transfer functionality with the - updated library. This example will display the transfer rates acheived using - the slower form of high-speed transfer using blocking-writes. - */ - -#include <cstdlib> -#include <iostream> -#include <sstream> -#include <string> -#include <RF24/RF24.h> -#include <unistd.h> - -using namespace std; -// -// Hardware configuration -// - -/****************** Raspberry Pi ***********************/ - -// Radio CE Pin, CSN Pin, SPI Speed -// See http://www.airspayce.com/mikem/bcm2835/group__constants.html#ga63c029bd6500167152db4e57736d0939 and the related enumerations for pin information. - -// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz -//RF24 radio(RPI_V2_GPIO_P1_22, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ); - -// NEW: Setup for RPi B+ -//RF24 radio(RPI_BPLUS_GPIO_J8_15,RPI_BPLUS_GPIO_J8_24, BCM2835_SPI_SPEED_8MHZ); - -// Setup for GPIO 15 CE and CE0 CSN with SPI Speed @ 8Mhz -RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ); - -/*** RPi Alternate ***/ -//Note: Specify SPI BUS 0 or 1 instead of CS pin number. -// See http://tmrh20.github.io/RF24/RPi.html for more information on usage - -//RPi Alternate, with MRAA -//RF24 radio(15,0); - -//RPi Alternate, with SPIDEV - Note: Edit RF24/arch/BBB/spi.cpp and set 'this->device = "/dev/spidev0.0";;' or as listed in /dev -//RF24 radio(22,0); - -/****************** Linux (BBB,x86,etc) ***********************/ - -// See http://tmrh20.github.io/RF24/pages.html for more information on usage -// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV - -// Setup for ARM(Linux) devices like BBB using spidev (default is "/dev/spidev1.0" ) -//RF24 radio(115,0); - -//BBB Alternate, with mraa -// CE pin = (Header P9, Pin 13) = 59 = 13 + 46 -//Note: Specify SPI BUS 0 or 1 instead of CS pin number. -//RF24 radio(59,0); - -/**************************************************************/ - -// Radio pipe addresses for the 2 nodes to communicate. -const uint64_t addresses[2] = {0xABCDABCD71LL, 0x544d52687CLL}; - -uint8_t data[32]; -unsigned long startTime, stopTime, counter, rxTimer = 0; - -void intHandler() -{ - //Read as long data is available - //Single interrupts may be lost if a lot of data comes in. - while (radio.available()) { - radio.read(&data, 32); - counter++; - } -} - -int main(int argc, char** argv) -{ - - bool role_ping_out = 1, role_pong_back = 0; - bool role = 0; - - // Print preamble: - - cout << "RF24/examples/Transfer/\n"; - - radio.begin(); // Setup and configure rf radio - radio.setChannel(1); - radio.setPALevel(RF24_PA_MAX); - radio.setDataRate(RF24_1MBPS); - radio.setAutoAck(1); // Ensure autoACK is enabled - radio.setRetries(2, 15); // Optionally, increase the delay between retries & # of retries - radio.setCRCLength(RF24_CRC_8); // Use 8-bit CRC for performance - radio.printDetails(); - /********* Role chooser ***********/ - - printf("\n ************ Role Setup ***********\n"); - string input = ""; - char myChar = {0}; - cout << "Choose a role: Enter 0 for receiver, 1 for transmitter (CTRL+C to exit)\n>"; - getline(cin, input); - - attachInterrupt(23, INT_EDGE_FALLING, intHandler); //Attach interrupt to bcm pin 23 - - if (input.length() == 1) { - myChar = input[0]; - if (myChar == '0') { - cout << "Role: Pong Back, awaiting transmission " << endl - << endl; - } - else { - cout << "Role: Ping Out, starting transmission " << endl - << endl; - role = role_ping_out; - } - } - /***********************************/ - - if (role == role_ping_out) { - radio.openWritingPipe(addresses[1]); - radio.openReadingPipe(1, addresses[0]); - radio.stopListening(); - } - else { - radio.openWritingPipe(addresses[0]); - radio.openReadingPipe(1, addresses[1]); - radio.startListening(); - } - - for (int i = 0; i < 32; i++) { - data[i] = rand() % 255; //Load the buffer with random data - } - - // forever loop - while (1) { - if (role == role_ping_out) { - sleep(2); - printf("Initiating Basic Data Transfer\n\r"); - - long int cycles = 10000; //Change this to a higher or lower number. - - // unsigned long pauseTime = millis(); //Uncomment if autoAck == 1 ( NOACK ) - startTime = millis(); - - for (int i = 0; i < cycles; i++) { //Loop through a number of cycles - data[0] = i; //Change the first byte of the payload for identification - if (!radio.writeFast(&data, 32)) { //Write to the FIFO buffers - counter++; //Keep count of failed payloads - } - - //This is only required when NO ACK ( enableAutoAck(0) ) payloads are used - /* if(millis() - pauseTime > 3){ // Need to drop out of TX mode every 4ms if sending a steady stream of multicast data - pauseTime = millis(); - radio.txStandBy(); // This gives the PLL time to sync back up - } - */ - } - stopTime = millis(); - - if (!radio.txStandBy()) { - counter += 3; - } - - float numBytes = cycles * 32; - float rate = numBytes / (stopTime - startTime); - - printf("Transfer complete at %.2f KB/s \n\r", rate); - printf("%lu of %lu Packets Failed to Send\n\r", counter, cycles); - counter = 0; - } - - if (role == role_pong_back) { - if (millis() - rxTimer > 1000) { - rxTimer = millis(); - printf("Rate: "); - float numBytes = counter * 32; - printf("%.2f KB/s \n\r", numBytes / 1000); - printf("Payload Count: %lu \n\r", counter); - counter = 0; - } - delay(2); - } - - } // loop -} // main diff --git a/RF24/examples_linux/manualAcknowledgements.cpp b/RF24/examples_linux/manualAcknowledgements.cpp deleted file mode 100644 index f352f33e2a0f9a1912bb4a96f6bfb65981059576..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/manualAcknowledgements.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. - * This example still uses ACK packets, but they have no payloads. Instead the - * acknowledging response is sent with `write()`. This tactic allows for more - * updated acknowledgement payload data, where actual ACK payloads' data are - * outdated by 1 transmission because they have to loaded before receiving a - * transmission. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ -#include <ctime> // time() -#include <iostream> // cin, cout, endl -#include <string> // string, getline() -#include <time.h> // CLOCK_MONOTONIC_RAW, timespec, clock_gettime() -#include <RF24/RF24.h> // RF24, RF24_PA_LOW, delay() - -using namespace std; - -/****************** Linux ***********************/ -// Radio CE Pin, CSN Pin, SPI Speed -// CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use their own pin numbering -// CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -// ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -// Generic: -RF24 radio(22, 0); -/****************** Linux (BBB,x86,etc) ***********************/ -// See http://nRF24.github.io/RF24/pages.html for more information on usage -// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV - -// For this example, we'll be using a payload containing -// a string & an integer number that will be incremented -// on every successful transmission. -// Make a data structure to store the entire payload of different datatypes -struct PayloadStruct -{ - char message[7]; // only using 6 characters for TX & RX payloads - uint8_t counter; -}; -PayloadStruct payload; - -void setRole(); // prototype to set the node's role -void master(); // prototype of the TX node's behavior -void slave(); // prototype of the RX node's behavior - -// custom defined timer for evaluating transmission time in microseconds -struct timespec startTimer, endTimer; -uint32_t getMicros(); // prototype to get ellapsed time in microseconds - -int main(int argc, char** argv) -{ - - // perform hardware check - if (!radio.begin()) { - cout << "radio hardware is not responding!!" << endl; - return 0; // quit now - } - - // append a NULL terminating 0 for printing as a c-string - payload.message[6] = 0; - - // Let these addresses be used for the pair of nodes used in this example - uint8_t address[2][6] = {"1Node", "2Node"}; - // the TX address^ , ^the RX address - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // print example's name - cout << argv[0] << endl; - - // Set the radioNumber via the terminal on startup - cout << "Which radio is this? Enter '0' or '1'. Defaults to '0' "; - string input; - getline(cin, input); - radioNumber = input.length() > 0 && (uint8_t)input[0] == 49; - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // ready to execute program now - setRole(); // calls master() or slave() based on user input - return 0; -} // main - -/** - * set this node's role from stdin stream. - * this only considers the first char as input. - */ -void setRole() -{ - string input = ""; - while (!input.length()) { - cout << "*** PRESS 'T' to begin transmitting to the other node\n"; - cout << "*** PRESS 'R' to begin receiving from the other node\n"; - cout << "*** PRESS 'Q' to exit" << endl; - getline(cin, input); - if (input.length() >= 1) { - if (input[0] == 'T' || input[0] == 't') - master(); - else if (input[0] == 'R' || input[0] == 'r') - slave(); - else if (input[0] == 'Q' || input[0] == 'q') - break; - else - cout << input[0] << " is an invalid input. Please try again." << endl; - } - input = ""; // stay in the while loop - } // while -} // setRole() - -/** - * make this node act as the transmitter - */ -void master() -{ - - memcpy(payload.message, "Hello ", 6); // set the outgoing message - radio.stopListening(); // put in TX mode - - unsigned int failures = 0; // keep track of failures - while (failures < 6) { - clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - - if (report) { - // transmission successful; wait for response and print results - - radio.startListening(); // put in RX mode - unsigned long start_timeout = millis(); // timer to detect no response - while (!radio.available()) { // wait for response - if (millis() - start_timeout > 200) // only wait 200 ms - break; - } - unsigned long ellapsedTime = getMicros(); // end the timer - radio.stopListening(); // put back in TX mode - - // print summary of transactions - uint8_t pipe; - cout << "Transmission successful! "; - if (radio.available(&pipe)) { // is there a payload received? grab the pipe number that received it - uint8_t bytes = radio.getPayloadSize(); // grab the incoming payload size - cout << "Round trip delay = "; - cout << ellapsedTime; // print the timer result - cout << " us. Sent: " << payload.message; // print outgoing message - cout << (unsigned int)payload.counter; // print outgoing counter - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming payload - cout << " Recieved " << (unsigned int)bytes; // print incoming payload size - cout << " on pipe " << (unsigned int)pipe; // print RX pipe number - cout << ": " << received.message; // print the incoming message - cout << (unsigned int)received.counter; // print the incoming counter - cout << endl; - payload.counter = received.counter; // save incoming counter for next outgoing counter - } - else { - cout << "Recieved no response." << endl; // no response received - } - } - else { - cout << "Transmission failed or timed out"; // payload was not delivered - cout << endl; - failures++; // increment failure counter - } // report - - // to make this example readable in the terminal - delay(1000); // slow transmissions down by 1 second - } // while - - cout << failures << " failures detected. Leaving TX role." << endl; -} // master - -/** - * make this node act as the receiver - */ -void slave() -{ - memcpy(payload.message, "World ", 6); // set the response message - radio.startListening(); // put in RX mode - - time_t startTimer = time(nullptr); // start a timer - while (time(nullptr) - startTimer < 6) { // use 6 second timeout - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getPayloadSize(); // get size of incoming payload - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming payload - payload.counter = received.counter + 1; // increment payload for response - - // transmit response & save result to `report` - radio.stopListening(); // put in TX mode - radio.writeFast(&payload, sizeof(payload)); // load response into TX FIFO - bool report = radio.txStandBy(150); // keep retrying for 150 ms - radio.startListening(); // put back in RX mode - - // print summary of transactions - cout << "Received " << (unsigned int)bytes; // print the size of the payload - cout << " bytes on pipe "; - cout << (unsigned int)pipe; // print the pipe number - cout << ": " << received.message; // print incoming message - cout << (unsigned int)received.counter; // print incoming counter - - if (report) { - cout << " Sent: " << payload.message; // print outgoing message - cout << (unsigned int)payload.counter; // print outgoing counter - cout << endl; - } - else { - cout << " Response failed to send." << endl; // failed to send response - } - startTimer = time(nullptr); // reset timer - } // available - } // while - - cout << "Nothing received in 6 seconds. Leaving RX role." << endl; - radio.stopListening(); // recommended idle mode is TX mode -} // slave - -/** - * Calculate the ellapsed time in microseconds - */ -uint32_t getMicros() -{ - // this function assumes that the timer was started using - // `clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer);` - - clock_gettime(CLOCK_MONOTONIC_RAW, &endTimer); - uint32_t seconds = endTimer.tv_sec - startTimer.tv_sec; - uint32_t useconds = (endTimer.tv_nsec - startTimer.tv_nsec) / 1000; - - return ((seconds)*1000 + useconds) + 0.5; -} diff --git a/RF24/examples_linux/manual_acknowledgements.py b/RF24/examples_linux/manual_acknowledgements.py deleted file mode 100644 index e5539df47922a19dbf662538b50e7cd97aadddb6..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/manual_acknowledgements.py +++ /dev/null @@ -1,240 +0,0 @@ -""" -A simple example of sending data from 1 nRF24L01 transceiver to another -with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. -This example still uses ACK packets, but they have no payloads. Instead the -acknowledging response is sent with `write()`. This tactic allows for more -updated acknowledgement payload data, where actual ACK payloads' data are -outdated by 1 transmission because they have to loaded before receiving a -transmission. - -This example was written to be used on 2 devices acting as 'nodes'. -""" -import sys -import argparse -import time -from RF24 import RF24, RF24_PA_LOW - - -parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter -) -parser.add_argument( - "-n", - "--node", - type=int, - choices=range(2), - help="the identifying radio number (or node ID number)", -) -parser.add_argument( - "-r", - "--role", - type=int, - choices=range(2), - help="'1' specifies the TX role. '0' specifies the RX role.", -) - -########### USER CONFIGURATION ########### -# See https://github.com/TMRh20/RF24/blob/master/pyRF24/readme.md -# Radio CE Pin, CSN Pin, SPI Speed -# CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use -# their own pin numbering -# CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -# ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -# Generic: -radio = RF24(22, 0) -################## Linux (BBB,x86,etc) ######################### -# See http://nRF24.github.io/RF24/pages.html for more information on usage -# See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -# See https://www.kernel.org/doc/Documentation/spi/spidev for more -# information on SPIDEV - -# using the python keyword global is bad practice. Instead we'll use a 1 item -# list to store our integer number for the payloads' counter -counter = [0] - - -def master(): - """Transmits a message and an incrementing integer every second, then - wait for a response for up to 200 ms. - """ - radio.stopListening() # put radio in TX mode - failures = 0 - while failures < 6: - # use bytes() to pack our counter data into the payload - # NOTE b"\x00" byte is a c-string's NULL terminating 0 - buffer = b"Hello \x00" + bytes(counter) - start_timer = time.monotonic_ns() # start timer - result = radio.write(buffer) - if not result: - failures += 1 - print("Transmission failed or timed out") - else: - radio.startListening() # put radio in RX mode - timout = time.monotonic() * 1000 + 200 # use 200 ms timeout - # declare a variable to save the incoming response - while not radio.available() and time.monotonic() * 1000 < timout: - pass # wait for incoming payload or timeout - radio.stopListening() # put radio in TX mode - end_timer = time.monotonic_ns() # end timer - decoded = buffer[:6].decode("utf-8") - print( - f"Transmission successful. Sent: {decoded}{counter[0]}.", - end=" ", - ) - has_payload, pipe_number = radio.available_pipe() - if has_payload: - # grab the incoming payload - received = radio.read(radio.payloadSize) - # NOTE received[7:8] discards NULL terminating 0 - counter[0] = received[7:8][0] # save the counter - decoded = bytes(received[:6]).decode("utf-8") - print( - f"Received {radio.payloadSize} bytes", - f"on pipe {pipe_number}: {decoded}{counter[0]}.", - f"Round-trip delay: {(end_timer - start_timer) / 1000} us.", - ) - else: - print("No response received.") - time.sleep(1) # make example readable by slowing down transmissions - print(failures, "failures detected. Leaving TX role.") - - -def slave(timeout: int = 6): - """Listen for any payloads and print the transaction - - :param int timeout: The number of seconds to wait (with no transmission) - until exiting function. - """ - radio.startListening() # put radio in RX mode - - start_timer = time.monotonic() # start a timer to detect timeout - while (time.monotonic() - start_timer) < timeout: - # receive `count` payloads or wait 6 seconds till timing out - has_payload, pipe_number = radio.available_pipe() - if has_payload: - received = radio.read(radio.payloadSize) # fetch the payload - # NOTE received[7:8] discards NULL terminating 0 - # increment the counter from received payload - counter[0] = received[7:8][0] + 1 if received[7:8][0] < 255 else 0 - # use bytes() to pack our counter data into the payload - # NOTE b"\x00" byte is a c-string's NULL terminating 0 - buffer = b"World \x00" + bytes(counter) - radio.stopListening() # put radio in TX mode - radio.writeFast(buffer) # load response into TX FIFO - # keep retrying to send response for 150 milliseconds - result = radio.txStandBy(150) # save response's result - # NOTE txStandBy() flushes TX FIFO on transmission failure - radio.startListening() # put radio back in RX mode - # print the payload received payload - decoded = bytes(received[:6]).decode("utf-8") - print( - f"Received {radio.payloadSize} bytes" - f"on pipe {pipe_number}: {decoded}{received[7:8][0]}.", - end=" ", - ) - if result: # did response succeed? - # print response's payload - decoded = buffer[:6].decode("utf-8") - print(f"Sent: {decoded}{counter[0]}") - else: - print("Response failed or timed out") - start_timer = time.monotonic() # reset the timeout timer - - print("Nothing received in", timeout, "seconds. Leaving RX role") - # recommended behavior is to keep in TX mode while idle - radio.stopListening() # put the radio in TX mode - - -def set_role() -> bool: - """Set the role using stdin stream. Timeout arg for slave() can be - specified using a space delimiter (e.g. 'R 10' calls `slave(10)`) - - :return: - - True when role is complete & app should continue running. - - False when app should exit - """ - user_input = ( - input( - "*** Enter 'R' for receiver role.\n" - "*** Enter 'T' for transmitter role.\n" - "*** Enter 'Q' to quit example.\n" - ) - or "?" - ) - user_input = user_input.split() - if user_input[0].upper().startswith("R"): - if len(user_input) > 1: - slave(int(user_input[1])) - else: - slave() - return True - if user_input[0].upper().startswith("T"): - master() - return True - if user_input[0].upper().startswith("Q"): - radio.powerDown() - return False - print(user_input[0], "is an unrecognized input. Please try again.") - return set_role() - - -if __name__ == "__main__": - - args = parser.parse_args() # parse any CLI args - - # initialize the nRF24L01 on the spi bus - if not radio.begin(): - raise RuntimeError("radio hardware is not responding") - - # For this example, we will use different addresses - # An address need to be a buffer protocol object (bytearray) - address = [b"1Node", b"2Node"] - # It is very helpful to think of an address as a path instead of as - # an identifying device destination - - print(sys.argv[0]) # print example name - - # to use different addresses on a pair of radios, we need a variable to - # uniquely identify which address this radio will use to transmit - # 0 uses address[0] to transmit, 1 uses address[1] to transmit - radio_number = args.node # uses default value from `parser` - if args.node is None: # if '--node' arg wasn't specified - radio_number = bool( - int(input("Which radio is this? Enter '0' or '1'. Defaults to '0' ") or 0) - ) - - # set the Power Amplifier level to -12 dBm since this test example is - # usually run with nRF24L01 transceivers in close proximity of each other - radio.setPALevel(RF24_PA_LOW) # RF24_PA_MAX is default - - # set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radio_number]) # always uses pipe 0 - - # set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[not radio_number]) # using pipe 1 - - # To save time during transmission, we'll set the payload size to be only - # what we need. For this example, we'll be using a byte for the - # payload counter and 7 bytes for the payload message - radio.payloadSize = 8 - - # for debugging, we have 2 options that print a large block of details - # (smaller) function that prints raw register values - # radio.printDetails() - # (larger) function that prints human readable data - # radio.printPrettyDetails() - - try: - if args.role is None: # if not specified with CLI arg '-r' - while set_role(): - pass # continue example until 'Q' is entered - else: # if role was set using CLI args - # run role once and exit - if bool(args.role): - master() - else: - slave() - except KeyboardInterrupt: - print(" Keyboard Interrupt detected. Powering down radio.") - radio.powerDown() diff --git a/RF24/examples_linux/multiceiverDemo.cpp b/RF24/examples_linux/multiceiverDemo.cpp deleted file mode 100644 index ee8b5ec601a9cba779a27a112ba91d2227c0715b..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/multiceiverDemo.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from as many as 6 nRF24L01 transceivers to - * 1 receiving transceiver. This technique is trademarked by - * Nordic Semiconductors as "MultiCeiver". - * - * This example was written to be used on up to 6 devices acting as TX nodes & - * only 1 device acting as the RX node (that's a maximum of 7 devices). - * Use `ctrl+c` to quit at any time. - */ -#include <ctime> // time() -#include <cstring> // strcmp() -#include <iostream> // cin, cout, endl -#include <string> // string, getline() -#include <time.h> // CLOCK_MONOTONIC_RAW, timespec, clock_gettime() -#include <RF24/RF24.h> // RF24, RF24_PA_LOW, delay() - -using namespace std; - -/****************** Linux ***********************/ -// Radio CE Pin, CSN Pin, SPI Speed -// CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use their own pin numbering -// CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -// ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -// Generic: -RF24 radio(22, 0); -/****************** Linux (BBB,x86,etc) ***********************/ -// See http://nRF24.github.io/RF24/pages.html for more information on usage -// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV - -// For this example, we'll be using 6 addresses; 1 for each TX node -// It is very helpful to think of an address as a path instead of as -// an identifying device destination -// Notice that the last byte is the only byte that changes in the last 5 -// addresses. This is a limitation of the nRF24L01 transceiver for pipes 2-5 -// because they use the same first 4 bytes from pipe 1. -uint64_t address[6] = {0x7878787878LL, - 0xB3B4B5B6F1LL, - 0xB3B4B5B6CDLL, - 0xB3B4B5B6A3LL, - 0xB3B4B5B60FLL, - 0xB3B4B5B605LL}; - -// For this example, we'll be using a payload containing -// a node ID number and a single integer number that will be incremented -// on every successful transmission. -// Make a data structure to use as a payload. -struct PayloadStruct -{ - unsigned int nodeID; - unsigned int payloadID; -}; -PayloadStruct payload; - -void setRole(); // prototype to set the node's role -void master(unsigned int); // prototype of a TX node's behavior -void slave(); // prototype of the RX node's behavior -void printHelp(string); // prototype to function that explain CLI arg usage - -// custom defined timer for evaluating transmission time in microseconds -struct timespec startTimer, endTimer; -uint32_t getMicros(); // prototype to get ellapsed time in microseconds - -int main(int argc, char** argv) -{ - - // perform hardware check - if (!radio.begin()) { - cout << "radio hardware is not responding!!" << endl; - return 0; // quit now - } - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - unsigned int nodeNumber = 'R'; // integers 0-5 = TX node; character 'R' or integer 82 = RX node - - bool foundArgNode = false; - if (argc > 1) { - if ((argc - 1) != 2) { - // CLI arg "-n"/"--node" needs an option specified for it - // only 1 arg is expected, so only traverse the first "--arg option" pair - printHelp(string(argv[0])); - return 0; - } - else if (strcmp(argv[1], "-n") == 0 || strcmp(argv[1], "--node") == 0) { - // "-n" or "--node" has been specified - foundArgNode = true; - if ((argv[2][0] - 48) < 6 && (argv[2][0] - 48) >= 0) { - nodeNumber = argv[2][0] - 48; - } - else if (argv[2][0] == 'R' || argv[2][0] == 'r') { - nodeNumber = 'R'; - } - else { - printHelp(string(argv[0])); - return 0; - } - } - else { - // "-n"/"--node" arg was not specified - printHelp(string(argv[0])); - return 0; - } - } - - // print example's name - cout << argv[0] << endl; - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // 2x int datatype occupy 8 bytes - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // ready to execute program now - if (!foundArgNode) { - setRole(); // calls master() or slave() based on user input - } - else { - nodeNumber < 6 ? master(nodeNumber) : slave(); - } - return 0; -} - -/** - * set this node's role from stdin stream. - * this only considers the first char as input. - */ -void setRole() -{ - - string input = ""; - while (!input.length()) { - cout << "*** Enter a number between 0 and 5 (inclusive) to act as\n"; - cout << " a unique node number that transmits to the RX node.\n"; - cout << "*** PRESS 'R' to begin receiving from the other nodes\n"; - cout << "*** PRESS 'Q' to exit" << endl; - getline(cin, input); - if (input.length() >= 1) { - unsigned int toNumber = (unsigned int)(input[0]) - 48; - if (toNumber < 6 && toNumber >= 0) - master(toNumber); - else if (input[0] == 'R' || input[0] == 'r') - slave(); - else if (input[0] == 'Q' || input[0] == 'q') - break; - else - cout << input[0] << " is an invalid input. Please try again." << endl; - } - input = ""; // stay in the while loop - } // while -} // setRole - -/** - * act as unique TX node identified by the `role` number - */ -void master(unsigned int role) -{ - // set the payload's nodeID & reset the payload's identifying number - payload.nodeID = role; - payload.payloadID = 0; - - // Set the address on pipe 0 to the RX node. - radio.stopListening(); // put radio in TX mode - radio.openWritingPipe(address[role]); - - // According to the datasheet, the auto-retry features's delay value should - // be "skewed" to allow the RX node to receive 1 transmission at a time. - // So, use varying delay between retry attempts and 15 (at most) retry attempts - radio.setRetries(((role * 3) % 12) + 3, 15); // maximum value is 15 for both args - - unsigned int failures = 0; - while (failures < 6) { - clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - uint32_t timerEllapsed = getMicros(); // end the timer - - if (report) { - // payload was delivered - cout << "Transmission of PayloadID "; - cout << payload.payloadID; // print payload number - cout << " as node " << payload.nodeID; // print node number - cout << " successful! Time to transmit = "; - cout << timerEllapsed << " us" << endl; // print the timer result - } - else { - // payload was not delivered - failures++; - cout << "Transmission failed or timed out" << endl; - } - payload.payloadID++; // increment payload number - - // to make this example readable in the terminal - delay(1000); // slow transmissions down by 1 second - } // while - cout << failures << " failures detected. Leaving TX role." << endl; -} // master - -/** - * act as the RX node that receives from up to 6 other TX nodes - */ -void slave() -{ - - // Set the addresses for all pipes to TX nodes - for (uint8_t i = 0; i < 6; ++i) - radio.openReadingPipe(i, address[i]); - - radio.startListening(); // put radio in RX mode - - time_t startTimer = time(nullptr); // start a timer - while (time(nullptr) - startTimer < 6) { // use 6 second timeout - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getPayloadSize(); // get the size of the payload - radio.read(&payload, bytes); // fetch payload from FIFO - cout << "Received " << (unsigned int)bytes; // print the size of the payload - cout << " bytes on pipe " << (unsigned int)pipe; // print the pipe number - cout << " from node " << payload.nodeID; // print the payload's origin - cout << ". PayloadID: " << payload.payloadID << endl; // print the payload's number - startTimer = time(nullptr); // reset timer - } - } - cout << "Nothing received in 6 seconds. Leaving RX role." << endl; -} // slave - -/** - * Calculate the ellapsed time in microseconds - */ -uint32_t getMicros() -{ - // this function assumes that the timer was started using - // `clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer);` - - clock_gettime(CLOCK_MONOTONIC_RAW, &endTimer); - uint32_t seconds = endTimer.tv_sec - startTimer.tv_sec; - uint32_t useconds = (endTimer.tv_nsec - startTimer.tv_nsec) / 1000; - - return ((seconds)*1000 + useconds) + 0.5; -} - -/** - * print a manual page of instructions on how to use this example's CLI args - */ -void printHelp(string progName) -{ - cout << "usage: " << progName << " [-h] [-n {0,1,2,3,4,5,r,R}]\n\n" - << "A simple example of sending data from as many as 6 nRF24L01 transceivers to\n" - << "1 receiving transceiver. This technique is trademarked by\n" - << "Nordic Semiconductors as 'MultiCeiver'.\n" - << "\nThis example was written to be used on up to 6 devices acting as TX nodes with\n" - << "another device acting as a RX node (that's a total of 7 devices).\n" - << "\noptional arguments:\n -h, --help\t\tshow this help message and exit\n" - << " -n {0,1,2,3,4,5,r,R}, --node {0,1,2,3,4,5,r,R}" - << "\n\t\t\t0-5 specifies the identifying node ID number for the TX role." - << "\n\t\t\t'r' or 'R' specifies the RX role." << endl; -} diff --git a/RF24/examples_linux/multiceiver_demo.py b/RF24/examples_linux/multiceiver_demo.py deleted file mode 100644 index fe7902e26cc208e631da665f4dbd802bcc892d1b..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/multiceiver_demo.py +++ /dev/null @@ -1,195 +0,0 @@ -""" -A simple example of sending data from as many as 6 nRF24L01 transceivers to -1 receiving transceiver. This technique is trademarked by -Nordic Semiconductors as "MultiCeiver". - -This example was written to be used on up to 6 devices acting as TX nodes & -only 1 device acting as the RX node (that's a maximum of 7 devices). -""" -import sys -import argparse -import time -import struct -from RF24 import RF24, RF24_PA_LOW - - -parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter -) -parser.add_argument( - "-n", - "--node", - choices=("0", "1", "2", "3", "4", "5", "R", "r"), - help="the identifying node ID number for the TX role. " - "Use 'R' or 'r' to specify the RX role", -) - -########### USER CONFIGURATION ########### -# See https://github.com/TMRh20/RF24/blob/master/pyRF24/readme.md -# Radio CE Pin, CSN Pin, SPI Speed -# CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use -# their own pin numbering -# CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -# ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -# Generic: -radio = RF24(22, 0) -################## Linux (BBB,x86,etc) ######################### -# See http://nRF24.github.io/RF24/pages.html for more information on usage -# See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -# See https://www.kernel.org/doc/Documentation/spi/spidev for more -# information on SPIDEV - -# setup the addresses for all transmitting radio nodes -addresses = [ - b"\x78" * 5, - b"\xF1\xB6\xB5\xB4\xB3", - b"\xCD\xB6\xB5\xB4\xB3", - b"\xA3\xB6\xB5\xB4\xB3", - b"\x0F\xB6\xB5\xB4\xB3", - b"\x05\xB6\xB5\xB4\xB3", -] -# It is very helpful to think of an address as a path instead of as -# an identifying device destination - - -def master(node_number): - """start transmitting to the base station. - - :param int node_number: the node's identifying index (from the - the `addresses` list). This is a required parameter - """ - # According to the datasheet, the auto-retry features's delay value should - # be "skewed" to allow the RX node to receive 1 transmission at a time. - # So, use varying delay between retry attempts and 15 (at most) retry attempts - radio.setRetries( - ((node_number * 3) % 12) + 3, 15 - ) # maximum value is 15 for both args - - radio.stopListening() # put radio in TX mode - # set the TX address to the address of the base station. - radio.openWritingPipe(addresses[node_number]) - counter = 0 - failures = 0 - while failures < 6: - counter += 1 - # payloads will include the node_number and a payload ID character - payload = struct.pack("<ii", node_number, counter) - start_timer = time.monotonic_ns() - report = radio.write(payload) - end_timer = time.monotonic_ns() - # show something to see it isn't frozen - print( - f"Transmission of payloadID {counter} as node {node_number}", - end=" ", - ) - if report: - print( - f"successful! Time to transmit = {(end_timer - start_timer) / 1000} us" - ) - else: - failures += 1 - print("failed or timed out") - time.sleep(1) # slow down the test for readability - print(failures, "failures detected. Leaving TX role.") - - -def slave(timeout: int = 10): - """Use the radio as a base station for listening to all nodes - - :param int timeout: The number of seconds to wait (with no transmission) - until exiting function. - """ - # write the addresses to all pipes. - for pipe_n, addr in enumerate(addresses): - radio.openReadingPipe(pipe_n, addr) - radio.startListening() # put radio in RX mode - start_timer = time.monotonic() # start timer - while time.monotonic() - start_timer < timeout: - has_payload, pipe_number = radio.available_pipe() - if has_payload: - # unpack payload - node_id, payload_id = struct.unpack("<ii", radio.read(radio.payloadSize)) - # show the pipe number that received the payload - print( - f"Received {radio.payloadSize} bytes", - f"on pipe {pipe_number} from node {node_id}.", - f"PayloadID: {payload_id}", - ) - start_timer = time.monotonic() # reset timer with every payload - - print("Nothing received in", timeout, "seconds. Leaving RX role") - radio.stopListening() - - -def set_role() -> bool: - """Set the role using stdin stream. Timeout arg for slave() can be - specified using a space delimiter (e.g. 'R 10' calls `slave(10)`) - - :return: - - True when role is complete & app should continue running. - - False when app should exit - """ - user_input = ( - input( - "*** Enter 'R' for receiver role.\n" - "*** Enter a number in range [0, 5] to use a specific node ID for " - "transmitter role.\n" - "*** Enter 'Q' to quit example.\n" - ) - or "?" - ) - user_input = user_input.split() - if user_input[0].upper().startswith("R"): - if len(user_input) > 1: - slave(int(user_input[1])) - else: - slave() - return True - if user_input[0].isdigit() and 0 <= int(user_input[0]) <= 5: - master(int(user_input[0])) - return True - if user_input[0].upper().startswith("Q"): - radio.powerDown() - return False - print(user_input[0], "is an unrecognized input. Please try again.") - return set_role() - - -if __name__ == "__main__": - - args = parser.parse_args() # parse any CLI args - - # initialize the nRF24L01 on the spi bus - if not radio.begin(): - raise RuntimeError("radio hardware is not responding") - - print(sys.argv[0]) # print example name - - # set the Power Amplifier level to -12 dBm since this test example is - # usually run with nRF24L01 transceivers in close proximity of each other - radio.setPALevel(RF24_PA_LOW) # RF24_PA_MAX is default - - # To save time during transmission, we'll set the payload size to be only what - # we need. - # 2 int occupy 8 bytes in memory using struct.pack() - # "ii" means 2 unsigned integers - radio.payloadSize = struct.calcsize("ii") - - # for debugging, we have 2 options that print a large block of details - # radio.printDetails(); # (smaller) function that prints raw register values - # radio.printPrettyDetails(); # (larger) function that prints human readable data - - try: - if args.node is None: # if not specified with CLI arg '-n' - while set_role(): - pass # continue example until 'Q' is entered - else: # if role was set using CLI args - # run role once and exit - if args.node.isdigit(): - master(int(args.node)) - else: - slave() - except KeyboardInterrupt: - print(" Keyboard Interrupt detected. Powering down radio.") - radio.powerDown() diff --git a/RF24/examples_linux/readme.md b/RF24/examples_linux/readme.md deleted file mode 100644 index 4728bd32194462fc070838a5d84e94b2ee4f4197..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -Note: These examples were originally designed for RPi, but should work on any supported Linux platform, with the proper pin configuration. - -See http://tmrh20.github.io/RF24 for more information \ No newline at end of file diff --git a/RF24/examples_linux/scanner.cpp b/RF24/examples_linux/scanner.cpp deleted file mode 100644 index 7a3be9744f530e75369ac58f75edc5785540d71c..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/scanner.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - - - 03/17/2013 : Charles-Henri Hallard (http://hallard.me) - Modified to use with Arduipi board http://hallard.me/arduipi - Changed to use modified bcm2835 and RF24 library - - */ - -/** - * Channel scanner - * - * Example to detect interference on the various channels available. - * This is a good diagnostic tool to check whether you're picking a - * good channel for your application. - * - * Inspired by cpixip. - * See http://arduino.cc/forum/index.php/topic,54795.0.html - */ - -#include <cstdlib> -#include <iostream> -#include <RF24/RF24.h> - -using namespace std; - -/****************** Linux ***********************/ -// Radio CE Pin, CSN Pin, SPI Speed -// CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use their own pin numbering -// CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -// ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -// Generic: -RF24 radio(22, 0); -/****************** Linux (BBB,x86,etc) ***********************/ -// See http://nRF24.github.io/RF24/pages.html for more information on usage -// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV - -// Channel info -const uint8_t num_channels = 126; -uint8_t values[num_channels]; - -const int num_reps = 100; -int reset_array = 0; - -int main(int argc, char** argv) -{ - // Print preamble - - // print example's name - printf("%s", argv[0]); - - // - // Setup and configure rf radio - // - radio.begin(); - - radio.setAutoAck(false); - - // Get into standby mode - radio.startListening(); - radio.stopListening(); - - radio.printDetails(); - - // Print out header, high then low digit - int i = 0; - - while (i < num_channels) { - printf("%x", i >> 4); - ++i; - } - printf("\n"); - - i = 0; - while (i < num_channels) { - printf("%x", i & 0xf); - ++i; - } - printf("\n"); - - // forever loop - while (1) { - // Clear measurement values - memset(values, 0, sizeof(values)); - - // Scan all channels num_reps times - int rep_counter = num_reps; - while (rep_counter--) { - - int i = num_channels; - while (i--) { - - // Select this channel - radio.setChannel(i); - - // Listen for a little - radio.startListening(); - delayMicroseconds(128); - radio.stopListening(); - - // Did we get a carrier? - if (radio.testCarrier()) { - ++values[i]; - } - } - } - - // Print out channel measurements, clamped to a single hex digit - i = 0; - while (i < num_channels) { - if (values[i]) - printf("%x", min(0xf, (values[i] & 0xf))); - else - printf("-"); - - ++i; - } - printf("\n"); - } - - return 0; -} - -// vim:ai:cin:sts=2 sw=2 ft=cpp diff --git a/RF24/examples_linux/scanner.py b/RF24/examples_linux/scanner.py deleted file mode 100644 index 014bca6362177f035ff6ee8e0dcad4e7f471dda6..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/scanner.py +++ /dev/null @@ -1,109 +0,0 @@ -"""A scanner example that uses the python `rich` module to provide -a user-friendly output.""" -import time -from typing import List - -try: - from rich.table import Table - from rich.console import Console - from rich.progress import BarColumn, Progress, TextColumn - from rich.live import Live - from rich.prompt import Prompt, IntPrompt - from rich.style import Style -except ImportError as exc: - raise ImportError( - "This example requires the python `rich` module installed." - "\nInstall it using 'python3 -m pip install rich'" - ) from exc -from RF24 import RF24, RF24_1MBPS, RF24_2MBPS, RF24_250KBPS - -CSN_PIN = 0 # connected to GPIO8 -CE_PIN = 22 # connected to GPIO22 -radio = RF24(CE_PIN, CSN_PIN) - -if not radio.begin(): - raise RuntimeError("Radio hardware not responding!") -radio.setAutoAck(False) - -offered_rates = ["1 Mbps", "2 Mbps", "250 kbps"] -available_rates = [RF24_1MBPS, RF24_2MBPS, RF24_250KBPS] -console = Console() -for i, rate in enumerate(offered_rates): - console.print(f"{i + 1}. {rate}") -DATA_RATE = ( - int(Prompt.ask("Choose the data rate", choices=["1", "2", "3"], default="1")) - 1 -) -radio.setDataRate(available_rates[DATA_RATE]) - -DURATION = IntPrompt.ask("Enter the scan duration (in whole seconds)") -SELECTED_RATE = offered_rates[DATA_RATE] - -CACHE_MAX = 5 # the depth of history to calculate peaks -history = [[False] * CACHE_MAX] * 126 # for tracking peak decay on each channel -signals = [False] * 126 # for tracking the signal count on each channel -totals = [0] * 126 # for the total signal count on each channel - -# create table of progress bars (labeled by frequency channel in MHz) -table = Table.grid(padding=(0, 1)) -progress_bars: List[Progress] = [None] * 126 -for i in range(21): # 21 rows - row = [] - for j in range(i, i + (21 * 6), 21): # 6 columns - COLOR = "white" if int(j / 21) % 2 else "yellow" - progress_bars[j] = Progress( - TextColumn("{task.description}", style=Style(color=COLOR)), - BarColumn(style=Style(color=COLOR)), - TextColumn("{task.fields[signals]}", style=Style(color=COLOR)), - ) - # add only 1 task for each progress bar - progress_bars[j].add_task(f"{2400 + (j)}", total=CACHE_MAX, signals="-") - row.append(progress_bars[j]) - table.add_row(*row) - - -def scan_channel(channel: int) -> bool: - """Scan a specified channel and report if a signal was detected.""" - radio.channel = channel - radio.startListening() - time.sleep(0.00013) - result = radio.testRPD() - radio.stopListening() - return result - - -def scan(duration: int = DURATION): - """Perform scan.""" - timeout = time.monotonic() + duration - console.print( - f"Scanning all channels using {SELECTED_RATE} for", - f"{duration} seconds. Channel labels are in MHz.", - ) - with Live(table, refresh_per_second=1000): - try: - while time.monotonic() < timeout: - for chl, p_bar in enumerate(progress_bars): - # save the latest in history (FIFO ordering) - history[chl] = history[chl][1:] + [signals[chl]] - - # refresh the latest - signals[chl] = scan_channel(chl) - - # update total signal count for the channel - totals[chl] += int(signals[chl]) - - p_bar.update( - p_bar.task_ids[0], - completed=history[chl].count(True), - signals="-" if not totals[chl] else totals[chl], - ) - except KeyboardInterrupt: - console.print(" Keyboard interrupt detected. Powering down radio.") - radio.powerDown() - - -if __name__ == "__main__": - scan() - radio.powerDown() -else: - console.print("Enter `scan()` to run a scan.") - console.print("Change data rate using `radio.setDataRate(RF24_**BPS)`") diff --git a/RF24/examples_linux/streamingData.cpp b/RF24/examples_linux/streamingData.cpp deleted file mode 100644 index b5657d13e92e6ea5a6b1ba5b17a806833d7d78f8..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/streamingData.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of streaming data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use `ctrl+c` to quit at any time. - */ -#include <cmath> // abs() -#include <ctime> // time() -#include <cstring> // strcmp() -#include <iostream> // cin, cout, endl -#include <string> // string, getline() -#include <time.h> // CLOCK_MONOTONIC_RAW, timespec, clock_gettime() -#include <RF24/RF24.h> // RF24, RF24_PA_LOW, delay() - -using namespace std; - -/****************** Linux ***********************/ -// Radio CE Pin, CSN Pin, SPI Speed -// CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use their own pin numbering -// CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -// ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -// Generic: -RF24 radio(22, 0); -/****************** Linux (BBB,x86,etc) ***********************/ -// See http://nRF24.github.io/RF24/pages.html for more information on usage -// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV - -// For this example, we'll be sending 32 payloads each containing -// 32 bytes of data that looks like ASCII art when printed to the serial -// monitor. The TX node and RX node needs only a single 32 byte buffer. -#define SIZE 32 // this is the maximum for this example. (minimum is 1) -char buffer[SIZE + 1]; // for the RX node -unsigned int counter = 0; // for counting the number of received payloads -void makePayload(uint8_t); // prototype to construct a payload dynamically -void setRole(); // prototype to set the node's role -void master(); // prototype of the TX node's behavior -void slave(); // prototype of the RX node's behavior -void printHelp(string); // prototype to function that explain CLI arg usage - -// custom defined timer for evaluating transmission time in microseconds -struct timespec startTimer, endTimer; -uint32_t getMicros(); // prototype to get ellapsed time in microseconds - -int main(int argc, char** argv) -{ - - // perform hardware check - if (!radio.begin()) { - cout << "radio hardware is not responding!!" << endl; - return 0; // quit now - } - - // add a NULL terminating 0 for printing as a c-string - buffer[SIZE] = 0; - - // Let these addresses be used for the pair of nodes used in this example - uint8_t address[2][6] = {"1Node", "2Node"}; - // the TX address^ , ^the RX address - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - bool foundArgNode = false; - bool foundArgRole = false; - bool role = false; - if (argc > 1) { - // CLI args are specified - if ((argc - 1) % 2 != 0) { - // some CLI arg doesn't have an option specified for it - printHelp(string(argv[0])); // all args need an option in this example - return 0; - } - else { - // iterate through args starting after program name - int a = 1; - while (a < argc) { - bool invalidOption = false; - if (strcmp(argv[a], "-n") == 0 || strcmp(argv[a], "--node") == 0) { - // "-n" or "--node" has been specified - foundArgNode = true; - if (argv[a + 1][0] - 48 <= 1) { - radioNumber = (argv[a + 1][0] - 48) == 1; - } - else { - // option is invalid - invalidOption = true; - } - } - else if (strcmp(argv[a], "-r") == 0 || strcmp(argv[a], "--role") == 0) { - // "-r" or "--role" has been specified - foundArgRole = true; - if (argv[a + 1][0] - 48 <= 1) { - role = (argv[a + 1][0] - 48) == 1; - } - else { - // option is invalid - invalidOption = true; - } - } - if (invalidOption) { - printHelp(string(argv[0])); - return 0; - } - a += 2; - } // while - if (!foundArgNode && !foundArgRole) { - // no valid args were specified - printHelp(string(argv[0])); - return 0; - } - } // else - } // if - - // print example's name - cout << argv[0] << endl; - - if (!foundArgNode) { - // Set the radioNumber via the terminal on startup - cout << "Which radio is this? Enter '0' or '1'. Defaults to '0' "; - string input; - getline(cin, input); - radioNumber = input.length() > 0 && (uint8_t)input[0] == 49; - } - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(SIZE); // default value is the maximum 32 bytes - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // ready to execute program now - if (!foundArgRole) { // if CLI arg "-r"/"--role" was not specified - setRole(); // calls master() or slave() based on user input - } - else { // if CLI arg "-r"/"--role" was specified - role ? master() : slave(); // based on CLI arg option - } - return 0; -} - -/** - * set this node's role from stdin stream. - * this only considers the first char as input. - */ -void setRole() -{ - string input = ""; - while (!input.length()) { - cout << "*** PRESS 'T' to begin transmitting to the other node\n"; - cout << "*** PRESS 'R' to begin receiving from the other node\n"; - cout << "*** PRESS 'Q' to exit" << endl; - getline(cin, input); - if (input.length() >= 1) { - if (input[0] == 'T' || input[0] == 't') - master(); - else if (input[0] == 'R' || input[0] == 'r') - slave(); - else if (input[0] == 'Q' || input[0] == 'q') - break; - else - cout << input[0] << " is an invalid input. Please try again." << endl; - } - input = ""; // stay in the while loop - } // while -} // setRole() - -/** - * make this node act as the transmitter - */ -void master() -{ - radio.stopListening(); // put radio in TX mode - - unsigned int failures = 0; // keep track of failures - uint8_t i = 0; - clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer); // start the timer - while (i < SIZE) { - makePayload(i); - if (!radio.writeFast(&buffer, SIZE)) { - failures++; - radio.reUseTX(); - } - else { - i++; - } - - if (failures >= 100) { - // most likely no device is listening for the data stream - cout << "Too many failures detected. "; - cout << "Aborting at payload " << buffer[0]; - break; - } - } // while - uint32_t ellapsedTime = getMicros(); // end the timer - cout << "Time to transmit data = "; - cout << ellapsedTime; // print the timer result - cout << " us. " << failures; // print number of retries - cout << " failures detected. Leaving TX role." << endl; -} // master - -/** - * make this node act as the receiver - */ -void slave() -{ - - counter = 0; - radio.startListening(); // put radio in RX mode - time_t startTimer = time(nullptr); // start a timer - while (time(nullptr) - startTimer < 6) { // use 6 second timeout - if (radio.available()) { // is there a payload - radio.read(&buffer, SIZE); // fetch payload from FIFO - cout << "Received: " << buffer; // print the payload's value - cout << " - " << counter << endl; // print the counter - counter++; // increment counter - startTimer = time(nullptr); // reset timer - } - } - radio.stopListening(); // use TX mode for idle behavior - - cout << "Nothing received in 6 seconds. Leaving RX role." << endl; -} - -/** - * Make a single payload based on position in stream. - * This example employs this function to save on memory allocated. - */ -void makePayload(uint8_t i) -{ - - // let the first character be an identifying alphanumeric prefix - // this lets us see which payload didn't get received - buffer[0] = i + (i < 26 ? 65 : 71); - for (uint8_t j = 0; j < SIZE - 1; ++j) { - char chr = j >= (SIZE - 1) / 2 + abs((SIZE - 1) / 2 - i); - chr |= j < (SIZE - 1) / 2 - abs((SIZE - 1) / 2 - i); - buffer[j + 1] = chr + 48; - } -} - -/** - * Calculate the ellapsed time in microseconds - */ -uint32_t getMicros() -{ - // this function assumes that the timer was started using - // `clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer);` - - clock_gettime(CLOCK_MONOTONIC_RAW, &endTimer); - uint32_t seconds = endTimer.tv_sec - startTimer.tv_sec; - uint32_t useconds = (endTimer.tv_nsec - startTimer.tv_nsec) / 1000; - - return ((seconds)*1000 + useconds) + 0.5; -} - -/** - * print a manual page of instructions on how to use this example's CLI args - */ -void printHelp(string progName) -{ - cout << "usage: " << progName << " [-h] [-n {0,1}] [-r {0,1}]\n\n" - << "A simple example of streaming data from 1 nRF24L01 transceiver to another.\n" - << "\nThis example was written to be used on 2 devices acting as 'nodes'.\n" - << "\noptional arguments:\n -h, --help\t\tshow this help message and exit\n" - << " -n {0,1}, --node {0,1}\n\t\t\tthe identifying radio number\n" - << " -r {0,1}, --role {0,1}\n\t\t\t'1' specifies the TX role." - << " '0' specifies the RX role." << endl; -} diff --git a/RF24/examples_linux/streaming_data.py b/RF24/examples_linux/streaming_data.py deleted file mode 100644 index 065f8fceb87e8c5e93b66ecac07d7a6d3c25d403..0000000000000000000000000000000000000000 --- a/RF24/examples_linux/streaming_data.py +++ /dev/null @@ -1,216 +0,0 @@ -""" -A simple example of streaming data from 1 nRF24L01 transceiver to another. - -This example was written to be used on 2 devices acting as 'nodes'. -""" -import sys -import argparse -import time -from RF24 import RF24, RF24_PA_LOW - - -parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter -) -parser.add_argument( - "-n", - "--node", - type=int, - choices=range(2), - help="the identifying radio number (or node ID number)", -) -parser.add_argument( - "-r", - "--role", - type=int, - choices=range(2), - help="'1' specifies the TX role. '0' specifies the RX role.", -) - -########### USER CONFIGURATION ########### -# See https://github.com/TMRh20/RF24/blob/master/pyRF24/readme.md -# Radio CE Pin, CSN Pin, SPI Speed -# CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use -# their own pin numbering -# CS Pin addresses the SPI bus number at /dev/spidev<a>.<b> -# ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc.. - -# Generic: -radio = RF24(22, 0) -################## Linux (BBB,x86,etc) ######################### -# See http://nRF24.github.io/RF24/pages.html for more information on usage -# See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA -# See https://www.kernel.org/doc/Documentation/spi/spidev for more -# information on SPIDEV - -# Specify the number of bytes in the payload. This is also used to -# specify the number of payloads in 1 stream of data -SIZE = 32 # this is the default maximum payload size - - -def make_buffer(buf_iter: int) -> bytes: - """Returns a dynamically created payloads - - :param int buf_iter: The position of the payload in the data stream - """ - # we'll use `SIZE` for the number of payloads in the list and the - # payloads' length - # prefix payload with a sequential letter to indicate which - # payloads were lost (if any) - buff = bytes([buf_iter + (65 if 0 <= buf_iter < 26 else 71)]) - for j in range(SIZE - 1): - char = bool(j >= (SIZE - 1) / 2 + abs((SIZE - 1) / 2 - buf_iter)) - char |= bool(j < (SIZE - 1) / 2 - abs((SIZE - 1) / 2 - buf_iter)) - buff += bytes([char + 48]) - return buff - - -def master(count: int = 1): - """Uses all 3 levels of the TX FIFO to send a stream of data - - :param int count: how many times to transmit the stream of data. - """ - radio.stopListening() # put radio in TX mode - radio.flush_tx() # clear the TX FIFO so we can use all 3 levels - failures = 0 # keep track of manual retries - start_timer = time.monotonic_ns() # start timer - for multiplier in range(count): # repeat transmit the same data stream - buf_iter = 0 # iterator of payloads for the while loop - while buf_iter < SIZE: # cycle through all the payloads - buffer = make_buffer(buf_iter) # make a payload - - if not radio.writeFast(buffer): # transmission failed - failures += 1 # increment manual retry count - if failures > 99 and buf_iter < 7 and multiplier < 2: - # we need to prevent an infinite loop - print("Too many failures detected. Aborting at payload ", buffer[0]) - multiplier = count # be sure to exit the for loop - break # exit the while loop - radio.reUseTX() # resend payload in top level of TX FIFO - else: # transmission succeeded - buf_iter += 1 - end_timer = time.monotonic_ns() # end timer - print( - f"Time to transmit data = {(end_timer - start_timer) / 1000} us.", - f"Detected {failures} failures." - ) - - -def slave(timeout: int = 6): - """Listen for any payloads and print them out (suffixed with received - counter) - - :param int timeout: The number of seconds to wait (with no transmission) - until exiting function. - """ - radio.startListening() # put radio in RX mode - count = 0 # keep track of the number of received payloads - start_timer = time.monotonic() # start timer - while (time.monotonic() - start_timer) < timeout: - if radio.available(): - count += 1 - # retrieve the received packet's payload - receive_payload = radio.read(radio.payloadSize) - print("Received:", receive_payload, "-", count) - start_timer = time.monotonic() # reset timer on every RX payload - - print("Nothing received in", timeout, "seconds. Leaving RX role") - # recommended behavior is to keep in TX mode while idle - radio.stopListening() # put the radio in TX mode - - - -def set_role() -> bool: - """Set the role using stdin stream. Role args can be specified using space - delimiters (e.g. 'R 10' calls `slave(10)` & 'T 3' calls `master(3)`) - - :return: - - True when role is complete & app should continue running. - - False when app should exit - """ - user_input = ( - input( - "*** Enter 'R' for receiver role.\n" - "*** Enter 'T' for transmitter role.\n" - "*** Enter 'Q' to quit example.\n" - ) - or "?" - ) - user_input = user_input.split() - if user_input[0].upper().startswith("R"): - if len(user_input) > 1: - slave(int(user_input[1])) - else: - slave() - return True - if user_input[0].upper().startswith("T"): - if len(user_input) > 1: - master(int(user_input[1])) - else: - master() - return True - if user_input[0].upper().startswith("Q"): - radio.powerDown() - return False - print(user_input[0], "is an unrecognized input. Please try again.") - return set_role() - - -if __name__ == "__main__": - - args = parser.parse_args() # parse any CLI args - - # initialize the nRF24L01 on the spi bus - if not radio.begin(): - raise RuntimeError("radio hardware is not responding") - - # For this example, we will use different addresses - # An address need to be a buffer protocol object (bytearray) - address = [b"1Node", b"2Node"] - # It is very helpful to think of an address as a path instead of as - # an identifying device destination - - print(sys.argv[0]) # print example name - - # to use different addresses on a pair of radios, we need a variable to - # uniquely identify which address this radio will use to transmit - # 0 uses address[0] to transmit, 1 uses address[1] to transmit - radio_number = args.node # uses default value from `parser` - if args.node is None: # if '--node' arg wasn't specified - radio_number = bool( - int(input("Which radio is this? Enter '0' or '1'. Defaults to '0' ") or 0) - ) - - # set the Power Amplifier level to -12 dBm since this test example is - # usually run with nRF24L01 transceivers in close proximity of each other - radio.setPALevel(RF24_PA_LOW) # RF24_PA_MAX is default - - # set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radio_number]) # always uses pipe 0 - - # set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[not radio_number]) # using pipe 1 - - # To save time during transmission, we'll set the payload size to be only - # what we need. For this example, we'll be using the default maximum 32 - radio.payloadSize = SIZE - - # for debugging, we have 2 options that print a large block of details - # (smaller) function that prints raw register values - # radio.printDetails() - # (larger) function that prints human readable data - # radio.printPrettyDetails() - - try: - if args.role is None: # if not specified with CLI arg '-r' - while set_role(): - pass # continue example until 'Q' is entered - else: # if role was set using CLI args - # run role once and exit - if bool(args.role): - master() - else: - slave() - except KeyboardInterrupt: - print(" Keyboard Interrupt detected. Powering down radio.") - radio.powerDown() diff --git a/RF24/examples_pico/CMakeLists.txt b/RF24/examples_pico/CMakeLists.txt deleted file mode 100644 index fe19684894ecd5bce1330a71480a66db1894ea7f..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -# Pull in SDK (must be before project) -include(../cmake/pico_sdk_import.cmake) - -project(pico_examples C CXX ASM) - -# Initialize the Pico SDK -pico_sdk_init() - -# In YOUR project, include RF24's CMakeLists.txt -# giving the path depending on where the library -# is cloned to in your project -include(../CMakeLists.txt) - -# iterate over a list of examples by name -set(EXAMPLES_LIST - gettingStarted - acknowledgementPayloads - streamingData - manualAcknowledgements - multiceiverDemo - interruptConfigure - scanner -) - -foreach(example ${EXAMPLES_LIST}) - # make a target - add_executable(${example} ${example}.cpp defaultPins.h) - - # link the necessary libs to the target - target_link_libraries(${example} PUBLIC - RF24 - pico_stdlib - hardware_spi - hardware_gpio - ) - - # specify USB port as default serial communication's interface (not UART RX/TX pins) - pico_enable_stdio_usb(${example} 1) - pico_enable_stdio_uart(${example} 0) - - # create map/bin/hex file etc. - pico_add_extra_outputs(${example}) -endforeach() diff --git a/RF24/examples_pico/acknowledgementPayloads.cpp b/RF24/examples_pico/acknowledgementPayloads.cpp deleted file mode 100644 index 66367ac0597f476166de05ece42ca45d21f3f1bb..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/acknowledgementPayloads.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with Acknowledgement (ACK) payloads attached to ACK packets. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Terminal to change each node's behavior. - */ -#include "pico/stdlib.h" // printf(), sleep_ms(), getchar_timeout_us(), to_us_since_boot(), get_absolute_time() -#include "pico/bootrom.h" // reset_usb_boot() -#include <tusb.h> // tud_cdc_connected() -#include <RF24.h> // RF24 radio object -#include "defaultPins.h" // board presumptive default pin numbers for CE_PIN and CSN_PIN - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(CE_PIN, CSN_PIN); - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX role, false = RX role - -// For this example, we'll be using a payload containing -// a string & an integer number that will be incremented -// on every successful transmission. -// Make a data structure to store the entire payload of different datatypes -struct PayloadStruct -{ - char message[7]; // only using 6 characters for TX & ACK payloads - uint8_t counter; -}; -PayloadStruct payload; - -bool setup() -{ - // an identifying device destination - // Let these addresses be used for the pair - uint8_t address[][6] = {"1Node", "2Node"}; - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - // to use different addresses on a pair of radios, we need a variable to - - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // wait here until the CDC ACM (serial port emulation) is connected - while (!tud_cdc_connected()) { - sleep_ms(10); - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - printf("radio hardware is not responding!!\n"); - return false; - } - - // print example's introductory prompt - printf("RF24/examples_pico/acknowledgementPayloads\n"); - - // To set the radioNumber via the Serial monitor on startup - printf("Which radio is this? Enter '0' or '1'. Defaults to '0'\n"); - char input = getchar(); - radioNumber = input == 49; - printf("radioNumber = %d\n", (int)radioNumber); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // to use ACK payloads, we need to enable dynamic payload lengths (for all nodes) - radio.enableDynamicPayloads(); // ACK payloads are dynamically sized - - // Acknowledgement packets have no payloads by default. We need to enable - // this feature for all nodes (TX & RX) to use ACK payloads. - radio.enableAckPayload(); - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // additional setup specific to the node's role - if (role) { - // setup the TX payload - - memcpy(payload.message, "Hello ", 6); // set the payload message - radio.stopListening(); // put radio in TX mode - } - else { - // setup the ACK payload & load the first response into the FIFO - - memcpy(payload.message, "World ", 6); // set the payload message - // load the payload for the first received transmission on pipe 0 - radio.writeAckPayload(1, &payload, sizeof(payload)); - - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // role variable is hardcoded to RX behavior, inform the user of this - printf("*** PRESS 'T' to begin transmitting to the other node\n"); - - return true; -} - -void loop() -{ - - if (role) { - // This device is a TX node - - uint64_t start_timer = to_us_since_boot(get_absolute_time()); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - uint64_t end_timer = to_us_since_boot(get_absolute_time()); // end the timer - - if (report) { - - // print details about outgoing payload - printf("Transmission successful! Time to transmit = %llu us. Sent: %s%d", - end_timer - start_timer, - payload.message, - payload.counter); - - uint8_t pipe; - if (radio.available(&pipe)) { // is there an ACK payload? grab the pipe number that received it - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming ACK payload - - // print details about incoming payload - printf(" Recieved %d bytes on pipe %d: %s%d\n", - radio.getDynamicPayloadSize(), - pipe, - received.message, - received.counter); - - // save incoming counter & increment for next outgoing - payload.counter = received.counter + 1; - } - else { - printf(" Recieved: an empty ACK packet\n"); // empty ACK packet received - } - } - else { - printf("Transmission failed or timed out\n"); // payload was not delivered - } - - // to make this example readable in the serial terminal - sleep_ms(1000); // slow transmissions down by 1 second - } - else { - // This device is a RX node - - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getDynamicPayloadSize(); // get the size of the payload - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming payload - - // print the details of transaction - printf("Received %d bytes on pipe %d: %s%d Sent: %s%d\n", - bytes, - pipe, - received.message, - received.counter, - payload.message, - payload.counter); - - // save incoming counter & increment for next outgoing - payload.counter = received.counter + 1; - // load the payload for the first received transmission on pipe 0 - radio.writeAckPayload(1, &payload, sizeof(payload)); - } - } // role - - char input = getchar_timeout_us(0); // get char from buffer for user input - if (input != PICO_ERROR_TIMEOUT) { - // change the role via the serial terminal - - if ((input == 'T' || input == 't') && !role) { - // Become the TX node - - role = true; - printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n"); - - memcpy(payload.message, "Hello ", 6); // change payload message - radio.stopListening(); // this also discards any unused ACK payloads - } - else if ((input == 'R' || input == 'r') && role) { - // Become the RX node - - role = false; - printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n"); - memcpy(payload.message, "World ", 6); // change payload message - - // load the payload for the first received transmission on pipe 0 - radio.writeAckPayload(1, &payload, sizeof(payload)); - radio.startListening(); - } - else if (input == 'b' || input == 'B') { - // reset to bootloader - radio.powerDown(); - reset_usb_boot(0, 0); - } - } -} // loop - -int main() -{ - stdio_init_all(); // init necessary IO for the RP2040 - - while (!setup()) { // if radio.begin() failed - // hold program in infinite attempts to initialize radio - } - while (true) { - loop(); - } - return 0; // we will never reach this -} diff --git a/RF24/examples_pico/defaultPins.h b/RF24/examples_pico/defaultPins.h deleted file mode 100644 index 319beed0db9abe11c10a5857b0af44508eb50f9b..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/defaultPins.h +++ /dev/null @@ -1,32 +0,0 @@ -// pre-chossen pins for different boards -#ifndef DEFAULTPINS_H -#define DEFAULTPINS_H - -#if defined(ADAFRUIT_QTPY_RP2040) - // for this board, you can still use the Stemma QT connector as a separate I2C bus (`i2c1`) - #define CE_PIN PICO_DEFAULT_I2C_SDA_PIN // the pin labeled SDA - #define CSN_PIN PICO_DEFAULT_I2C_SCL_PIN // the pin labeled SCL - #define IRQ_PIN PICO_DEFAULT_UART_RX_PIN // the pin labeled RX - -#elif defined(PIMORONI_TINY2040) - // default SPI_SCK_PIN = 6 - // default SPI_TX_PIN = 7 - // default SPI_RX_PIN = 4 - #define CE_PIN PICO_DEFAULT_I2C_SCL_PIN // pin 3 - #define CSN_PIN PICO_DEFAULT_SPI_CSN_PIN // pin 5 - #define IRQ_PIN PICO_DEFAULT_I2C_SDA_PIN // pin 2 - -#elif defined(SPARFUN_THINGPLUS) - #define CSN_PIN 16 // the pin labeled 16 - #define CE_PIN 7 // the pin labeled SCL - #define IRQ_PIN 6 // the pin labeled SDA - -#else - // pins available on (ADAFRUIT_ITSYBITSY_RP2040 || ADAFRUIT_FEATHER_RP2040 || Pico_board || Sparkfun_ProMicro || SparkFun MicroMod) - - #define CE_PIN 7 - #define CSN_PIN 8 - #define IRQ_PIN 6 -#endif // board detection macro defs - -#endif // DEFAULTPINS_H diff --git a/RF24/examples_pico/gettingStarted.cpp b/RF24/examples_pico/gettingStarted.cpp deleted file mode 100644 index 32d83d28562d1044c1674ea72d7ebc283969c99e..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/gettingStarted.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Terminal to change each node's behavior. - */ -#include "pico/stdlib.h" // printf(), sleep_ms(), getchar_timeout_us(), to_us_since_boot(), get_absolute_time() -#include "pico/bootrom.h" // reset_usb_boot() -#include <tusb.h> // tud_cdc_connected() -#include <RF24.h> // RF24 radio object -#include "defaultPins.h" // board presumptive default pin numbers for CE_PIN and CSN_PIN - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(CE_PIN, CSN_PIN); - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX role, false = RX role - -// For this example, we'll be using a payload containing -// a single float number that will be incremented -// on every successful transmission -float payload = 0.0; - -bool setup() -{ - // Let these addresses be used for the pair - uint8_t address[][6] = {"1Node", "2Node"}; - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // wait here until the CDC ACM (serial port emulation) is connected - while (!tud_cdc_connected()) { - sleep_ms(10); - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - printf("radio hardware is not responding!!\n"); - return false; - } - - // print example's introductory prompt - printf("RF24/examples_pico/gettingStarted\n"); - - // To set the radioNumber via the Serial terminal on startup - printf("Which radio is this? Enter '0' or '1'. Defaults to '0'\n"); - char input = getchar(); - radioNumber = input == 49; - printf("radioNumber = %d\n", (int)radioNumber); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // float datatype occupies 4 bytes - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // additional setup specific to the node's role - if (role) { - radio.stopListening(); // put radio in TX mode - } - else { - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // role variable is hardcoded to RX behavior, inform the user of this - printf("*** PRESS 'T' to begin transmitting to the other node\n"); - - return true; -} // setup - -void loop() -{ - if (role) { - // This device is a TX node - - uint64_t start_timer = to_us_since_boot(get_absolute_time()); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - uint64_t end_timer = to_us_since_boot(get_absolute_time()); // end the timer - - if (report) { - // payload was delivered; print the payload sent & the timer result - printf("Transmission successful! Time to transmit = %llu us. Sent: %f\n", end_timer - start_timer, payload); - - // increment float payload - payload += 0.01; - } - else { - // payload was not delivered - printf("Transmission failed or timed out\n"); - } - - // to make this example readable in the serial terminal - sleep_ms(1000); // slow transmissions down by 1 second - } - else { - // This device is a RX node - - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getPayloadSize(); // get the size of the payload - radio.read(&payload, bytes); // fetch payload from FIFO - - // print the size of the payload, the pipe number, payload's value - printf("Received %d bytes on pipe %d: %f\n", bytes, pipe, payload); - } - } // role - - char input = getchar_timeout_us(0); // get char from buffer for user input - if (input != PICO_ERROR_TIMEOUT) { - // change the role via the serial terminal - - if ((input == 'T' || input == 't') && !role) { - // Become the TX node - - role = true; - printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n"); - radio.stopListening(); - } - else if ((input == 'R' || input == 'r') && role) { - // Become the RX node - - role = false; - printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n"); - radio.startListening(); - } - else if (input == 'b' || input == 'B') { - // reset to bootloader - radio.powerDown(); - reset_usb_boot(0, 0); - } - } -} // loop - -int main() -{ - stdio_init_all(); // init necessary IO for the RP2040 - - while (!setup()) { // if radio.begin() failed - // hold program in infinite attempts to initialize radio - } - while (true) { - loop(); - } - return 0; // we will never reach this -} diff --git a/RF24/examples_pico/interruptConfigure.cpp b/RF24/examples_pico/interruptConfigure.cpp deleted file mode 100644 index 0b59aff6b0dc97ff57567209839441e4bff85088..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/interruptConfigure.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * This example uses Acknowledgement (ACK) payloads attached to ACK packets to - * demonstrate how the nRF24L01's IRQ (Interrupt Request) pin can be - * configured to detect when data is received, or when data has transmitted - * successfully, or when data has failed to transmit. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Terminal to change each node's behavior. - */ -#include "pico/stdlib.h" // printf(), sleep_ms(), getchar_timeout_us(), to_us_since_boot(), get_absolute_time() -#include "pico/bootrom.h" // reset_usb_boot() -#include <tusb.h> // tud_cdc_connected() -#include <RF24.h> // RF24 radio object -#include "defaultPins.h" // board presumptive default pin numbers for IRQ_PIN, CE_PIN, and CSN_PIN - -// We will be using the nRF24L01's IRQ pin for this example -volatile bool wait_for_event = false; // used to wait for an IRQ event to trigger - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(CE_PIN, CSN_PIN); - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX node, false = RX node - -// For this example, we'll be using a payload containing -// a string that changes on every transmission. (successful or not) -// Make a couple arrays of payloads & an iterator to traverse them -const uint8_t tx_pl_size = 5; -const uint8_t ack_pl_size = 4; -uint8_t pl_iterator = 0; -// The " + 1" compensates for the c-string's NULL terminating 0 -char tx_payloads[][tx_pl_size + 1] = {"Ping ", "Pong ", "Radio", "1FAIL"}; -char ack_payloads[][ack_pl_size + 1] = {"Yak ", "Back", " ACK"}; - -void interruptHandler(uint gpio, uint32_t events); // prototype to handle IRQ events -void printRxFifo(); // prototype to print RX FIFO with 1 buffer - -bool setup() -{ - // Let these addresses be used for the pair - uint8_t address[][6] = {"1Node", "2Node"}; - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // wait here until the CDC ACM (serial port emulation) is connected - while (!tud_cdc_connected()) { - sleep_ms(10); - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - printf("radio hardware is not responding!!\n"); - return false; - } - - // print example's introductory prompt - printf("RF24/examples_pico/interruptConfigure\n"); - - // To set the radioNumber via the Serial terminal on startup - printf("Which radio is this? Enter '0' or '1'. Defaults to '0'\n"); - char input = getchar(); - radioNumber = input == 49; - printf("radioNumber = %d\n", (int)radioNumber); - - // setup the IRQ_PIN - gpio_set_irq_enabled_with_callback(IRQ_PIN, GPIO_IRQ_EDGE_FALL, true, &interruptHandler); - // IMPORTANT: do not call radio.available() before calling - // radio.whatHappened() when the interruptHandler() is triggered by the - // IRQ pin FALLING event. According to the datasheet, the pipe information - // is unreliable during the IRQ pin FALLING transition. - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // For this example we use acknowledgment (ACK) payloads to trigger the - // IRQ pin when data is received on the TX node. - // to use ACK payloads, we need to enable dynamic payload lengths - radio.enableDynamicPayloads(); // ACK payloads are dynamically sized - - // Acknowledgement packets have no payloads by default. We need to enable - // this feature for all nodes (TX & RX) to use ACK payloads. - radio.enableAckPayload(); - // Fot this example, we use the same address to send data back and forth - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // additional setup specific to the node's role - if (role) { - // setup for TX mode - radio.stopListening(); // put radio in TX mode - } - else { - // setup for RX mode - - // let IRQ pin not trigger in RX mode - radio.maskIRQ(1, 1, 1); // args = "data_sent", "data_fail", "data_ready" - - // Fill the TX FIFO with 3 ACK payloads for the first 3 received - // transmissions on pipe 1 - radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); - - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // role variable is hardcoded to RX behavior, inform the user of this - printf("*** PRESS 'T' to begin transmitting to the other node\n"); - - return true; -} - -void loop() -{ - if (role && !wait_for_event) { - // This device is a TX node. This if block is only triggered when - // NOT waiting for an IRQ event to happen - - if (pl_iterator == 0) { - // Test the "data ready" event with the IRQ pin - - printf("\nConfiguring IRQ pin to ignore the 'data sent' event\n"); - radio.maskIRQ(true, false, false); // args = "data_sent", "data_fail", "data_ready" - printf(" Pinging RX node for 'data ready' event...\n"); - } - else if (pl_iterator == 1) { - // Test the "data sent" event with the IRQ pin - - printf("\nConfiguring IRQ pin to ignore the 'data ready' event\n"); - radio.maskIRQ(false, false, true); // args = "data_sent", "data_fail", "data_ready" - printf(" Pinging RX node for 'data sent' event...\n"); - } - else if (pl_iterator == 2) { - // Use this iteration to fill the RX node's FIFO which sets us up for the next test. - - // write() uses virtual interrupt flags that work despite the masking of the IRQ pin - radio.maskIRQ(1, 1, 1); // disable IRQ masking for this step - - printf("\nSending 1 payload to fill RX node's FIFO. IRQ pin is neglected.\n"); - // write() will call flush_tx() on 'data fail' events - if (radio.write(&tx_payloads[pl_iterator], tx_pl_size)) { - if (radio.rxFifoFull()) { - printf("RX node's FIFO is full; it is not listening any more\n"); - } - else { - printf("Transmission successful, but the RX node might still be listening.\n"); - } - } - else { - printf("Transmission failed or timed out. Continuing anyway.\n"); - radio.flush_tx(); // discard payload(s) that failed to transmit - } - } - else if (pl_iterator == 3) { - // test the "data fail" event with the IRQ pin - - printf("\nConfiguring IRQ pin to reflect all events\n"); - radio.maskIRQ(0, 0, 0); // args = "data_sent", "data_fail", "data_ready" - printf(" Pinging inactive RX node for 'data fail' event...\n"); - } - - if (pl_iterator < 4 && pl_iterator != 2) { - - // IRQ pin is LOW when activated. Otherwise it is always HIGH - // Wait until IRQ pin is activated. - wait_for_event = true; - - // use the non-blocking call to write a payload and begin transmission - // the "false" argument means we are expecting an ACK packet response - radio.startFastWrite(tx_payloads[pl_iterator++], tx_pl_size, false); - - // In this example, the "data fail" event is always configured to - // trigger the IRQ pin active. Because the auto-ACK feature is on by - // default, we don't need a timeout check to prevent an infinite loop. - } - else if (pl_iterator == 4) { - // all IRQ tests are done; flush_tx() and print the ACK payloads for fun - - // CE pin is still HIGH which consumes more power. Example is now idling so... - radio.stopListening(); // ensure CE pin is LOW - // stopListening() also calls flush_tx() when ACK payloads are enabled - - printRxFifo(); - pl_iterator++; - - // inform user what to do next - printf("\n*** PRESS 'T' to restart the transmissions"); - printf("\n*** PRESS 'R' to change to Receive role\n"); - } - else if (pl_iterator == 2) { - pl_iterator++; // proceed from step 3 to last step (stop at step 4 for readability) - } - } - else if (!role && radio.rxFifoFull()) { - // This device is a RX node - // - // The RX role waits until RX FIFO is full then stops listening while - // the FIFOs get reset and starts listening again. - radio.stopListening(); // also calls flush_tx() when ACKs are enabled - printRxFifo(); // also clears RX FIFO - - // Fill the TX FIFO with 3 ACK payloads for the first 3 received - // transmissions on pipe 1. - radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); - - sleep_ms(200); // let radio TX role complete - radio.startListening(); // We're ready to start over. Begin listening. - - } // role - - char input = getchar_timeout_us(0); // get char from buffer for user input - if (input != PICO_ERROR_TIMEOUT) { - // change the role via the serial terminal - - if (input == 'T' || input == 't') { - // Become the TX node - if (!role) - printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n"); - else if (role && wait_for_event) // don't interrupt on ongoing test - return; // exit now; start next loop() - else - printf("*** RESTARTING IRQ PIN TEST ***\n"); - - role = true; - wait_for_event = false; - pl_iterator = 0; // reset the iterator - radio.flush_tx(); // discard any payloads in the TX FIFO - - // startListening() clears the IRQ masks also. This is required for - // continued TX operations when a transmission fails. - radio.stopListening(); // this also discards any unused ACK payloads - } - else if ((input == 'R' || input == 'r') /* && role */) { - // Become the RX node - printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n"); - - role = false; - radio.maskIRQ(1, 1, 1); // the IRQ pin should not trigger in this example's RX rode - - // Fill the TX FIFO with 3 ACK payloads for the first 3 received - // transmissions on pipe 1 - radio.flush_tx(); // make sure there is room for 3 new ACK payloads - radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size); - radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size); - radio.startListening(); - } - else if (input == 'b' || input == 'B') { - // reset to bootloader - radio.powerDown(); - reset_usb_boot(0, 0); - } - } // user input -} // loop - -/** - * when the IRQ pin goes active LOW, call this fuction print out why - */ -void interruptHandler(uint gpio, uint32_t events) -{ - - if (gpio != IRQ_PIN && !(events | GPIO_IRQ_EDGE_FALL)) { - // the gpio pin and event does not match the configuration we specified - return; - } - - // print IRQ status and all masking flags' states - printf("\tIRQ pin is actively LOW\n"); // show that this function was called - bool tx_ds, tx_df, rx_dr; // declare variables for IRQ masks - radio.whatHappened(tx_ds, tx_df, rx_dr); // get values for IRQ masks - // whatHappened() clears the IRQ masks also. This is required for - // continued TX operations when a transmission fails. - // clearing the IRQ masks resets the IRQ pin to its inactive state (HIGH) - - // print "data sent", "data fail", "data ready" mask states - printf("\tdata_sent: %s, data_fail: %s, data_ready: %s\n", - tx_ds ? "true" : "false", - tx_df ? "true" : "false", - rx_dr ? "true" : "false"); - - if (tx_df) // if TX payload failed - radio.flush_tx(); // clear all payloads from the TX FIFO - - // print if test passed or failed. Unintentional fails mean the RX node was not listening. - // pl_iterator has already been incremented by now - if (pl_iterator <= 1) { - printf(" 'Data Ready' event test %s\n", rx_dr ? "passed" : "failed"); - } - else if (pl_iterator == 2) { - printf(" 'Data Sent' event test %s\n", tx_ds ? "passed" : "failed"); - } - else if (pl_iterator == 4) { - printf(" 'Data Fail' event test %s\n", tx_df ? "passed" : "failed"); - } - wait_for_event = false; // ready to continue with loop() operations -} // interruptHandler - -/** - * Print the entire RX FIFO with one buffer. This will also flush the RX FIFO. - * Remember that the payload sizes are declared as tx_pl_size and ack_pl_size. - */ -void printRxFifo() -{ - if (radio.available()) { // if there is data in the RX FIFO - // to flush the data from the RX FIFO, we'll fetch it all using 1 buffer - - uint8_t pl_size = !role ? tx_pl_size : ack_pl_size; - char rx_fifo[pl_size * 3 + 1]; // RX FIFO is full & we know ACK payloads' size - if (radio.rxFifoFull()) { - rx_fifo[pl_size * 3] = 0; // add a NULL terminating char to use as a c-string - radio.read(&rx_fifo, pl_size * 3); // this clears the RX FIFO (for this example) - } - else { - uint8_t i = 0; - while (radio.available()) { - radio.read(&rx_fifo + (i * pl_size), pl_size); - i++; - } - rx_fifo[i * pl_size] = 0; // add a NULL terminating char to use as a c-string - } - printf("Complete RX FIFO: %s\n", rx_fifo); // print the entire RX FIFO with 1 buffer - } -} - -int main() -{ - stdio_init_all(); // init necessary IO for the RP2040 - - while (!setup()) { // if radio.begin() failed - // hold program in infinite attempts to initialize radio - } - while (true) { - loop(); - } - return 0; // we will never reach this -} diff --git a/RF24/examples_pico/manualAcknowledgements.cpp b/RF24/examples_pico/manualAcknowledgements.cpp deleted file mode 100644 index bfe2d57f9c0a4e1907ed127df4f345163e1d738b..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/manualAcknowledgements.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty (2bndy5) - */ - -/** - * A simple example of sending data from 1 nRF24L01 transceiver to another - * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. - * This example still uses ACK packets, but they have no payloads. Instead the - * acknowledging response is sent with `write()`. This tactic allows for more - * updated acknowledgement payload data, where actual ACK payloads' data are - * outdated by 1 transmission because they have to loaded before receiving a - * transmission. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Terminal to change each node's behavior. - */ -#include "pico/stdlib.h" // printf(), sleep_ms(), getchar_timeout_us(), to_us_since_boot(), get_absolute_time() -#include "pico/bootrom.h" // reset_usb_boot() -#include <tusb.h> // tud_cdc_connected() -#include <RF24.h> // RF24 radio object -#include "defaultPins.h" // board presumptive default pin numbers for CE_PIN and CSN_PIN - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(CE_PIN, CSN_PIN); - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX node, false = RX node - -// For this example, we'll be using a payload containing -// a string & an integer number that will be incremented -// on every successful transmission. -// Make a data structure to store the entire payload of different datatypes -struct PayloadStruct -{ - char message[7]; // only using 6 characters for TX & RX payloads - uint8_t counter; -}; -PayloadStruct payload; - -bool setup() -{ - // append a NULL terminating character for printing as a c-string - payload.message[6] = 0; - - // Let these addresses be used for the pair - uint8_t address[][6] = {"1Node", "2Node"}; - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // wait here until the CDC ACM (serial port emulation) is connected - while (!tud_cdc_connected()) { - sleep_ms(10); - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - printf("radio hardware is not responding!!\n"); - return false; - } - - // print example's introductory prompt - printf("RF24/examples_pico/manualAcknowledgements\n"); - - // To set the radioNumber via the Serial monitor on startup - printf("Which radio is this? Enter '0' or '1'. Defaults to '0'\n"); - char input = getchar(); - radioNumber = input == 49; - printf("radioNumber = %d\n", (int)radioNumber); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - if (role) { - // setup the TX node - - memcpy(payload.message, "Hello ", 6); // set the outgoing message - radio.stopListening(); // put radio in TX mode - } - else { - // setup the RX node - - memcpy(payload.message, "World ", 6); // set the outgoing message - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // role variable is hardcoded to RX behavior, inform the user of this - printf("*** PRESS 'T' to begin transmitting to the other node\n"); - - return true; -} // setup() - -void loop() -{ - if (role) { - // This device is a TX node - - uint64_t start_timer = to_us_since_boot(get_absolute_time()); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - - if (report) { - // transmission successful; wait for response and print results - - radio.startListening(); // put in RX mode - uint64_t start_timeout = to_ms_since_boot(get_absolute_time()); // timer to detect timeout - while (!radio.available()) { // wait for response - if (to_ms_since_boot(get_absolute_time()) - start_timeout > 200) // only wait 200 ms - break; - } - uint64_t end_timer = to_us_since_boot(get_absolute_time()); // end the timer - radio.stopListening(); // put back in TX mode - - // print summary of transactions - printf("Transmission successful!"); // payload was delivered - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload received - // print details about outgoing payload - printf(" Round-trip delay: %llu us. Sent: %s%d", - end_timer - start_timer, - payload.message, - payload.counter); - - PayloadStruct received; - radio.read(&received, sizeof(received)); // get payload from RX FIFO - - // print details about incoming payload - printf(" Received %d bytes on pipe %d: %s%d\n", - radio.getPayloadSize(), - pipe, - received.message, - received.counter); - - payload.counter = received.counter; // save incoming counter for next outgoing counter - } - else { - printf(" Recieved no response.\n"); // no response received - } - } - else { - printf("Transmission failed or timed out\n"); // payload was not delivered - } // report - - // to make this example readable in the serial terminal - sleep_ms(1000); // slow transmissions down by 1 second - } - else { - // This device is a RX node - - uint8_t pipe; - if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - PayloadStruct received; - radio.read(&received, sizeof(received)); // get incoming payload - payload.counter = received.counter + 1; // increment incoming counter for next outgoing response - - // transmit response & save result to `report` - radio.stopListening(); // put in TX mode - radio.writeFast(&payload, sizeof(payload)); // load response to TX FIFO - bool report = radio.txStandBy(150); // keep retrying for 150 ms - radio.startListening(); // put back in RX mode - - // print summary of transactions, starting with details about incoming payload - printf("Received %d bytes on pipe %d: %s%d", - radio.getPayloadSize(), - pipe, - received.message, - received.counter); - - if (report) { - // print outgoing payload and its counter - printf(" Sent: %s%d", payload.message, payload.counter); - } - else { - printf(" Response failed.\n"); // failed to send response - } - } - } // role - - char input = getchar_timeout_us(0); // get char from buffer for user input - if (input != PICO_ERROR_TIMEOUT) { - // change the role via the serial terminal - - if ((input == 'T' || input == 't') && !role) { - // Become the TX node - - role = true; - memcpy(payload.message, "Hello ", 6); // set the outgoing message - printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n"); - radio.stopListening(); // put in TX mode - } - else if ((input == 'R' || input == 'r') && role) { - // Become the RX node - - role = false; - memcpy(payload.message, "World ", 6); // set the response message - printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n"); - radio.startListening(); // put in RX mode - } - else if (input == 'b' || input == 'B') { - // reset to bootloader - radio.powerDown(); - reset_usb_boot(0, 0); - } - } -} // loop - -int main() -{ - stdio_init_all(); // init necessary IO for the RP2040 - - while (!setup()) { // if radio.begin() failed - // hold program in infinite attempts to initialize radio - } - while (true) { - loop(); - } - return 0; // we will never reach this -} diff --git a/RF24/examples_pico/multiceiverDemo.cpp b/RF24/examples_pico/multiceiverDemo.cpp deleted file mode 100644 index 18a7d40f871377849406a8bb72be2be1f417820c..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/multiceiverDemo.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty 2bndy5 - */ - -/** - * A simple example of sending data from as many as 6 nRF24L01 transceivers to - * 1 receiving transceiver. This technique is trademarked by - * Nordic Semiconductors as "MultiCeiver". - * - * This example was written to be used on up to 6 devices acting as TX nodes & - * only 1 device acting as the RX node (that's a maximum of 7 devices). - * Use the Serial Terminal to change each node's behavior. - */ -#include "pico/stdlib.h" // printf(), sleep_ms(), getchar_timeout_us(), to_us_since_boot(), get_absolute_time() -#include "pico/bootrom.h" // reset_usb_boot() -#include <tusb.h> // tud_cdc_connected() -#include <RF24.h> // RF24 radio object -#include "defaultPins.h" // board presumptive default pin numbers for CE_PIN and CSN_PIN - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(CE_PIN, CSN_PIN); - -// For this example, we'll be using 6 addresses; 1 for each TX node -// It is very helpful to think of an address as a path instead of as -// an identifying device destination -// Notice that the last byte is the only byte that changes in the last 5 -// addresses. This is a limitation of the nRF24L01 transceiver for pipes 2-5 -// because they use the same first 4 bytes from pipe 1. -uint64_t address[6] = {0x7878787878LL, - 0xB3B4B5B6F1LL, - 0xB3B4B5B6CDLL, - 0xB3B4B5B6A3LL, - 0xB3B4B5B60FLL, - 0xB3B4B5B605LL}; - -// Because this example allow up to 6 nodes (specified by numbers 0-5) to -// transmit and only 1 node to receive, we will use a negative value in our -// role variable to signify this node is a receiver. -// role variable is used to control whether this node is sending or receiving -char role = 'R'; // integers 0-5 = TX node; character 'R' or integer 82 = RX node - -// For this example, we'll be using a payload containing -// a node ID number and a single integer number that will be incremented -// on every successful transmission. -// Make a data structure to use as a payload. -struct PayloadStruct -{ - unsigned long nodeID; - unsigned long payloadID; -}; -PayloadStruct payload; - -// This example uses all 6 pipes to receive while TX nodes only use 2 pipes -// To make this easier we'll use a function to manage the addresses, and the -// payload's nodeID -void setRole(); // declare a prototype; definition is found after the loop() - -bool setup() -{ - // wait here until the CDC ACM (serial port emulation) is connected - while (!tud_cdc_connected()) { - sleep_ms(10); - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - printf("radio hardware is not responding!!\n"); - return false; - } - - // print example's introductory prompt - printf("RF24/examples_pico/multiceiverDemo\n"); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity of - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit a float - radio.setPayloadSize(sizeof(payload)); // 2x int datatype occupy 8 bytes - - // Set the pipe addresses accordingly. This function additionally also - // calls startListening() or stopListening() and sets the payload's nodeID - setRole(); - - // For debugging info - // printf_begin(); // needed only once for printing details - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // role variable is hardcoded to RX behavior, inform the user of this - printf("*** Enter a number between 0 and 5 (inclusive) to change\n"); - printf(" the identifying node number that transmits.\n"); - - return true; -} // setup() - -void loop() -{ - if (role <= 53) { - // This device is a TX node - - uint64_t start_timer = to_us_since_boot(get_absolute_time()); // start the timer - bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report - uint64_t end_timer = to_us_since_boot(get_absolute_time()); // end the timer - - if (report) { - // payload was delivered - printf("Transmission of payloadID %ld as node %ld successful! Time to transmit: %llu us\n", - payload.payloadID, - payload.nodeID, - end_timer - start_timer); - } - else { - printf("Transmission failed or timed out\n"); // payload was not delivered - } - - payload.payloadID++; // increment payload number - - // to make this example readable in the serial terminal - sleep_ms(1000); // slow transmissions down by 1 second - } - else if (role == 'R') { - // This device is the RX node - - uint8_t pipe; - while (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it - uint8_t bytes = radio.getPayloadSize(); // get the size of the payload - radio.read(&payload, bytes); // fetch payload from FIFO - - // print details about incoming payload - printf("Received %d bytes on pipe %d from node %ld. PayloadID: %ld\n", - bytes, - pipe, - payload.nodeID, - payload.payloadID); - } - } // role - - char input = getchar_timeout_us(0); // get char from buffer for user input - if (input != PICO_ERROR_TIMEOUT) { - // change the role via the serial terminal - - if ((input == 'R' || input == 'r') && role <= 53) { - // Become the RX node - - role = 'R'; - printf("*** CHANGING ROLE TO RECEIVER ***\n"); - printf("--- Enter a number between 0 and 5 (inclusive) to act as\n"); - printf(" a unique node number that transmits to the RX node.\n"); - setRole(); // change address on all pipes to TX nodes - } - else if (input >= 48 && input <= 53 && input != role) { - // Become a TX node with identifier 'input' - - role = input - 48; - printf("*** CHANGING ROLE TO NODE %c ***\n", input); - printf("--- Enter a number between 0 and 5 (inclusive) to change\n"); - printf(" the identifying node number that transmits.\n"); - printf("--- PRESS 'R' to act as the RX node.\n"); - setRole(); // change address on pipe 0 to the RX node - } - else if (input == 'b' || input == 'B') { - // reset to bootloader - radio.powerDown(); - reset_usb_boot(0, 0); - } - } - -} // loop - -void setRole() -{ - if (role == 'R') { - // For the RX node - - // Set the addresses for all pipes to TX nodes - for (uint8_t i = 0; i < 6; ++i) - radio.openReadingPipe(i, address[i]); - - radio.startListening(); // put radio in RX mode - } - else { - // For the TX node - - // set the payload's nodeID & reset the payload's identifying number - payload.nodeID = role; - payload.payloadID = 0; - - // Set the address on pipe 0 to the RX node. - radio.stopListening(); // put radio in TX mode - radio.openWritingPipe(address[role]); - - // According to the datasheet, the auto-retry features's delay value should - // be "skewed" to allow the RX node to receive 1 transmission at a time. - // So, use varying delay between retry attempts and 15 (at most) retry attempts - radio.setRetries(((role * 3) % 12) + 3, 15); // maximum value is 15 for both args - } -} // setRole - -int main() -{ - stdio_init_all(); // init necessary IO for the RP2040 - - while (!setup()) { // if radio.begin() failed - // hold program in infinite attempts to initialize radio - } - while (true) { - loop(); - } - return 0; // we will never reach this -} diff --git a/RF24/examples_pico/scanner.cpp b/RF24/examples_pico/scanner.cpp deleted file mode 100644 index d67bd8b4374dfd605ebb8287af74748a9ba87d72..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/scanner.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - - - 06/04/2021 : Brendan Doherty (https://github.com/2bndy5) - Modified to use with PicoSDK - - */ - -/** - * Channel scanner - * - * Example to detect interference on the various channels available. - * This is a good diagnostic tool to check whether you're picking a - * good channel for your application. - * - * Inspired by cpixip. - * See http://arduino.cc/forum/index.php/topic,54795.0.html - */ - -#include "pico/stdlib.h" // printf(), sleep_ms(), getchar_timeout_us(), to_us_since_boot(), get_absolute_time() -#include "pico/bootrom.h" // reset_usb_boot() -#include <tusb.h> // tud_cdc_connected() -#include <RF24.h> // RF24 radio object, rf24_min() -#include "defaultPins.h" // board presumptive default pin numbers for CE_PIN and CSN_PIN - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(CE_PIN, CSN_PIN); - -// Channel info -const uint8_t num_channels = 126; -uint8_t values[num_channels]; - -const int num_reps = 100; -int reset_array = 0; - -int main() -{ - stdio_init_all(); // init necessary IO for the RP2040 - - // wait here until the CDC ACM (serial port emulation) is connected - while (!tud_cdc_connected()) { - sleep_ms(10); - } - - // initialize the transceiver on the SPI bus - while (!radio.begin()) { - printf("radio hardware is not responding!!\n"); - } - - // print example's name - printf("RF24/examples_pico/scanner\n"); - - radio.setAutoAck(false); - - // Get into standby mode - radio.startListening(); - radio.stopListening(); - - // radio.printDetails(); - - // Print out header, high then low digit - int i = 0; - - while (i < num_channels) { - printf("%x", i >> 4); - ++i; - } - printf("\n"); - - i = 0; - while (i < num_channels) { - printf("%x", i & 0xf); - ++i; - } - printf("\n"); - - // forever loop - while (1) { - // Clear measurement values - memset(values, 0, sizeof(values)); - - // Scan all channels num_reps times - int rep_counter = num_reps; - while (rep_counter--) { - - int i = num_channels; - while (i--) { - - // Select this channel - radio.setChannel(i); - - // Listen for a little - radio.startListening(); - sleep_us(128); - radio.stopListening(); - - // Did we get a carrier? - if (radio.testCarrier()) { - ++values[i]; - } - } - } - - // Print out channel measurements, clamped to a single hex digit - i = 0; - while (i < num_channels) { - if (values[i]) - printf("%x", rf24_min(0xf, (values[i] & 0xf))); - else - printf("-"); - - ++i; - } - printf("\n"); - } - - return 0; -} diff --git a/RF24/examples_pico/streamingData.cpp b/RF24/examples_pico/streamingData.cpp deleted file mode 100644 index 4d02e1024304b2e286703ea1abde8021b793d341..0000000000000000000000000000000000000000 --- a/RF24/examples_pico/streamingData.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * See documentation at https://nRF24.github.io/RF24 - * See License information at root directory of this library - * Author: Brendan Doherty 2bndy5 - */ - -/** - * A simple example of streaming data from 1 nRF24L01 transceiver to another. - * - * This example was written to be used on 2 devices acting as "nodes". - * Use the Serial Terminal to change each node's behavior. - */ -#include "pico/stdlib.h" // printf(), sleep_ms(), getchar_timeout_us(), to_us_since_boot(), get_absolute_time() -#include "pico/bootrom.h" // reset_usb_boot() -#include <tusb.h> // tud_cdc_connected() -#include <math.h> // abs() -#include <RF24.h> // RF24 radio object -#include "defaultPins.h" // board presumptive default pin numbers for CE_PIN and CSN_PIN - -// instantiate an object for the nRF24L01 transceiver -RF24 radio(CE_PIN, CSN_PIN); - -// Used to control whether this node is sending or receiving -bool role = false; // true = TX node, false = RX node - -// For this example, we'll be sending 32 payloads each containing -// 32 bytes of data that looks like ASCII art when printed to the serial -// monitor. The TX node and RX node needs only a single 32 byte buffer. -#define SIZE 32 // this is the maximum for this example. (minimum is 1) -char buffer[SIZE + 1]; // for the RX node -uint8_t counter = 0; // for counting the number of received payloads -void makePayload(uint8_t); // prototype to construct a payload dynamically - -bool setup() -{ - buffer[SIZE] = 0; // add a NULL terminating character (for easy printing) - - // Let these addresses be used for the pair - uint8_t address[][6] = {"1Node", "2Node"}; - // It is very helpful to think of an address as a path instead of as - // an identifying device destination - - // to use different addresses on a pair of radios, we need a variable to - // uniquely identify which address this radio will use to transmit - bool radioNumber; // 0 uses address[0] to transmit, 1 uses address[1] to transmit - - // wait here until the CDC ACM (serial port emulation) is connected - while (!tud_cdc_connected()) { - sleep_ms(10); - } - - // initialize the transceiver on the SPI bus - if (!radio.begin()) { - printf("radio hardware is not responding!!\n"); - return false; - } - - // print example's introductory prompt - printf("RF24/examples_pico/streamingData\n"); - - // To set the radioNumber via the Serial monitor on startup - printf("Which radio is this? Enter '0' or '1'. Defaults to '0'\n"); - char input = getchar(); - radioNumber = input == 49; - printf("radioNumber = %d\n", (int)radioNumber); - - // Set the PA Level low to try preventing power supply related problems - // because these examples are likely run with nodes in close proximity to - // each other. - radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default. - - // save on transmission time by setting the radio to only transmit the - // number of bytes we need to transmit - radio.setPayloadSize(SIZE); // default value is the maximum 32 bytes - - // set the TX address of the RX node into the TX pipe - radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 - - // set the RX address of the TX node into a RX pipe - radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 - - // additional setup specific to the node's role - if (role) { - radio.stopListening(); // put radio in TX mode - } - else { - radio.startListening(); // put radio in RX mode - } - - // For debugging info - // radio.printDetails(); // (smaller) function that prints raw register values - // radio.printPrettyDetails(); // (larger) function that prints human readable data - - // role variable is hardcoded to RX behavior, inform the user of this - printf("*** PRESS 'T' to begin transmitting to the other node\n"); - - return true; -} // setup() - -void loop() -{ - - if (role) { - // This device is a TX node - - radio.flush_tx(); - uint8_t i = 0; - uint8_t failures = 0; - uint64_t start_timer = to_us_since_boot(get_absolute_time()); // start the timer - while (i < SIZE) { - makePayload(i); // make the payload - if (!radio.writeFast(&buffer, SIZE)) { - failures++; - radio.reUseTX(); - } - else { - i++; - } - - if (failures >= 100) { - printf("Too many failures detected. Aborting at payload %c\n", buffer[0]); - break; - } - } - uint64_t end_timer = to_us_since_boot(get_absolute_time()); // end the timer - - // print results from transmitting stream - printf("Time to transmit = %llu us with %d failures detected\n", end_timer - start_timer, failures); - - // to make this example readable in the serial terminal - sleep_ms(1000); // slow transmissions down by 1 second - } - else { - // This device is a RX node - - if (radio.available()) { // is there a payload? - radio.read(&buffer, SIZE); // fetch payload from FIFO - - // print the received payload and its counter - printf("Received: %s - %d\n", buffer, counter++); - } - } // role - - char input = getchar_timeout_us(0); // get char from buffer for user input - if (input != PICO_ERROR_TIMEOUT) { - // change the role via the serial terminal - - if ((input == 'T' || input == 't') && !role) { - // Become the TX node - - role = true; - counter = 0; //reset the RX node's counter - printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n"); - radio.stopListening(); - } - else if ((input == 'R' || input == 'r') && role) { - // Become the RX node - - role = false; - printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n"); - radio.startListening(); - } - else if (input == 'b' || input == 'B') { - // reset to bootloader - radio.powerDown(); - reset_usb_boot(0, 0); - } - } -} // loop - -void makePayload(uint8_t i) -{ - // Make a single payload based on position in stream. - // This example employs function to save memory on certain boards. - - // let the first character be an identifying alphanumeric prefix - // this lets us see which payload didn't get received - buffer[0] = i + (i < 26 ? 65 : 71); - for (uint8_t j = 0; j < SIZE - 1; ++j) { - char chr = j >= (SIZE - 1) / 2 + abs((SIZE - 1) / 2 - i); - chr |= j < (SIZE - 1) / 2 - abs((SIZE - 1) / 2 - i); - buffer[j + 1] = chr + 48; - } -} - -int main() -{ - stdio_init_all(); // init necessary IO for the RP2040 - - while (!setup()) { // if radio.begin() failed - // hold program in infinite attempts to initialize radio - } - while (true) { - loop(); - } - return 0; // we will never reach this -} diff --git a/RF24/images/ghetto_sheilding_1.png b/RF24/images/ghetto_sheilding_1.png deleted file mode 100644 index 1cdaaced268986c9189d5f31f1b8dfc0c9d1299f..0000000000000000000000000000000000000000 Binary files a/RF24/images/ghetto_sheilding_1.png and /dev/null differ diff --git a/RF24/images/ghetto_sheilding_2.png b/RF24/images/ghetto_sheilding_2.png deleted file mode 100644 index 5480898dc334d1fa4f3ae12b5d8fe27bba43f0a2..0000000000000000000000000000000000000000 Binary files a/RF24/images/ghetto_sheilding_2.png and /dev/null differ diff --git a/RF24/images/pinout.jpg b/RF24/images/pinout.jpg deleted file mode 100644 index f83ddb7095fa1790f3821fb8208bba813c39d0b7..0000000000000000000000000000000000000000 Binary files a/RF24/images/pinout.jpg and /dev/null differ diff --git a/RF24/keywords.txt b/RF24/keywords.txt deleted file mode 100644 index 1d8e770ec57440850462e6ba62866c891434bff0..0000000000000000000000000000000000000000 --- a/RF24/keywords.txt +++ /dev/null @@ -1,61 +0,0 @@ -RF24 KEYWORD1 -begin KEYWORD2 -isChipConnected KEYWORD2 -startListening KEYWORD2 -stopListening KEYWORD2 -available KEYWORD2 -read KEYWORD2 -write KEYWORD2 -openWritingPipe KEYWORD2 -openReadingPipe KEYWORD2 -printDetails KEYWORD2 -printPrettyDetails KEYWORD2 -rxFifoFull KEYWORD2 -powerDown KEYWORD2 -powerUp KEYWORD2 -writeFast KEYWORD2 -writeBlocking KEYWORD2 -txStandBy KEYWORD2 -writeAckPayload KEYWORD2 -whatHappened KEYWORD2 -startFastWrite KEYWORD2 -startWrite KEYWORD2 -reUseTX KEYWORD2 -flush_tx KEYWORD2 -flush_rx KEYWORD2 -testCarrier KEYWORD2 -testRPD KEYWORD2 -isValid KEYWORD2 -closeReadingPipe KEYWORD2 -failureDetected KEYWORD2 -setAddressWidth KEYWORD2 -setRetries KEYWORD2 -setChannel KEYWORD2 -getChannel KEYWORD2 -setPayloadSize KEYWORD2 -getPayloadSize KEYWORD2 -getDynamicPayloadSize KEYWORD2 -enableAckPayload KEYWORD2 -disableAckPayload KEYWORD2 -enableDynamicPayloads KEYWORD2 -disableDynamicPayloads KEYWORD2 -isPVariant KEYWORD2 -setAutoAck KEYWORD2 -setPALevel KEYWORD2 -getPALevel KEYWORD2 -getARC KEYWORD2 -setDataRate KEYWORD2 -getDataRate KEYWORD2 -setCRCLength KEYWORD2 -getCRCLength KEYWORD2 -disableCRC KEYWORD2 -maskIRQ KEYWORD2 -txDelay KEYWORD2 -csDelay KEYWORD2 -startConstCarrier KEYWORD2 -stopConstCarrier KEYWORD2 -enableDynamicAck KEYWORD2 -isAckPayloadAvailable KEYWORD2 -printf_begin KEYWORD2 -sprintfPrettyDetails KEYWORD2 -encodeRadioDetails KEYWORD2 diff --git a/RF24/library.json b/RF24/library.json deleted file mode 100644 index a2d98a58a67b903ad9f62721532529e1611d8397..0000000000000000000000000000000000000000 --- a/RF24/library.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "RF24", - "keywords": "rf, radio, wireless, spi", - "description": "Radio driver, OSI layer 2 library for nRF24L01(+) transceiver modules.", - "license": "GPL-2.0-only", - "repository": { - "type": "git", - "url": "https://github.com/nRF24/RF24.git" - }, - "version": "1.4.6", - "export": { - "exclude": [ - "datasheets", - ".github/*", - "keywords.txt", - "configure", - "examples_pico/*", - "examples_linux/*", - "pyRF24/*", - "cmake/*", - "CMakeLists.txt", - "Makefile", - "utility/CMakeLists.txt", - "utility/wiringPi/*", - "utility/MRAA/*", - "utility/LittleWire/*", - "utility/RPi/*", - "utility/SPIDEV/*", - "utility/rp2/*", - "utility/ATXMegaD3/*" - ] - }, - "frameworks": "arduino", - "platforms": [ - "atmelavr", - "atmelsam", - "teensy", - "atmelmegaavr", - "espressif32", - "espressif8266", - "ststm32" - ] -} diff --git a/RF24/library.properties b/RF24/library.properties deleted file mode 100644 index 3f7e06f5eedf18e0934872e54df0b766fbfbbdb1..0000000000000000000000000000000000000000 --- a/RF24/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=RF24 -version=1.4.6 -author=TMRh20 -maintainer=TMRh20,Avamander -sentence=Radio driver, OSI layer 2 library for nrf24L01(+) modules. -paragraph=Core library for nRF24L01(+) communication. Simple to use for beginners, but offers advanced configuration options. Many examples are included to demonstrate various modes of communication. -category=Communication -url=https://nRF24.github.io/RF24/ -architectures=* diff --git a/RF24/nRF24L01.h b/RF24/nRF24L01.h deleted file mode 100644 index a072686a841cbbf88aba3e82e9cc724ee5553377..0000000000000000000000000000000000000000 --- a/RF24/nRF24L01.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de> - Portions Copyright (C) 2011 Greg Copeland - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -/* Memory Map */ -#define NRF_CONFIG 0x00 -#define EN_AA 0x01 -#define EN_RXADDR 0x02 -#define SETUP_AW 0x03 -#define SETUP_RETR 0x04 -#define RF_CH 0x05 -#define RF_SETUP 0x06 -#define NRF_STATUS 0x07 -#define OBSERVE_TX 0x08 -#define CD 0x09 -#define RX_ADDR_P0 0x0A -#define RX_ADDR_P1 0x0B -#define RX_ADDR_P2 0x0C -#define RX_ADDR_P3 0x0D -#define RX_ADDR_P4 0x0E -#define RX_ADDR_P5 0x0F -#define TX_ADDR 0x10 -#define RX_PW_P0 0x11 -#define RX_PW_P1 0x12 -#define RX_PW_P2 0x13 -#define RX_PW_P3 0x14 -#define RX_PW_P4 0x15 -#define RX_PW_P5 0x16 -#define FIFO_STATUS 0x17 -#define DYNPD 0x1C -#define FEATURE 0x1D - -/* Bit Mnemonics */ -#define MASK_RX_DR 6 -#define MASK_TX_DS 5 -#define MASK_MAX_RT 4 -#define EN_CRC 3 -#define CRCO 2 -#define PWR_UP 1 -#define PRIM_RX 0 -#define ENAA_P5 5 -#define ENAA_P4 4 -#define ENAA_P3 3 -#define ENAA_P2 2 -#define ENAA_P1 1 -#define ENAA_P0 0 -#define ERX_P5 5 -#define ERX_P4 4 -#define ERX_P3 3 -#define ERX_P2 2 -#define ERX_P1 1 -#define ERX_P0 0 -#define AW 0 -#define ARD 4 -#define ARC 0 -#define PLL_LOCK 4 -#define CONT_WAVE 7 -#define RF_DR 3 -#define RF_PWR 6 -#define RX_DR 6 -#define TX_DS 5 -#define MAX_RT 4 -#define RX_P_NO 1 -#define TX_FULL 0 -#define PLOS_CNT 4 -#define ARC_CNT 0 -#define TX_REUSE 6 -#define FIFO_FULL 5 -#define TX_EMPTY 4 -#define RX_FULL 1 -#define RX_EMPTY 0 -#define DPL_P5 5 -#define DPL_P4 4 -#define DPL_P3 3 -#define DPL_P2 2 -#define DPL_P1 1 -#define DPL_P0 0 -#define EN_DPL 2 -#define EN_ACK_PAY 1 -#define EN_DYN_ACK 0 - -/* Instruction Mnemonics */ -#define R_REGISTER 0x00 -#define W_REGISTER 0x20 -#define REGISTER_MASK 0x1F -#define ACTIVATE 0x50 -#define R_RX_PL_WID 0x60 -#define R_RX_PAYLOAD 0x61 -#define W_TX_PAYLOAD 0xA0 -#define W_ACK_PAYLOAD 0xA8 -#define FLUSH_TX 0xE1 -#define FLUSH_RX 0xE2 -#define REUSE_TX_PL 0xE3 -#define RF24_NOP 0xFF - -/* Non-P omissions */ -#define LNA_HCURR 0 - -/* P model memory Map */ -#define RPD 0x09 -#define W_TX_PAYLOAD_NO_ACK 0xB0 - -/* P model bit Mnemonics */ -#define RF_DR_LOW 5 -#define RF_DR_HIGH 3 -#define RF_PWR_LOW 1 -#define RF_PWR_HIGH 2 diff --git a/RF24/printf.h b/RF24/printf.h deleted file mode 100644 index 7c8d4b58eb45e1465827b2bd99e599f65561d6e6..0000000000000000000000000000000000000000 --- a/RF24/printf.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - */ -/* Galileo support from spaniakos <spaniakos@gmail.com> */ - -/** - * @file printf.h - * - * Setup necessary to direct stdout to the Arduino Serial library, which - * enables 'printf' - */ - -#ifndef __PRINTF_H__ -#define __PRINTF_H__ - -#if defined(ARDUINO_ARCH_AVR) || defined(__ARDUINO_X86__) || defined(ARDUINO_ARCH_MEGAAVR) - -int serial_putc(char c, FILE*) -{ - Serial.write(c); - return c; -} - -#elif defined(ARDUINO_ARCH_MBED) -REDIRECT_STDOUT_TO(Serial); - -#endif // defined (ARDUINO_ARCH_AVR) || defined (__ARDUINO_X86__) || defined (ARDUINO_ARCH_MBED) || defined (ARDUINO_ARCH_MEGAAVR) - -void printf_begin(void) -{ -#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR) - fdevopen(&serial_putc, 0); - -#elif defined(__ARDUINO_X86__) - // For redirect stdout to /dev/ttyGS0 (Serial Monitor port) - stdout = freopen("/dev/ttyGS0", "w", stdout); - delay(500); - printf("Redirecting to Serial..."); -#endif // defined(__ARDUINO_X86__) -} - -#endif // __PRINTF_H__ diff --git a/RF24/pyRF24/crossunixccompiler.py b/RF24/pyRF24/crossunixccompiler.py deleted file mode 100644 index 881d907d3008fc5fde59aff9b03828532d98b73f..0000000000000000000000000000000000000000 --- a/RF24/pyRF24/crossunixccompiler.py +++ /dev/null @@ -1,70 +0,0 @@ -import sys -from distutils import unixccompiler -from distutils import ccompiler - - -def register(): - sys.modules["distutils.crossunixccompiler"] = sys.modules[__name__] - ccompiler.compiler_class["crossunix"] = ( - __name__, - "CrossUnixCCompiler", - "UNIX-style compiler for cross compilation", - ) - - -def try_remove_all(lst, starts): - lst[:] = [x for x in lst if not x.startswith(starts)] - - -class CrossUnixCCompiler(unixccompiler.UnixCCompiler): - def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): - try_remove_all( - self.compiler_so, ("-m64", "-fstack-protector-strong", "-mtune=generic") - ) - try_remove_all(cc_args, "-I/usr") - try_remove_all(pp_opts, "-I/usr") - return unixccompiler.UnixCCompiler._compile( - self, obj, src, ext, cc_args, extra_postargs, pp_opts - ) - - def link( - self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None, - ): - try_remove_all(self.library_dirs, ("/usr")) - return unixccompiler.UnixCCompiler.link( - self, - target_desc, - objects, - output_filename, - output_dir, - libraries, - library_dirs, - runtime_library_dirs, - export_symbols, - debug, - extra_preargs, - extra_postargs, - build_temp, - target_lang, - ) - - def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs): - self.__class__ = unixccompiler.UnixCCompiler - ret = unixccompiler.UnixCCompiler._fix_lib_args( - self, libraries, library_dirs, runtime_library_dirs - ) - self.__class__ = CrossUnixCCompiler - return ret diff --git a/RF24/pyRF24/pyRF24.cpp b/RF24/pyRF24/pyRF24.cpp deleted file mode 100644 index 3f2e04fe031fbfa8b9e6abfc38568425bf35ed18..0000000000000000000000000000000000000000 --- a/RF24/pyRF24/pyRF24.cpp +++ /dev/null @@ -1,348 +0,0 @@ -#include <boost/python.hpp> -#include <RF24/RF24.h> - -namespace bp = boost::python; - -// ******************** explicit wrappers ************************** -// for methods which need it - mostly for buffer operations -// - -void throw_ba_exception(void) -{ - PyErr_SetString(PyExc_TypeError, "buf parameter must be bytes or bytearray"); - bp::throw_error_already_set(); -} - -char* get_bytes_or_bytearray_str(bp::object buf) -{ - PyObject* py_ba; - py_ba = buf.ptr(); - if (PyByteArray_Check(py_ba)) - return PyByteArray_AsString(py_ba); - else if (PyBytes_Check(py_ba)) - return PyBytes_AsString(py_ba); - else - throw_ba_exception(); - - return NULL; -} - -int get_bytes_or_bytearray_ln(bp::object buf) -{ - PyObject* py_ba; - py_ba = buf.ptr(); - if (PyByteArray_Check(py_ba)) - return PyByteArray_Size(py_ba); - else if (PyBytes_Check(py_ba)) - return PyBytes_Size(py_ba); - else - throw_ba_exception(); - - return 0; -} - -bp::object read_wrap(RF24& ref, int maxlen) -{ - char* buf = new char[maxlen + 1]; - ref.read(buf, maxlen); - bp::object py_ba(bp::handle<>(PyByteArray_FromStringAndSize(buf, maxlen < ref.getPayloadSize() ? maxlen : ref.getPayloadSize()))); - delete[] buf; - return py_ba; -} - -bool write_wrap1(RF24& ref, bp::object buf) -{ - return ref.write(get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf)); -} - -bool write_wrap2(RF24& ref, bp::object buf, const bool multicast) -{ - return ref.write(get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf), multicast); -} - -bool writeAckPayload_wrap(RF24& ref, uint8_t pipe, bp::object buf) -{ - return ref.writeAckPayload(pipe, get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf)); -} - -bool writeFast_wrap1(RF24& ref, bp::object buf) -{ - return ref.writeFast(get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf)); -} - -bool writeFast_wrap2(RF24& ref, bp::object buf, const bool multicast) -{ - return ref.writeFast(get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf), multicast); -} - -bool writeBlocking_wrap(RF24& ref, bp::object buf, uint32_t timeout) -{ - return ref.writeBlocking(get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf), timeout); -} - -void startFastWrite_wrap1(RF24& ref, bp::object buf, const bool multicast) -{ - ref.startFastWrite(get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf), multicast); -} - -void startFastWrite_wrap2(RF24& ref, bp::object buf, const bool multicast, bool startTx) -{ - ref.startFastWrite(get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf), multicast, startTx); -} - -void startWrite_wrap(RF24& ref, bp::object buf, const bool multicast) -{ - ref.startWrite(get_bytes_or_bytearray_str(buf), get_bytes_or_bytearray_ln(buf), multicast); -} - -void openWritingPipe_wrap(RF24& ref, const bp::object address) -{ - ref.openWritingPipe((const uint8_t*)(get_bytes_or_bytearray_str(address))); -} - -void openReadingPipe_wrap(RF24& ref, uint8_t number, const bp::object address) -{ - ref.openReadingPipe(number, (const uint8_t*)(get_bytes_or_bytearray_str(address))); -} - -bp::tuple whatHappened_wrap(RF24& ref) -{ - bool tx_ok; - bool tx_fail; - bool tx_ready; - - ref.whatHappened(tx_ok, tx_fail, tx_ready); - return bp::make_tuple(tx_ok, tx_fail, tx_ready); -} - -bp::tuple available_wrap(RF24& ref) -{ - bool result; - uint8_t pipe; - - result = ref.available(&pipe); - return bp::make_tuple(result, pipe); -} - -void setPALevel_wrap(RF24& ref, rf24_pa_dbm_e level) -{ - ref.setPALevel(level, 1); -} - -bool begin_with_pins(RF24& ref, uint16_t _cepin, uint16_t _cspin) -{ - return ref.begin(_cepin, _cspin); -} - -bp::object sprintfPrettyDetails_wrap(RF24& ref) -{ - char* buf = new char[870]; - ref.sprintfPrettyDetails(buf); - bp::object ret_str(bp::handle<>(PyUnicode_FromString(reinterpret_cast<const char*>(buf)))); - delete[] buf; - return ret_str; -} - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(txStandBy_wrap1, RF24::txStandBy, 0, 2) -//BOOST_PYTHON_FUNCTION_OVERLOADS(txStandBy_wrap2, RF24::txStandBy, 1, 2) - -// ******************** enums ************************** -// from both RF24 and bcm2835 - -BOOST_PYTHON_MODULE(RF24) -{ - -#ifdef BCM2835_H - bp::enum_<RPiGPIOPin>("RPiGPIOPin") - .value("RPI_GPIO_P1_03", RPI_GPIO_P1_03) - .value("RPI_GPIO_P1_05", RPI_GPIO_P1_05) - .value("RPI_GPIO_P1_07", RPI_GPIO_P1_07) - .value("RPI_GPIO_P1_08", RPI_GPIO_P1_08) - .value("RPI_GPIO_P1_10", RPI_GPIO_P1_10) - .value("RPI_GPIO_P1_11", RPI_GPIO_P1_11) - .value("RPI_GPIO_P1_12", RPI_GPIO_P1_12) - .value("RPI_GPIO_P1_13", RPI_GPIO_P1_13) - .value("RPI_GPIO_P1_15", RPI_GPIO_P1_15) - .value("RPI_GPIO_P1_16", RPI_GPIO_P1_16) - .value("RPI_GPIO_P1_18", RPI_GPIO_P1_18) - .value("RPI_GPIO_P1_19", RPI_GPIO_P1_19) - .value("RPI_GPIO_P1_21", RPI_GPIO_P1_21) - .value("RPI_GPIO_P1_22", RPI_GPIO_P1_22) - .value("RPI_GPIO_P1_23", RPI_GPIO_P1_23) - .value("RPI_GPIO_P1_24", RPI_GPIO_P1_24) - .value("RPI_GPIO_P1_26", RPI_GPIO_P1_26) - .value("RPI_V2_GPIO_P1_03", RPI_V2_GPIO_P1_03) - .value("RPI_V2_GPIO_P1_05", RPI_V2_GPIO_P1_05) - .value("RPI_V2_GPIO_P1_07", RPI_V2_GPIO_P1_07) - .value("RPI_V2_GPIO_P1_08", RPI_V2_GPIO_P1_08) - .value("RPI_V2_GPIO_P1_10", RPI_V2_GPIO_P1_10) - .value("RPI_V2_GPIO_P1_11", RPI_V2_GPIO_P1_11) - .value("RPI_V2_GPIO_P1_12", RPI_V2_GPIO_P1_12) - .value("RPI_V2_GPIO_P1_13", RPI_V2_GPIO_P1_13) - .value("RPI_V2_GPIO_P1_15", RPI_V2_GPIO_P1_15) - .value("RPI_V2_GPIO_P1_16", RPI_V2_GPIO_P1_16) - .value("RPI_V2_GPIO_P1_18", RPI_V2_GPIO_P1_18) - .value("RPI_V2_GPIO_P1_19", RPI_V2_GPIO_P1_19) - .value("RPI_V2_GPIO_P1_21", RPI_V2_GPIO_P1_21) - .value("RPI_V2_GPIO_P1_22", RPI_V2_GPIO_P1_22) - .value("RPI_V2_GPIO_P1_23", RPI_V2_GPIO_P1_23) - .value("RPI_V2_GPIO_P1_24", RPI_V2_GPIO_P1_24) - .value("RPI_V2_GPIO_P1_26", RPI_V2_GPIO_P1_26) - .value("RPI_V2_GPIO_P5_03", RPI_V2_GPIO_P5_03) - .value("RPI_V2_GPIO_P5_04", RPI_V2_GPIO_P5_04) - .value("RPI_V2_GPIO_P5_05", RPI_V2_GPIO_P5_05) - .value("RPI_V2_GPIO_P5_06", RPI_V2_GPIO_P5_06) - .value("RPI_BPLUS_GPIO_J8_03", RPI_BPLUS_GPIO_J8_03) - .value("RPI_BPLUS_GPIO_J8_05", RPI_BPLUS_GPIO_J8_05) - .value("RPI_BPLUS_GPIO_J8_07", RPI_BPLUS_GPIO_J8_07) - .value("RPI_BPLUS_GPIO_J8_08", RPI_BPLUS_GPIO_J8_08) - .value("RPI_BPLUS_GPIO_J8_10", RPI_BPLUS_GPIO_J8_10) - .value("RPI_BPLUS_GPIO_J8_11", RPI_BPLUS_GPIO_J8_11) - .value("RPI_BPLUS_GPIO_J8_12", RPI_BPLUS_GPIO_J8_12) - .value("RPI_BPLUS_GPIO_J8_13", RPI_BPLUS_GPIO_J8_13) - .value("RPI_BPLUS_GPIO_J8_15", RPI_BPLUS_GPIO_J8_15) - .value("RPI_BPLUS_GPIO_J8_16", RPI_BPLUS_GPIO_J8_16) - .value("RPI_BPLUS_GPIO_J8_18", RPI_BPLUS_GPIO_J8_18) - .value("RPI_BPLUS_GPIO_J8_19", RPI_BPLUS_GPIO_J8_19) - .value("RPI_BPLUS_GPIO_J8_21", RPI_BPLUS_GPIO_J8_21) - .value("RPI_BPLUS_GPIO_J8_22", RPI_BPLUS_GPIO_J8_22) - .value("RPI_BPLUS_GPIO_J8_23", RPI_BPLUS_GPIO_J8_23) - .value("RPI_BPLUS_GPIO_J8_24", RPI_BPLUS_GPIO_J8_24) - .value("RPI_BPLUS_GPIO_J8_26", RPI_BPLUS_GPIO_J8_26) - .value("RPI_BPLUS_GPIO_J8_29", RPI_BPLUS_GPIO_J8_29) - .value("RPI_BPLUS_GPIO_J8_31", RPI_BPLUS_GPIO_J8_31) - .value("RPI_BPLUS_GPIO_J8_32", RPI_BPLUS_GPIO_J8_32) - .value("RPI_BPLUS_GPIO_J8_33", RPI_BPLUS_GPIO_J8_33) - .value("RPI_BPLUS_GPIO_J8_35", RPI_BPLUS_GPIO_J8_35) - .value("RPI_BPLUS_GPIO_J8_36", RPI_BPLUS_GPIO_J8_36) - .value("RPI_BPLUS_GPIO_J8_37", RPI_BPLUS_GPIO_J8_37) - .value("RPI_BPLUS_GPIO_J8_38", RPI_BPLUS_GPIO_J8_38) - .value("RPI_BPLUS_GPIO_J8_40", RPI_BPLUS_GPIO_J8_40) - .export_values(); - - bp::enum_<bcm2835SPIClockDivider>("bcm2835SPIClockDivider") - .value("BCM2835_SPI_CLOCK_DIVIDER_65536", BCM2835_SPI_CLOCK_DIVIDER_65536) - .value("BCM2835_SPI_CLOCK_DIVIDER_32768", BCM2835_SPI_CLOCK_DIVIDER_32768) - .value("BCM2835_SPI_CLOCK_DIVIDER_16384", BCM2835_SPI_CLOCK_DIVIDER_16384) - .value("BCM2835_SPI_CLOCK_DIVIDER_8192", BCM2835_SPI_CLOCK_DIVIDER_8192) - .value("BCM2835_SPI_CLOCK_DIVIDER_4096", BCM2835_SPI_CLOCK_DIVIDER_4096) - .value("BCM2835_SPI_CLOCK_DIVIDER_2048", BCM2835_SPI_CLOCK_DIVIDER_2048) - .value("BCM2835_SPI_CLOCK_DIVIDER_1024", BCM2835_SPI_CLOCK_DIVIDER_1024) - .value("BCM2835_SPI_CLOCK_DIVIDER_512", BCM2835_SPI_CLOCK_DIVIDER_512) - .value("BCM2835_SPI_CLOCK_DIVIDER_256", BCM2835_SPI_CLOCK_DIVIDER_256) - .value("BCM2835_SPI_CLOCK_DIVIDER_128", BCM2835_SPI_CLOCK_DIVIDER_128) - .value("BCM2835_SPI_CLOCK_DIVIDER_64", BCM2835_SPI_CLOCK_DIVIDER_64) - .value("BCM2835_SPI_CLOCK_DIVIDER_32", BCM2835_SPI_CLOCK_DIVIDER_32) - .value("BCM2835_SPI_CLOCK_DIVIDER_16", BCM2835_SPI_CLOCK_DIVIDER_16) - .value("BCM2835_SPI_CLOCK_DIVIDER_8", BCM2835_SPI_CLOCK_DIVIDER_8) - .value("BCM2835_SPI_CLOCK_DIVIDER_4", BCM2835_SPI_CLOCK_DIVIDER_4) - .value("BCM2835_SPI_CLOCK_DIVIDER_2", BCM2835_SPI_CLOCK_DIVIDER_2) - .value("BCM2835_SPI_CLOCK_DIVIDER_1", BCM2835_SPI_CLOCK_DIVIDER_1) - .export_values(); - - bp::enum_<bcm2835SPIChipSelect>("bcm2835SPIChipSelect") - .value("BCM2835_SPI_CS0", BCM2835_SPI_CS0) - .value("BCM2835_SPI_CS1", BCM2835_SPI_CS1) - .value("BCM2835_SPI_CS2", BCM2835_SPI_CS2) - .value("BCM2835_SPI_CS_NONE", BCM2835_SPI_CS_NONE) - .export_values(); - -#endif // BCM2835_H - - bp::enum_<rf24_crclength_e>("rf24_crclength_e") - .value("RF24_CRC_DISABLED", RF24_CRC_DISABLED) - .value("RF24_CRC_8", RF24_CRC_8) - .value("RF24_CRC_16", RF24_CRC_16) - .export_values(); - - bp::enum_<rf24_datarate_e>("rf24_datarate_e") - .value("RF24_1MBPS", RF24_1MBPS) - .value("RF24_2MBPS", RF24_2MBPS) - .value("RF24_250KBPS", RF24_250KBPS) - .export_values(); - - bp::enum_<rf24_pa_dbm_e>("rf24_pa_dbm_e") - .value("RF24_PA_MIN", RF24_PA_MIN) - .value("RF24_PA_LOW", RF24_PA_LOW) - .value("RF24_PA_HIGH", RF24_PA_HIGH) - .value("RF24_PA_MAX", RF24_PA_MAX) - .value("RF24_PA_ERROR", RF24_PA_ERROR) - .export_values(); - - // ******************** RF24 class ************************** - bp::class_<RF24>("RF24", bp::init<uint16_t, uint16_t>((bp::arg("_cepin"), bp::arg("_cspin")))) -#if defined(RF24_LINUX) && !defined(MRAA) - .def(bp::init<uint16_t, uint16_t, uint32_t>((bp::arg("_cepin"), bp::arg("_cspin"), bp::arg("spispeed")))) - .def(bp::init<uint32_t>((bp::arg("spispeed")))) - .def(bp::init<>()) -#endif - .def("available", (bool (::RF24::*)())(&::RF24::available)) - .def("available_pipe", &available_wrap) // needed to rename this method as python does not allow such overloading - .def("begin", (bool (::RF24::*)(void))(&::RF24::begin)) - .def("begin", &begin_with_pins) - .def("closeReadingPipe", &RF24::closeReadingPipe) - .def("disableCRC", &RF24::disableCRC) - .def("enableAckPayload", &RF24::enableAckPayload) - .def("enableDynamicAck", &RF24::enableDynamicAck) - .def("enableDynamicPayloads", &RF24::enableDynamicPayloads) - .def("disableDynamicPayloads", &RF24::disableDynamicPayloads) - .def("flush_tx", &RF24::flush_tx) - .def("flush_rx", &RF24::flush_rx) - .def("getCRCLength", &RF24::getCRCLength) - .def("getDataRate", &RF24::getDataRate) - .def("getDynamicPayloadSize", &RF24::getDynamicPayloadSize) - .def("getPALevel", &RF24::getPALevel) - .def("isAckPayloadAvailable", &RF24::isAckPayloadAvailable) - .def("isPVariant", &RF24::isPVariant) - .def("isValid", &RF24::isValid) - .def("isChipConnected", &RF24::isChipConnected) - .def("maskIRQ", &RF24::maskIRQ, (bp::arg("tx_ok"), bp::arg("tx_fail"), bp::arg("rx_ready"))) - .def("openReadingPipe", &openReadingPipe_wrap, (bp::arg("number"), bp::arg("address"))) - .def("openReadingPipe", (void (::RF24::*)(::uint8_t, ::uint64_t))(&::RF24::openReadingPipe), (bp::arg("number"), bp::arg("address"))) - .def("openWritingPipe", &openWritingPipe_wrap, (bp::arg("address"))) - .def("openWritingPipe", (void (::RF24::*)(::uint64_t))(&::RF24::openWritingPipe), (bp::arg("address"))) - .def("powerDown", &RF24::powerDown) - .def("powerUp", &RF24::powerUp) - .def("printDetails", &RF24::printDetails) - .def("printPrettyDetails", &RF24::printPrettyDetails) - .def("sprintfPrettyDetails", &sprintfPrettyDetails_wrap) - .def("reUseTX", &RF24::reUseTX) - .def("read", &read_wrap, (bp::arg("maxlen"))) - .def("rxFifoFull", &RF24::rxFifoFull) - .def("isFifo", (uint8_t(::RF24::*)(bool))(&::RF24::isFifo), (bp::arg("about_tx"))) - .def("isFifo", (bool (::RF24::*)(bool, bool))(&::RF24::isFifo), (bp::arg("about_tx"), bp::arg("check_empty"))) - .def("setAddressWidth", &RF24::setAddressWidth) - .def("setAutoAck", (void (::RF24::*)(bool))(&::RF24::setAutoAck), (bp::arg("enable"))) - .def("setAutoAck", (void (::RF24::*)(::uint8_t, bool))(&::RF24::setAutoAck), (bp::arg("pipe"), bp::arg("enable"))) - .def("setCRCLength", &RF24::setCRCLength, (bp::arg("length"))) - .def("setDataRate", &RF24::setDataRate, (bp::arg("speed"))) - .def("setPALevel", &RF24::setPALevel, (bp::arg("level"), bp::arg("lnaEnable") = 1)) - .def("setPALevel", &setPALevel_wrap, (bp::arg("level"))) - .def("setRetries", &RF24::setRetries, (bp::arg("delay"), bp::arg("count"))) - .def("startFastWrite", &startFastWrite_wrap1, (bp::arg("buf"), bp::arg("len"), bp::arg("multicast"))) - .def("startFastWrite", &startFastWrite_wrap2, (bp::arg("buf"), bp::arg("len"), bp::arg("multicast"), bp::arg("startTx"))) - .def("startListening", &RF24::startListening) - .def("startWrite", &startWrite_wrap, (bp::arg("buf"), bp::arg("len"), bp::arg("multicast"))) - .def("stopListening", &RF24::stopListening) - .def("testCarrier", &RF24::testCarrier) - .def("testRPD", &RF24::testRPD) - .def("toggleAllPipes", &RF24::toggleAllPipes) - .def("setRadiation", &RF24::setRadiation) - .def("txStandBy", (bool (::RF24::*)(::uint32_t, bool))(&RF24::txStandBy), txStandBy_wrap1(bp::args("timeout", "startTx"))) - .def("whatHappened", &whatHappened_wrap) - .def("startConstCarrier", &RF24::startConstCarrier, (bp::arg("level"), bp::arg("channel"))) - .def("stopConstCarrier", &RF24::stopConstCarrier) - .def("write", &write_wrap1, (bp::arg("buf"))) - .def("write", &write_wrap2, (bp::arg("buf"), bp::arg("multicast"))) - .def("writeAckPayload", writeAckPayload_wrap, (bp::arg("pipe"), bp::arg("buf"))) - .def("writeBlocking", &writeBlocking_wrap, (bp::arg("buf"), bp::arg("timeout"))) - .def("writeFast", &writeFast_wrap1, (bp::arg("buf"))) - .def("writeFast", &writeFast_wrap2, (bp::arg("buf"), bp::arg("multicast"))) - .add_property("channel", &RF24::getChannel, &RF24::setChannel) - .def("setChannel", &RF24::setChannel, (bp::arg("channel"))) - .def("getChannel", &RF24::getChannel) - .add_property("payloadSize", &RF24::getPayloadSize, &RF24::setPayloadSize) - .def("setPayloadSize", &RF24::setPayloadSize, (bp::arg("size"))) - .def("getPayloadSize", &RF24::getPayloadSize) - .def_readwrite("failureDetected", &RF24::failureDetected); -} diff --git a/RF24/pyRF24/setup.py b/RF24/pyRF24/setup.py deleted file mode 100644 index bc9f0f7faae68ade3812859bef33c12a716521ac..0000000000000000000000000000000000000000 --- a/RF24/pyRF24/setup.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=invalid-name -import os -from sys import version_info -from setuptools import setup, Extension -import crossunixccompiler - -version = "" -cflags = os.getenv("CFLAGS", "") -symlink_directory = [] - -# NOTE current repo directory structure requires the use of -# `python3 setup.py build` and `python3 setup.py install` -# where `pip3 install ./pyRF24` copies pyRF24 directory to -# `tmp` folder that doesn't have the needed `../Makefile.inc` -# NOTE can't access "../Makefile.inc" from working dir because -# it's relative. Brute force absolute path dynamically. -git_dir = os.path.split(os.path.abspath(os.getcwd()))[0] - -try: # get compiler options from the generated Makefile.inc - with open(os.path.join(git_dir, "Makefile.inc"), "r", encoding="utf-8") as f: - for line in f.read().splitlines(): - identifier, value = line.split("=", 1) - if identifier == "CPUFLAGS": - # this is never reached as CPUFLAGS var is concatenated into CFLAGS var. - # however the CFLAGS var may conditionally contain "-lwiringPi" - cflags += " " + value - elif identifier == "HEADER_DIR": - cflags += " -I" + os.path.dirname(value) - elif identifier == "LIB_DIR": - cflags += " -L" + value - elif identifier == "LIB_VERSION": - version = value - elif identifier in ("CC", "CXX"): - os.environ[identifier] = value - -except FileNotFoundError: # assuming lib was built & installed with CMake - - # get LIB_VERSION from library.properties file for Arduino IDE - with open(os.path.join(git_dir, "library.properties"), "r", encoding="utf-8") as f: - for line in f.read().splitlines(): - if line.startswith("version"): - version = line.split("=")[1] - -# check C++ RF24 lib is installed -finally: - - # check for possible linker flags set via CFLAGS environment variable - for flag in cflags.split("-"): - if flag.startswith("L"): - symlink_directory.append( - flag[1:].strip() + (" " if len(symlink_directory) else "") - ) - - if not symlink_directory: - print( - "install location of librf24.so isn't explicit; trying default locations." - ) - symlink_directory = ["/usr/local/lib", "/usr/lib"] - - found_symlink = False - for symlink_loc in symlink_directory: - if os.path.isfile(symlink_loc + "/librf24.so"): - print("librf24.so found at", symlink_loc) - found_symlink = True - - if not found_symlink: - raise FileNotFoundError( - "RF24 library is not installed. librf24.so does not exist in {}.".format( - " or ".join(symlink_directory) - ) - ) - - # avoid IRQ support if pigpio is not available; link to pigpio if it is found - found_pigpio = False - for symlink_loc in symlink_directory: - if os.path.exists(symlink_loc + "/libpigpio.so"): - found_pigpio = True - # IRQ pin features will be implemented in python via pigpio's python API or RPi.GPIO - cflags += " -DRF24_NO_INTERRUPT" - -# append any additionally found compiler flags -os.environ["CFLAGS"] = cflags - -# get the proper boost.python lib symlink name according to version of python -if version_info >= (3,): - BOOST_LIB = "boost_python3" -else: - BOOST_LIB = "boost_python" - -crossunixccompiler.register() - -long_description = """ -.. warning:: This python wrapper for the RF24 C++ library was not intended - for distribution on pypi.org. If you're reading this, then this package - is likely unauthorized or unofficial. -""" - - -setup( - name="RF24", - version=version, - license="GPLv2", - license_files=(os.path.join(git_dir, "LICENSE"),), - long_description=long_description, - long_description_content_type="text/x-rst", - classifiers=[ - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Programming Language :: C++", - "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", - ], - ext_modules=[ - Extension( - "RF24", - sources=["pyRF24.cpp"], - libraries=["rf24", BOOST_LIB] + (["pigpio"] if found_pigpio else []) - ) - ], -) diff --git a/RF24/utility/ATTiny/RF24_arch_config.h b/RF24/utility/ATTiny/RF24_arch_config.h deleted file mode 100644 index f46a966f4298e94138cc4ca82cdadd10b69564d9..0000000000000000000000000000000000000000 --- a/RF24/utility/ATTiny/RF24_arch_config.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - TMRh20 2015 - ATTiny Configuration File -*/ - -#ifndef RF24_UTILITY_ATTINY_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_ATTINY_RF24_ARCH_CONFIG_H_ - -/*** USER DEFINES: ***/ -//#define FAILURE_HANDLING -//#define MINIMAL -/**********************/ - -#define rf24_max(a, b) (a > b ? a : b) -#define rf24_min(a, b) (a < b ? a : b) - -#if ARDUINO < 100 - #include <WProgram.h> -#else - #include <Arduino.h> -#endif - -#include <stddef.h> - -#include <SPI.h> - -#define _SPI SPI - -#if !defined(RF24_CSN_SETTLE_LOW_DELAY) - #define RF24_CSN_SETTLE_LOW_DELAY 11 -#endif - -#if !defined(RF24_CSN_SETTLE_HIGH_DELAY) - #define RF24_CSN_SETTLE_HIGH_DELAY 100 -#endif - -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) - - #if defined(RF24_TINY) - #define printf_P(...) - #endif -#endif // !defined(SERIAL_DEBUG) - -#include <avr/pgmspace.h> - -#define PRIPSTR "%S" - -#endif // RF24_UTILITY_ATTINY_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/ATXMegaD3/RF24_arch_config.h b/RF24/utility/ATXMegaD3/RF24_arch_config.h deleted file mode 100644 index 8c4bd38c79c8d86d90d2c79ce5ca6232b1c864b7..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/RF24_arch_config.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -/** - * @file RF24_arch_config.h - * General defines and includes for RF24/Linux - */ - -#ifndef RF24_UTILITY_ATXMEGAD3_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_ATXMEGAD3_RF24_ARCH_CONFIG_H_ - -#include <stddef.h> -#include <avr/pgmspace.h> -#include "spi.h" -#include "gpio.h" -#include "compatibility.h" -#include <stdint.h> -#include <stdio.h> -//#include <time.h> -#include <string.h> -//#include <sys/time.h> - -//#define _BV(x) (1<<(x)) -#define _SPI SPI -#define RF24_SPI_PTR - -#undef SERIAL_DEBUG -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -// Use the avr pgmspace commands -//// Avoid spurious warnings -//#if 1 -//#if ! defined( NATIVE ) && defined( ARDUINO ) -//#undef PROGMEM -//#define PROGMEM __attribute__(( section(".progmem.data") )) -//#undef PSTR -//#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) -//#endif -//#endif - -typedef uint16_t prog_uint16_t; -//#define PSTR(x) (x) -//#define printf_P printf -//#define strlen_P strlen -//#define PROGMEM -//#define pgm_read_word(p) (*(const unsigned short *)(p)) -#define PRIPSTR "%s" -//#define pgm_read_byte(p) (*(const unsigned char *)(p)) - -// Function, constant map as a result of migrating from Arduino -#define LOW GPIO::OUTPUT_LOW -#define HIGH GPIO::OUTPUT_HIGH -#define INPUT GPIO::DIRECTION_IN -#define OUTPUT GPIO::DIRECTION_OUT -#define digitalWrite(pin, value) GPIO::write(pin, value) -#define pinMode(pin, direction) GPIO::open(pin, direction) -#define delay(milisec) __msleep(milisec) -#define delayMicroseconds(usec) __usleep(usec) -#define millis() __millis() - -#endif // RF24_UTILITY_ATXMEGAD3_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/ATXMegaD3/compatibility.c b/RF24/utility/ATXMegaD3/compatibility.c deleted file mode 100644 index 4f8437e88f571ba930c33a84dbfc0ff8fd4351fa..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/compatibility.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * compatibility.c - * - * Created: 19/1/2016 15:31:35 - * Author: akatran - */ - -#include <avr/io.h> -#include <stdint.h> -#include <util/delay.h> - -volatile uint32_t _millis; - -void __msleep(int milisec) -{ - while (milisec-- > 0) { - _delay_ms(1); - } -} - -void __usleep(int usec) -{ - while (usec-- > 0) { - _delay_us(1); - } -} - -void __start_timer() -{ - // Timer details : Clock is 32MHz, Timer resolution is 8bit, Prescaler is 256, Period is 124, Real Time is 0.001s - - /* Set the timer to run at the fastest rate. */ - TCE0.CTRLA = TC_CLKSEL_DIV256_gc; - - /* Configure the timer for normal counting. */ - TCE0.CTRLB = TC_WGMODE_NORMAL_gc; - - /* At 2 MHz, one tick is 0.5 us. Set period to 8 us. */ - TCE0.PER = 124; - //TCC0.PER = 2; - - /* Configure timer to generate an interrupt on overflow. */ - TCE0.INTCTRLA = TC_OVFINTLVL_HI_gc; - - /* Enable this interrupt level. */ - PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; - - _millis = 0; -} - -long __millis() -{ - return _millis; -} - -void update_milisec() -{ - _millis++; -} diff --git a/RF24/utility/ATXMegaD3/compatibility.h b/RF24/utility/ATXMegaD3/compatibility.h deleted file mode 100644 index 75b04b2e80a691ecfff7965a288d5e86e04459a6..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/compatibility.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file compatibility.h - * @author purinda - * - * Created on 24 June 2012, 3:08 PM - * - * Class declaration for SPI helper files - */ - -#ifndef RF24_UTILITY_ATXMEGAD3_COMPATIBLITY_H_ -#define RF24_UTILITY_ATXMEGAD3_COMPATIBLITY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stddef.h> -//#include <time.h> -//#include <sys/time.h> - -void __msleep(int milisec); - -void __usleep(int usec); - -void __start_timer(); - -long __millis(); - -void update_milisec(); - -#ifdef __cplusplus -} -#endif - -#endif // RF24_UTILITY_ATXMEGAD3_COMPATIBLITY_H_ diff --git a/RF24/utility/ATXMegaD3/gpio.cpp b/RF24/utility/ATXMegaD3/gpio.cpp deleted file mode 100644 index 4195ab8665c3fcc530ef5165eabb17fdd44a9dae..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/gpio.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * gpio.cpp - * - * Created: 20/1/2016 11:57:21 - * Author: akatran - */ - -//#include "gpio_helper.h" -#include "gpio.h" -#include <stdlib.h> - -void GPIO::open(int port, int DDR) -{ - uint8_t pin; - PORT_t* p = GPIO_getPort(port, &pin); - if (DDR == 0) { - p->DIRCLR = pin; - } - else if (DDR == 1) { - p->DIRSET = pin; - } -} - -void GPIO::close(int port) -{ - // Nothing to do with close; -} - -int GPIO::read(int port) -{ - uint8_t pin; - PORT_t* p = GPIO_getPort(port, &pin); - return p->IN; -} - -void GPIO::write(int port, int value) -{ - uint8_t pin; - PORT_t* p = GPIO_getPort(port, &pin); - if (value == 0) { - p->OUTCLR = pin; - } - else if (value == 1) { - p->OUTSET = pin; - } -} diff --git a/RF24/utility/ATXMegaD3/gpio.h b/RF24/utility/ATXMegaD3/gpio.h deleted file mode 100644 index b63e8eec01590fbb49b0230fc16b482772ec44af..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/gpio.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file gpio.h - * Class declaration for SPI helper files - */ -#ifndef RF24_UTILITY_ATXMEGAD3_GPIO_H_ -#define RF24_UTILITY_ATXMEGAD3_GPIO_H_ - -#include <avr/io.h> -#include "gpio_helper.h" - -class GPIO -{ - -public: - static const int DIRECTION_OUT = 1; - static const int DIRECTION_IN = 0; - - static const int OUTPUT_HIGH = 1; - static const int OUTPUT_LOW = 0; - - GPIO(); - - static void open(int port, int DDR); - - static void close(int port); - - static int read(int port); - - static void write(int port, int value); - - virtual ~GPIO(); -}; - -#endif // RF24_UTILITY_ATXMEGAD3_GPIO_H_ diff --git a/RF24/utility/ATXMegaD3/gpio_helper.c b/RF24/utility/ATXMegaD3/gpio_helper.c deleted file mode 100644 index 7c5a2864321b518f552544bf99f20965c9345715..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/gpio_helper.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * gpio_helper.c - * - * Created: 22/1/2016 15:28:48 - * Author: akatran - */ - -#include "gpio_helper.h" - -/** - * Get the port corresponding in portnum. Default is PORTC. - */ -PORT_t* GPIO_getPort(int pinnum, uint8_t* pin_bm) -//PORT_t * GPIO_getPort(int portnum) -{ - PORT_t* port = &PORTC; - if ((pinnum >= XMEGA_PORTA_PIN0) && (pinnum <= XMEGA_PORTA_PIN7)) { - port = &PORTA; - *pin_bm = (1 << pinnum); - } - else if ((pinnum >= XMEGA_PORTB_PIN0) && (pinnum <= XMEGA_PORTB_PIN7)) { - port = &PORTB; - *pin_bm = (1 << (pinnum - 8)); - } - else if ((pinnum >= XMEGA_PORTC_PIN0) && (pinnum <= XMEGA_PORTC_PIN7)) { - port = &PORTC; - *pin_bm = (1 << (pinnum - 16)); - } - else if ((pinnum >= XMEGA_PORTD_PIN0) && (pinnum <= XMEGA_PORTD_PIN7)) { - port = &PORTD; - *pin_bm = (1 << (pinnum - 24)); - } - else if ((pinnum >= XMEGA_PORTE_PIN0) && (pinnum <= XMEGA_PORTE_PIN7)) { - port = &PORTE; - *pin_bm = (1 << (pinnum - 32)); - } - else if ((pinnum >= XMEGA_PORTF_PIN0) && (pinnum <= XMEGA_PORTF_PIN7)) { - port = &PORTF; - *pin_bm = (1 << (pinnum - 40)); - } - - return port; -} diff --git a/RF24/utility/ATXMegaD3/gpio_helper.h b/RF24/utility/ATXMegaD3/gpio_helper.h deleted file mode 100644 index b41a22af8fd012b0b5ab65263f956e82769f9a01..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/gpio_helper.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file gpio_helper.h - * @author akatran - * - * Created: 22/1/2016 15:29:12 - */ -#ifndef RF24_UTILITY_MRAA_GPIO_HELPER_H_ -#define RF24_UTILITY_MRAA_GPIO_HELPER_H_ - -#include <avr/io.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* Defines */ - -#define XMEGA_PORTA_PIN0 0 -#define XMEGA_PORTA_PIN1 1 -#define XMEGA_PORTA_PIN2 2 -#define XMEGA_PORTA_PIN3 3 -#define XMEGA_PORTA_PIN4 4 -#define XMEGA_PORTA_PIN5 5 -#define XMEGA_PORTA_PIN6 6 -#define XMEGA_PORTA_PIN7 7 - -#define XMEGA_PORTB_PIN0 8 -#define XMEGA_PORTB_PIN1 9 -#define XMEGA_PORTB_PIN2 10 -#define XMEGA_PORTB_PIN3 11 -#define XMEGA_PORTB_PIN4 12 -#define XMEGA_PORTB_PIN5 13 -#define XMEGA_PORTB_PIN6 14 -#define XMEGA_PORTB_PIN7 15 - -#define XMEGA_PORTC_PIN0 16 -#define XMEGA_PORTC_PIN1 17 -#define XMEGA_PORTC_PIN2 18 -#define XMEGA_PORTC_PIN3 19 -#define XMEGA_PORTC_PIN4 20 -#define XMEGA_PORTC_PIN5 21 -#define XMEGA_PORTC_PIN6 22 -#define XMEGA_PORTC_PIN7 23 - -#define XMEGA_PORTD_PIN0 24 -#define XMEGA_PORTD_PIN1 25 -#define XMEGA_PORTD_PIN2 26 -#define XMEGA_PORTD_PIN3 27 -#define XMEGA_PORTD_PIN4 28 -#define XMEGA_PORTD_PIN5 29 -#define XMEGA_PORTD_PIN6 30 -#define XMEGA_PORTD_PIN7 31 - -#define XMEGA_PORTE_PIN0 32 -#define XMEGA_PORTE_PIN1 33 -#define XMEGA_PORTE_PIN2 34 -#define XMEGA_PORTE_PIN3 35 -#define XMEGA_PORTE_PIN4 36 -#define XMEGA_PORTE_PIN5 37 -#define XMEGA_PORTE_PIN6 38 -#define XMEGA_PORTE_PIN7 39 - -#define XMEGA_PORTF_PIN0 40 -#define XMEGA_PORTF_PIN1 41 -#define XMEGA_PORTF_PIN2 42 -#define XMEGA_PORTF_PIN3 43 -#define XMEGA_PORTF_PIN4 44 -#define XMEGA_PORTF_PIN5 45 -#define XMEGA_PORTF_PIN6 46 -#define XMEGA_PORTF_PIN7 47 - -#define XMEGA_SPI_PORT_C 20 -#define XMEGA_SPI_PORT_D 28 - -//void GPIO_getPort(int pinnum, PORT_t * port, uint8_t pin); -//void GPIO_getPort(int pinnum, PORT_t * port, uint8_t * pin_bm); -PORT_t* GPIO_getPort(int pinnum, uint8_t* pin_bm); - -#ifdef __cplusplus -} -#endif - -#endif // RF24_UTILITY_MRAA_GPIO_HELPER_H_ diff --git a/RF24/utility/ATXMegaD3/includes.h b/RF24/utility/ATXMegaD3/includes.h deleted file mode 100644 index 2cbf987f8ce450ec9d9d8705adba41017e4cceb0..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/includes.h +++ /dev/null @@ -1,19 +0,0 @@ -/** -* @file includes.h -* Configuration defines for RF24/Linux -*/ - -#ifndef RF24_UTILITY_INCLUDES_H_ -#define RF24_UTILITY_INCLUDES_H_ - -/** - * Define a specific platform for this configuration - */ -// #define RF24_BBB - -/** - * Load the correct configuration for this platform - */ -// #include "BBB/RF24_arch_config.h" - -#endif // RF24_UTILITY_INCLUDES_H_ diff --git a/RF24/utility/ATXMegaD3/spi.cpp b/RF24/utility/ATXMegaD3/spi.cpp deleted file mode 100644 index b6b664ba3d38755f9ea55a0bbb10588f0109d14c..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/spi.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * spi.cpp - * - * Created: 20/1/2016 10:10:39 - * Author: akatran - */ - -#include <avr/io.h> -#include "gpio_helper.h" -#include "spi.h" - -using namespace std; - -void SPI::begin(uint8_t _port) -{ - if (_port == XMEGA_SPI_PORT_C) // Select SPI on PORTC - { - device = &SPIC; - port = &PORTC; - } - else if (_port == XMEGA_SPI_PORT_D) // Select SPI on PORTD - { - device = &SPID; - port = &PORTD; - } - - init(); -} - -uint8_t SPI::transfer(uint8_t tx_) -{ - register8_t data; - device->DATA = tx_; - while (!(device->STATUS & (1 << 7))) { - } - data = device->DATA; - //PORTF.OUT = data; - return data; -} - -void SPI::init() -{ - port->DIRCLR = SPI_MISO_bm; - port->DIRSET = SPI_MOSI_bm | SPI_SCK_bm | SPI_SS_bm; - - //device->CTRL = 0; - device->CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_MODE_0_gc | SPI_PRESCALER_DIV4_gc; - device->INTCTRL = 0; //Disable interrupts -} - -SPI::SPI() -{ -} - -SPI::~SPI() -{ -} - -void operator delete(void* p) // or delete(void *, std::size_t) -{ -} diff --git a/RF24/utility/ATXMegaD3/spi.h b/RF24/utility/ATXMegaD3/spi.h deleted file mode 100644 index 7bf02164c5b2dce5073822e85585d7569efe25fc..0000000000000000000000000000000000000000 --- a/RF24/utility/ATXMegaD3/spi.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @file spi.h - * Class declaration for SPI helper files - */ -#ifndef RF24_UTILITY_ATXMEGAD3_SPI_H_ -#define RF24_UTILITY_ATXMEGAD3_SPI_H_ - -#include <avr/io.h> -#include <stdint.h> -//#include <string.h> -//#include <unistd.h> -//#include <stdio.h> -//#include <stdlib.h> -//#include <getopt.h> -//#include <fcntl.h> -//#include <sys/ioctl.h> -//#include <inttypes.h> -//#include <linux/types.h> -//#include <linux/spi/spidev.h> - -#define SPI_SS_bm (1 << 4) /* SPI SS pin mask 4 */ -#define SPI_MOSI_bm (1 << 5) /* SPI MOSI pin mask 5 */ -#define SPI_MISO_bm (1 << 6) /* SPI MISO pin mask 6 */ -#define SPI_SCK_bm (1 << 7) /* SPI SCK pin mask 7 */ - -using namespace std; - -class SPI -{ - -public: - SPI(); - - /** - * Start SPI - * @param port is the SPI port (XMEGA_SPI_PORT_C for SPI on PORTC, XMEGA_SPI_PORT_D on PORTD etc). - */ - void begin(uint8_t port); - - uint8_t transfer(uint8_t tx_); - - void transfernb(char* tbuf, char* rbuf, uint32_t len); - - void transfern(char* buf, uint32_t len); - - virtual ~SPI(); - -private: - /** Default SPI device */ - SPI_t* device; - /* Port of the SPI */ - PORT_t* port; - - void init(); -}; - -#endif //RF24_UTILITY_ATXMEGAD3_SPI_H_ diff --git a/RF24/utility/CMakeLists.txt b/RF24/utility/CMakeLists.txt deleted file mode 100644 index 656c89b14d625c0ce8747d7adf5c56fab6e6fb57..0000000000000000000000000000000000000000 --- a/RF24/utility/CMakeLists.txt +++ /dev/null @@ -1,155 +0,0 @@ -########################### -### declare the appropriate sources and install rules based on driver selected -########################### -if ("${RF24_DRIVER}" STREQUAL "wiringPi") # Use wiringPi - set(RF24_LINKED_DRIVER ${LibWiringPi} PARENT_SCOPE) - add_compile_options(-pthread) - set(RF24_DRIVER_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/spi.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h - PARENT_SCOPE - ) - install(FILES - ${RF24_DRIVER}/includes.h - ${RF24_DRIVER}/spi.h - ${RF24_DRIVER}/RF24_arch_config.h - DESTINATION include/RF24/utility/${RF24_DRIVER} - ) -elseif("${RF24_DRIVER}" STREQUAL "RPi") # use RPi - install(FILES - ${RF24_DRIVER}/includes.h - ${RF24_DRIVER}/bcm2835.h - ${RF24_DRIVER}/spi.h - ${RF24_DRIVER}/compatibility.h - ${RF24_DRIVER}/RF24_arch_config.h - DESTINATION include/RF24/utility/${RF24_DRIVER} - ) - if(NOT "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND" AND NOT DEFINED RF24_NO_INTERRUPT) - set(RF24_LINKED_DRIVER ${LibPIGPIO} PARENT_SCOPE) - message(STATUS "linking to pigpio lib for interrupt functionality") - install(FILES - ${RF24_DRIVER}/interrupt.h - DESTINATION include/RF24/utility/${RF24_DRIVER} - ) - set(RF24_DRIVER_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/bcm2835.c - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/spi.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/compatibility.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/interrupt.cpp - PARENT_SCOPE - ) - else() - set(RF24_DRIVER_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/bcm2835.c - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/spi.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/compatibility.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h - PARENT_SCOPE - ) - endif() -elseif("${RF24_DRIVER}" STREQUAL "SPIDEV") # use SPIDEV - if(NOT SPIDEV_EXISTS) - message(WARNING "Detecting /dev/spidev0.0 failed - continuing anyway. Please make sure SPI is enabled.") - endif() - install(FILES - ${RF24_DRIVER}/includes.h - ${RF24_DRIVER}/gpio.h - ${RF24_DRIVER}/spi.h - ${RF24_DRIVER}/compatibility.h - ${RF24_DRIVER}/RF24_arch_config.h - DESTINATION include/RF24/utility/${RF24_DRIVER} - ) - if(NOT "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND" AND NOT DEFINED RF24_NO_INTERRUPT) - set(RF24_LINKED_DRIVER ${LibPIGPIO} PARENT_SCOPE) - message(STATUS "linking to pigpio lib for interrupt functionality") - install(FILES - ${RF24_DRIVER}/interrupt.h - DESTINATION include/RF24/utility/${RF24_DRIVER} - ) - set(RF24_DRIVER_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/gpio.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/spi.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/compatibility.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/interrupt.cpp - PARENT_SCOPE - ) - else() - set(RF24_DRIVER_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/gpio.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/spi.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/compatibility.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h - PARENT_SCOPE - ) - endif() -elseif("${RF24_DRIVER}" STREQUAL "MRAA") # use MRAA - set(RF24_LINKED_DRIVER ${LibMRAA} PARENT_SCOPE) - set(RF24_DRIVER_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/gpio.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/spi.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/compatibility.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h - PARENT_SCOPE - ) - install(FILES - ${RF24_DRIVER}/includes.h - ${RF24_DRIVER}/gpio.h - ${RF24_DRIVER}/spi.h - ${RF24_DRIVER}/compatibility.h - ${RF24_DRIVER}/RF24_arch_config.h - DESTINATION include/RF24/utility/${RF24_DRIVER} - ) -elseif("${RF24_DRIVER}" STREQUAL "pigpio") # use pigpio - set(RF24_LINKED_DRIVER ${LibPIGPIO} PARENT_SCOPE) - set(RF24_DRIVER_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/gpio.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/spi.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/compatibility.cpp - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/interrupt.cpp - PARENT_SCOPE - ) - install(FILES - ${RF24_DRIVER}/includes.h - ${RF24_DRIVER}/gpio.h - ${RF24_DRIVER}/spi.h - ${RF24_DRIVER}/compatibility.h - ${RF24_DRIVER}/RF24_arch_config.h - ${RF24_DRIVER}/interrupt.h - DESTINATION include/RF24/utility/${RF24_DRIVER} - ) -elseif("${RF24_DRIVER}" STREQUAL "LittleWire") # use LittleWire - set(RF24_LINKED_DRIVER ${LibLittleWire} PARENT_SCOPE) - set(RF24_DRIVER_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h - ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/RF24_arch_config.h - PARENT_SCOPE - ) - install(FILES - ${RF24_DRIVER}/includes.h - ${RF24_DRIVER}/RF24_arch_config.h - DESTINATION include/RF24/utility/${RF24_DRIVER} - ) -else() # No valid/supported driver selected nor detected... this is vital - message(FATAL_ERROR "No valid/supported driver selected or auto-detection failed to resolve one. - Please specify 1 of the following supported drivers (ie `-D RF24_DRIVER=SPIDEV`): - \twiringPi - \tRPi - \tSPIDEV - \tMRAA - \tLittleWire - \tpigpio" - ) -endif() - -# copy the includes file to the project source directory's utility folder -execute_process(COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/${RF24_DRIVER}/includes.h ${CMAKE_CURRENT_LIST_DIR}/includes.h) diff --git a/RF24/utility/LittleWire/RF24_arch_config.h b/RF24/utility/LittleWire/RF24_arch_config.h deleted file mode 100644 index c35d4721396923f2c947faf011628dea8e4b6f33..0000000000000000000000000000000000000000 --- a/RF24/utility/LittleWire/RF24_arch_config.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef RF24_UTILITY_LITTLEWIRE_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_LITTLEWIRE_RF24_ARCH_CONFIG_H_ - -#include <stdint.h> -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <sys/time.h> -#include <stddef.h> - -// Additional fixes for LittleWire -#include <LittleWireSPI/littlewirespi.h> -#include <LittleWireSPI/avr_fixes.h> - -extern LittleWireSPI _SPI; - -// GCC a Arduino Missing -#define _BV(x) (1 << (x)) -#define pgm_read_word(p) (*(const unsigned short*)(p)) -#define pgm_read_byte(p) (*(const unsigned char*)(p)) -#define pgm_read_ptr(p) (*(void* const*)(p)) - -//typedef uint16_t prog_uint16_t; -#define PSTR(x) (x) -#define printf_P printf -#define strlen_P strlen -#define PROGMEM -#define PRIPSTR "%s" - -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) - #if defined(RF24_TINY) - #define printf_P(...) - #endif -#endif - -#endif // RF24_UTILITY_LITTLEWIRE_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/LittleWire/includes.h b/RF24/utility/LittleWire/includes.h deleted file mode 100644 index dd0b6a88794c5e5238b3956a1848872e6390d32e..0000000000000000000000000000000000000000 --- a/RF24/utility/LittleWire/includes.h +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @file includes.h - * Configuration defines for RF24/Linux - */ - -#ifndef RF24_UTILITY_INCLUDES_H_ -#define RF24_UTILITY_INCLUDES_H_ - -/** - * Define a specific platform for this configuration - */ -#define LITTLEWIRE - -/** - * Load the correct configuration for this platform - */ -#include "LittleWire/RF24_arch_config.h" - -#endif // RF24_UTILITY_INCLUDES_H_ diff --git a/RF24/utility/MRAA/RF24_arch_config.h b/RF24/utility/MRAA/RF24_arch_config.h deleted file mode 100644 index ff267ab27934c16c6c729123e9fd47532012b123..0000000000000000000000000000000000000000 --- a/RF24/utility/MRAA/RF24_arch_config.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef RF24_UTILITY_MRAA_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_MRAA_RF24_ARCH_CONFIG_H_ - -#include "mraa.h" -#include "spi.h" -#include "gpio.h" -#include "compatibility.h" - -#include <stdint.h> -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <sys/time.h> -#include <stddef.h> -#include <iostream> -#include <unistd.h> -#include <stdlib.h> - -//#include <UtilTime.h> // Precompiled arduino x86 based utiltime for timing functions - -// GCC a Arduino Missing -#define HIGH 1 -#define LOW 0 -#define _BV(x) (1 << (x)) -#define pgm_read_word(p) (*(const unsigned short*)(p)) -#define pgm_read_byte(p) (*(const unsigned char*)(p)) -#define pgm_read_ptr(p) (*(void* const*)(p)) -#define _SPI spi - -#define RF24_LINUX -//typedef uint16_t prog_uint16_t; -#define PSTR(x) (x) -#define printf_P printf -#define sprintf_P sprintf -#define strlen_P strlen -#define PROGMEM -#define PRIPSTR "%s" - -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -#define digitalWrite(pin, value) gpio.write(pin, value) -#define digitalRead(pin) GPIO::read(pin) -#define pinMode(pin, direction) gpio.open(pin, direction) - -#ifndef __TIME_H__ - // Prophet: Redefine time functions only if precompiled arduino time is not included - #define delay(milisec) __msleep(milisec) - #define delayMicroseconds(usec) __usleep(usec) - #define millis() __millis() -#endif - -#define INPUT mraa::DIR_IN -#define OUTPUT mraa::DIR_OUT - -// SPI defines for ARDUINO API -#define MSBFIRST 1 -//#define SPI_MODE0 mraa::SPI_MODE0 -#define SPI_CLOCK_DIV2 RF24_SPI_SPEED - -#endif // RF24_UTILITY_MRAA_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/MRAA/compatibility.cpp b/RF24/utility/MRAA/compatibility.cpp deleted file mode 100644 index 8593fbd0b7fa4a6fb72937364ce0b91ae9516638..0000000000000000000000000000000000000000 --- a/RF24/utility/MRAA/compatibility.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "compatibility.h" -#include <chrono> -//static struct timeval start, end; -//static long mtime, seconds, useconds; - -/**********************************************************************/ -/** - * This function is added in order to simulate arduino delay() function - * @param milisec - */ -void __msleep(int milisec) -{ - struct timespec req = {0}; - req.tv_sec = 0; - req.tv_nsec = milisec * 1000000L; - nanosleep(&req, (struct timespec*)NULL); - //usleep(milisec*1000); -} - -void __usleep(int milisec) -{ - struct timespec req = {0}; - req.tv_sec = 0; - req.tv_nsec = milisec * 1000L; - nanosleep(&req, (struct timespec*)NULL); - //usleep(milisec); -} - -auto start = std::chrono::steady_clock::now(); - -/** - * This function is added in order to simulate arduino millis() function - */ -void __start_timer() -{ - //gettimeofday(&start, NULL); -} - -long __millis() -{ - auto end = std::chrono::steady_clock::now(); - - return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); -} diff --git a/RF24/utility/MRAA/compatibility.h b/RF24/utility/MRAA/compatibility.h deleted file mode 100644 index ffc6953fbfbe5867a4fb35ee4d35da9e67dcc7b9..0000000000000000000000000000000000000000 --- a/RF24/utility/MRAA/compatibility.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file compatiblity.h - * @author purinda - * - * Created on 24 June 2012, 3:08 PM - */ - -#ifndef RF24_UTILITY_MRAA_COMPATIBLITY_H_ -#define RF24_UTILITY_MRAA_COMPATIBLITY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stddef.h> -#include <time.h> -#include <sys/time.h> - -void __msleep(int milisec); - -void __usleep(int milisec); - -void __start_timer(); - -long __millis(); - -#ifdef __cplusplus -} -#endif - -#endif // RF24_UTILITY_MRAA_COMPATIBLITY_H_ diff --git a/RF24/utility/MRAA/gpio.cpp b/RF24/utility/MRAA/gpio.cpp deleted file mode 100644 index 31d249583c438788eb6828947d482edb519c618e..0000000000000000000000000000000000000000 --- a/RF24/utility/MRAA/gpio.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * TMRh20 2015 - * - */ - -#include "gpio.h" - -GPIO::GPIO() -{ - // Prophet: basic members initialization - gpio_ce_pin = -1; - //gpio_cs_pin = -1; - gpio_0 = NULL; - //gpio_1 = NULL; -} - -GPIO::~GPIO() -{ - // Prophet: this should free memory, and unexport pins when RF24 and/or GPIO gets deleted or goes out of scope - this->close(gpio_ce_pin); - //this->close(gpio_cs_pin); -} - -void GPIO::begin(uint8_t ce_pin, uint8_t cs_pin) -{ - gpio_ce_pin = ce_pin; - //gpio_cs_pin = cs_pin; - - // Prophet: owner can be set here, because we use our pins exclusively, and are making mraa:Gpio context persistent - // so pins will be unexported only if close is called, or on destruction - gpio_0 = new mraa::Gpio(ce_pin /*,0*/); - //gpio_1 = new mraa::Gpio(cs_pin/*,0*/); -} - -void GPIO::open(int port, int DDR) -{ - if (port == gpio_ce_pin) { - gpio_0 = new mraa::Gpio(port, 0); - // WARNING: use of memory mapped file system is deprecated in MRAA lib - gpio_0->useMmap(true); // `false` (or just not calling `useMmap()`) uses default file system? - gpio_0->dir((mraa::Dir)DDR); - } - /* - else if(port == gpio_cs_pin) { - gpio_1 = new mraa::Gpio(port,0); - gpio_1->useMmap(true); - gpio_1->dir( (mraa::Dir)DDR); - }*/ -} - -void GPIO::close(int port) -{ - // Prophet: using same theme of working with port numbers as with GPIO::open, - // checking for mraa::Gpio context existence to be sure, that GPIO::begin was called - if (port == gpio_ce_pin) { - if (gpio_0 != NULL) { - delete gpio_0; - } - } - - /* - if(port == gpio_cs_pin) { - if (gpio_1 != NULL) { - delete gpio_1; - } - } - */ -} - -int GPIO::read(int port) -{ - if (port == gpio_ce_pin) { - return gpio_0->read(); - } - /* - else if(port == gpio_cs_pin) { - return gpio_1->read(); - } - */ - return -1; -} - -void GPIO::write(int port, int value) -{ - - if (port == gpio_ce_pin) { - gpio_0->write(value); - } - /* - else if(port == gpio_cs_pin) { - gpio_1->write( value); - } - */ -} diff --git a/RF24/utility/MRAA/gpio.h b/RF24/utility/MRAA/gpio.h deleted file mode 100644 index 4252d3f28baf064f23fec4255648d1e05d7a577b..0000000000000000000000000000000000000000 --- a/RF24/utility/MRAA/gpio.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file spi.h - * @author TMRh20 2015 - * Class declaration for GPIO helper files - */ -#ifndef RF24_UTILITY_MRAA_GPIO_H_ -#define RF24_UTILITY_MRAA_GPIO_H_ - -#include <cstdio> -#include <stdio.h> -#include "mraa.hpp" - -class GPIO -{ - -public: - GPIO(); - - virtual ~GPIO(); - - void begin(uint8_t ce_pin, uint8_t cs_pin); - - void open(int port, int DDR); - - void close(int port); - - int read(int port); - - void write(int port, int value); - -private: - int gpio_ce_pin; /** ce_pin value of the RF24 device **/ - // int gpio_cs_pin; /** cs_pin value of the RF24 device **/ - mraa::Gpio* gpio_0; /** gpio object for ce_pin **/ - // mraa::Gpio* gpio_1; /** gpio object for cs_pin **/ -}; - -#endif // RF24_UTILITY_MRAA_GPIO_H_ diff --git a/RF24/utility/MRAA/includes.h b/RF24/utility/MRAA/includes.h deleted file mode 100644 index d5d6979097fb2b85668c7c192ffa89e1e44ed061..0000000000000000000000000000000000000000 --- a/RF24/utility/MRAA/includes.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef RF24_UTILITY_INCLUDES_H_ -#define RF24_UTILITY_INCLUDES_H_ - -#ifndef MRAA - #define MRAA -#endif - -#include "MRAA/RF24_arch_config.h" - -#endif // RF24_UTILITY_INCLUDES_H_ diff --git a/RF24/utility/MRAA/spi.cpp b/RF24/utility/MRAA/spi.cpp deleted file mode 100644 index 1e5c06345321104605e3eb67e32ba3d2257830f0..0000000000000000000000000000000000000000 --- a/RF24/utility/MRAA/spi.cpp +++ /dev/null @@ -1,59 +0,0 @@ - -#include "spi.h" -#include "mraa.h" - -SPI::SPI() -{ - mspi = NULL; -} - -void SPI::begin(int busNo, uint32_t spi_speed) -{ - // init mraa spi bus, it will handle chip select internally. For CS pin wiring user must check SPI details in hardware manual - mspi = new mraa::Spi(busNo); - - mspi->mode(mraa::SPI_MODE0); - mspi->bitPerWord(8); - - // Prophet: this will try to set 8MHz, however MRAA will reset to max platform speed and syslog a message of it - mspi->frequency(spi_speed); -} - -void SPI::end() -{ - // Prophet: we should check for existence of mspi before deleting it - if (mspi != NULL) { - delete mspi; - } -} - -void SPI::setBitOrder(uint8_t bit_order) -{ - if (mspi != NULL) { - mspi->lsbmode((mraa_boolean_t)bit_order); - } // Prophet: bit_order -} - -void SPI::setDataMode(uint8_t data_mode) -{ - if (mspi != NULL) { - mspi->mode((mraa::Spi_Mode)data_mode); - } -} - -void SPI::setClockDivider(uint32_t spi_speed) -{ - if (mspi != NULL) { - mspi->frequency(spi_speed); - } -} - -void SPI::chipSelect(int csn_pin) -{ -} - -SPI::~SPI() -{ - // Prophet: we should call end here to free used memory and unexport SPI interface - this->end(); -} diff --git a/RF24/utility/MRAA/spi.h b/RF24/utility/MRAA/spi.h deleted file mode 100644 index a27fdeb17a0a97c7492585d66f73fc161a92c60b..0000000000000000000000000000000000000000 --- a/RF24/utility/MRAA/spi.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * TMRh20 2015 - * SPI layer for RF24 - */ - -#ifndef RF24_UTILITY_MRAA_SPI_H_ -#define RF24_UTILITY_MRAA_SPI_H_ -/** - * @file spi.h - * Class declaration for SPI helper files - */ - -#include <stdio.h> -#include "mraa.h" -#include "mraa.hpp" - -#include "../../RF24_config.h" // This is cyclical and should be fixed - -class SPI -{ -public: - SPI(); - - virtual ~SPI(); - - mraa::Spi* mspi; - - inline uint8_t transfer(uint8_t _data); - - inline void transfernb(char* tbuf, char* rbuf, uint32_t len); - - inline void transfern(char* buf, uint32_t len); - - void begin(int busNo, uint32_t spi_speed = RF24_SPI_SPEED); - - void end(); - - void setBitOrder(uint8_t bit_order); - - void setDataMode(uint8_t data_mode); - - void setClockDivider(uint32_t spi_speed); - - void chipSelect(int csn_pin); -}; - -uint8_t SPI::transfer(uint8_t _data) -{ - return mspi->writeByte(_data); -} - -void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len) -{ - mspi->transfer((uint8_t*)tbuf, (uint8_t*)rbuf, len); -} - -void SPI::transfern(char* buf, uint32_t len) -{ - transfernb(buf, buf, len); -} - -#endif // RF24_UTILITY_MRAA_SPI_H_ diff --git a/RF24/utility/RPi/RF24_arch_config.h b/RF24/utility/RPi/RF24_arch_config.h deleted file mode 100644 index abe1ab36fcdaf8605b2628dc0f0faf67384daf60..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/RF24_arch_config.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef RF24_UTILITY_RPI_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_RPI_RF24_ARCH_CONFIG_H_ - -#define RF24_LINUX - -#include <stdint.h> -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <sys/time.h> -#include <stddef.h> - -#include "bcm2835.h" -#include "spi.h" -#include "compatibility.h" - -#define _SPI spi - -#if defined(SPI_HAS_TRANSACTION) - // this gets triggered as /utility/RPi/spi.h defines SPI_HAS_TRANSACTION (unless modified by end-user) - #define RF24_SPI_TRANSACTIONS -#endif - -// GCC a Arduino Missing -#define _BV(x) (1 << (x)) -#define pgm_read_word(p) (*(const unsigned short*)(p)) -#define pgm_read_byte(p) (*(const unsigned char*)(p)) -#define pgm_read_ptr(p) (*(void* const*)(p)) - -//typedef uint16_t prog_uint16_t; -#define PSTR(x) (x) -#define printf_P printf -#define strlen_P strlen -#define PROGMEM -#define PRIPSTR "%s" - -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -#define digitalWrite(pin, value) bcm2835_gpio_write(pin, value) -#define pinMode(pin, value) bcm2835_gpio_fsel(pin, value) -#define OUTPUT BCM2835_GPIO_FSEL_OUTP -#define INPUT BCM2835_GPIO_FSEL_INPT - -#endif // RF24_UTILITY_RPI_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/RPi/bcm2835.c b/RF24/utility/RPi/bcm2835.c deleted file mode 100644 index 557b3aa6340c7082a0ebb91d7827fb7f444c6aa2..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/bcm2835.c +++ /dev/null @@ -1,2031 +0,0 @@ -/* bcm2835.c -// C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi -// http://elinux.org/RPi_Low-level_peripherals -// http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf -// -// Author: Mike McCauley -// Copyright (C) 2011-2013 Mike McCauley -// $Id: bcm2835.c,v 1.28 2020/01/11 05:07:13 mikem Exp mikem $ -*/ -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <sys/types.h> - -#define BCK2835_LIBRARY_BUILD -#include "bcm2835.h" - -/* This define enables a little test program (by default a blinking output on pin RPI_GPIO_PIN_11) -// You can do some safe, non-destructive testing on any platform with: -// gcc bcm2835.c -D BCM2835_TEST -// ./a.out -*/ -/*#define BCM2835_TEST*/ - -/* Uncommenting this define compiles alternative I2C code for the version 1 RPi -// The P1 header I2C pins are connected to SDA0 and SCL0 on V1. -// By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected. -*/ -/* #define I2C_V1*/ - -/* Physical address and size of the peripherals block -// May be overridden on RPi2 -*/ -off_t bcm2835_peripherals_base = BCM2835_PERI_BASE; -size_t bcm2835_peripherals_size = BCM2835_PERI_SIZE; - -/* Virtual memory address of the mapped peripherals block - */ -uint32_t *bcm2835_peripherals = (uint32_t *)MAP_FAILED; - -/* And the register bases within the peripherals block - */ -volatile uint32_t *bcm2835_gpio = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_pwm = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_clk = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_pads = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_spi0 = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_bsc0 = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_bsc1 = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_st = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_aux = (uint32_t *)MAP_FAILED; -volatile uint32_t *bcm2835_spi1 = (uint32_t *)MAP_FAILED; - - - -/* This variable allows us to test on hardware other than RPi. -// It prevents access to the kernel memory, and does not do any peripheral access -// Instead it prints out what it _would_ do if debug were 0 - */ -static uint8_t debug = 0; - -/* RPI 4 has different pullup registers - we need to know if we have that type */ - -static uint8_t pud_type_rpi4 = 0; - -/* RPI 4 has different pullup operation - make backwards compat */ - -static uint8_t pud_compat_setting = BCM2835_GPIO_PUD_OFF; - -/* I2C The time needed to transmit one byte. In microseconds. - */ -static int i2c_byte_wait_us = 0; - -/* SPI bit order. BCM2835 SPI0 only supports MSBFIRST, so we instead - * have a software based bit reversal, based on a contribution by Damiano Benedetti - */ -static uint8_t bcm2835_spi_bit_order = BCM2835_SPI_BIT_ORDER_MSBFIRST; -static uint8_t bcm2835_byte_reverse_table[] = -{ - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; - -static uint8_t bcm2835_correct_order(uint8_t b) -{ - if (bcm2835_spi_bit_order == BCM2835_SPI_BIT_ORDER_LSBFIRST) - return bcm2835_byte_reverse_table[b]; - else - return b; -} - -#ifdef BCM2835_HAVE_LIBCAP -#include <sys/capability.h> -static int bcm2835_has_capability(cap_value_t capability) -{ - int ok = 0; - cap_t cap = cap_get_proc(); - if (cap) - { - cap_flag_value_t value; - if (cap_get_flag(cap,capability,CAP_EFFECTIVE,&value) == 0 && value == CAP_SET) - ok = 1; - cap_free(cap); - } - return ok; -} -#endif - -/* -// Low level register access functions -*/ - -/* Function to return the pointers to the hardware register bases */ -uint32_t* bcm2835_regbase(uint8_t regbase) -{ - switch (regbase) - { - case BCM2835_REGBASE_ST: - return (uint32_t *)bcm2835_st; - case BCM2835_REGBASE_GPIO: - return (uint32_t *)bcm2835_gpio; - case BCM2835_REGBASE_PWM: - return (uint32_t *)bcm2835_pwm; - case BCM2835_REGBASE_CLK: - return (uint32_t *)bcm2835_clk; - case BCM2835_REGBASE_PADS: - return (uint32_t *)bcm2835_pads; - case BCM2835_REGBASE_SPI0: - return (uint32_t *)bcm2835_spi0; - case BCM2835_REGBASE_BSC0: - return (uint32_t *)bcm2835_bsc0; - case BCM2835_REGBASE_BSC1: - return (uint32_t *)bcm2835_st; - case BCM2835_REGBASE_AUX: - return (uint32_t *)bcm2835_aux; - case BCM2835_REGBASE_SPI1: - return (uint32_t *)bcm2835_spi1; - - } - return (uint32_t *)MAP_FAILED; -} - -void bcm2835_set_debug(uint8_t d) -{ - debug = d; -} - -unsigned int bcm2835_version(void) -{ - return BCM2835_VERSION; -} - -/* Read with memory barriers from peripheral - * - */ -uint32_t bcm2835_peri_read(volatile uint32_t* paddr) -{ - uint32_t ret; - if (debug) - { - printf("bcm2835_peri_read paddr %p\n", (void *) paddr); - return 0; - } - else - { - __sync_synchronize(); - ret = *paddr; - __sync_synchronize(); - return ret; - } -} - -/* read from peripheral without the read barrier - * This can only be used if more reads to THE SAME peripheral - * will follow. The sequence must terminate with memory barrier - * before any read or write to another peripheral can occur. - * The MB can be explicit, or one of the barrier read/write calls. - */ -uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr) -{ - if (debug) - { - printf("bcm2835_peri_read_nb paddr %p\n", paddr); - return 0; - } - else - { - return *paddr; - } -} - -/* Write with memory barriers to peripheral - */ - -void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value) -{ - if (debug) - { - printf("bcm2835_peri_write paddr %p, value %08X\n", paddr, value); - } - else - { - __sync_synchronize(); - *paddr = value; - __sync_synchronize(); - } -} - -/* write to peripheral without the write barrier */ -void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value) -{ - if (debug) - { - printf("bcm2835_peri_write_nb paddr %p, value %08X\n", - paddr, value); - } - else - { - *paddr = value; - } -} - -/* Set/clear only the bits in value covered by the mask - * This is not atomic - can be interrupted. - */ -void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask) -{ - uint32_t v = bcm2835_peri_read(paddr); - v = (v & ~mask) | (value & mask); - bcm2835_peri_write(paddr, v); -} - -/* -// Low level convenience functions -*/ - -/* Function select -// pin is a BCM2835 GPIO pin number NOT RPi pin number -// There are 6 control registers, each control the functions of a block -// of 10 pins. -// Each control register has 10 sets of 3 bits per GPIO pin: -// -// 000 = GPIO Pin X is an input -// 001 = GPIO Pin X is an output -// 100 = GPIO Pin X takes alternate function 0 -// 101 = GPIO Pin X takes alternate function 1 -// 110 = GPIO Pin X takes alternate function 2 -// 111 = GPIO Pin X takes alternate function 3 -// 011 = GPIO Pin X takes alternate function 4 -// 010 = GPIO Pin X takes alternate function 5 -// -// So the 3 bits for port X are: -// X / 10 + ((X % 10) * 3) -*/ -void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode) -{ - /* Function selects are 10 pins per 32 bit word, 3 bits per pin */ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFSEL0/4 + (pin/10); - uint8_t shift = (pin % 10) * 3; - uint32_t mask = BCM2835_GPIO_FSEL_MASK << shift; - uint32_t value = mode << shift; - bcm2835_peri_set_bits(paddr, value, mask); -} - -/* Set output pin */ -void bcm2835_gpio_set(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPSET0/4 + pin/32; - uint8_t shift = pin % 32; - bcm2835_peri_write(paddr, 1 << shift); -} - -/* Clear output pin */ -void bcm2835_gpio_clr(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPCLR0/4 + pin/32; - uint8_t shift = pin % 32; - bcm2835_peri_write(paddr, 1 << shift); -} - -/* Set all output pins in the mask */ -void bcm2835_gpio_set_multi(uint32_t mask) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPSET0/4; - bcm2835_peri_write(paddr, mask); -} - -/* Clear all output pins in the mask */ -void bcm2835_gpio_clr_multi(uint32_t mask) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPCLR0/4; - bcm2835_peri_write(paddr, mask); -} - -/* Read input pin */ -uint8_t bcm2835_gpio_lev(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEV0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = bcm2835_peri_read(paddr); - return (value & (1 << shift)) ? HIGH : LOW; -} - -/* See if an event detection bit is set -// Sigh cant support interrupts yet -*/ -uint8_t bcm2835_gpio_eds(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = bcm2835_peri_read(paddr); - return (value & (1 << shift)) ? HIGH : LOW; -} - -uint32_t bcm2835_gpio_eds_multi(uint32_t mask) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4; - uint32_t value = bcm2835_peri_read(paddr); - return (value & mask); -} - -/* Write a 1 to clear the bit in EDS */ -void bcm2835_gpio_set_eds(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_write(paddr, value); -} - -void bcm2835_gpio_set_eds_multi(uint32_t mask) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4; - bcm2835_peri_write(paddr, mask); -} - -/* Rising edge detect enable */ -void bcm2835_gpio_ren(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPREN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, value, value); -} -void bcm2835_gpio_clr_ren(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPREN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, 0, value); -} - -/* Falling edge detect enable */ -void bcm2835_gpio_fen(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFEN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, value, value); -} -void bcm2835_gpio_clr_fen(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFEN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, 0, value); -} - -/* High detect enable */ -void bcm2835_gpio_hen(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPHEN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, value, value); -} -void bcm2835_gpio_clr_hen(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPHEN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, 0, value); -} - -/* Low detect enable */ -void bcm2835_gpio_len(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, value, value); -} -void bcm2835_gpio_clr_len(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, 0, value); -} - -/* Async rising edge detect enable */ -void bcm2835_gpio_aren(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAREN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, value, value); -} -void bcm2835_gpio_clr_aren(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAREN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, 0, value); -} - -/* Async falling edge detect enable */ -void bcm2835_gpio_afen(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAFEN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, value, value); -} -void bcm2835_gpio_clr_afen(uint8_t pin) -{ - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAFEN0/4 + pin/32; - uint8_t shift = pin % 32; - uint32_t value = 1 << shift; - bcm2835_peri_set_bits(paddr, 0, value); -} - -/* Set pullup/down */ -void bcm2835_gpio_pud(uint8_t pud) -{ - if( pud_type_rpi4 ) - { - pud_compat_setting = pud; - } - else { - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUD/4; - bcm2835_peri_write(paddr, pud); -} -} - -/* Pullup/down clock -// Clocks the value of pud into the GPIO pin -*/ -void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on) -{ - if( pud_type_rpi4 ) - { - if( on ) - bcm2835_gpio_set_pud( pin, pud_compat_setting); - } - else - { - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUDCLK0/4 + pin/32; - uint8_t shift = pin % 32; - bcm2835_peri_write(paddr, (on ? 1 : 0) << shift); -} -} - -/* Read GPIO pad behaviour for groups of GPIOs */ -uint32_t bcm2835_gpio_pad(uint8_t group) -{ - if (bcm2835_pads == MAP_FAILED){ - return 0; - } - - volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group; - return bcm2835_peri_read(paddr); -} - -/* Set GPIO pad behaviour for groups of GPIOs -// powerup value for all pads is -// BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA -*/ -void bcm2835_gpio_set_pad(uint8_t group, uint32_t control) -{ - if (bcm2835_pads == MAP_FAILED){ - return; - } - - volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group; - bcm2835_peri_write(paddr, control | BCM2835_PAD_PASSWRD); -} - -/* Some convenient arduino-like functions -// milliseconds -*/ -void bcm2835_delay(unsigned int millis) -{ - struct timespec sleeper; - - sleeper.tv_sec = (time_t)(millis / 1000); - sleeper.tv_nsec = (long)(millis % 1000) * 1000000; - nanosleep(&sleeper, NULL); -} - -/* microseconds */ -void bcm2835_delayMicroseconds(uint64_t micros) -{ - struct timespec t1; - uint64_t start; - - if (debug) - { - /* Cant access sytem timers in debug mode */ - printf("bcm2835_delayMicroseconds %lld\n", (long long int) micros); - return; - } - - /* Calling nanosleep() takes at least 100-200 us, so use it for - // long waits and use a busy wait on the System Timer for the rest. - */ - start = bcm2835_st_read(); - - /* Not allowed to access timer registers (result is not as precise)*/ - if (start==0) - { - t1.tv_sec = 0; - t1.tv_nsec = 1000 * (long)(micros); - nanosleep(&t1, NULL); - return; - } - - if (micros > 450) - { - t1.tv_sec = 0; - t1.tv_nsec = 1000 * (long)(micros - 200); - nanosleep(&t1, NULL); - } - - bcm2835_st_delay(start, micros); -} - -/* -// Higher level convenience functions -*/ - -/* Set the state of an output */ -void bcm2835_gpio_write(uint8_t pin, uint8_t on) -{ - if (on) - bcm2835_gpio_set(pin); - else - bcm2835_gpio_clr(pin); -} - -/* Set the state of a all 32 outputs in the mask to on or off */ -void bcm2835_gpio_write_multi(uint32_t mask, uint8_t on) -{ - if (on) - bcm2835_gpio_set_multi(mask); - else - bcm2835_gpio_clr_multi(mask); -} - -/* Set the state of a all 32 outputs in the mask to the values in value */ -void bcm2835_gpio_write_mask(uint32_t value, uint32_t mask) -{ - bcm2835_gpio_set_multi(value & mask); - bcm2835_gpio_clr_multi((~value) & mask); -} - -/* Set the pullup/down resistor for a pin -// -// The GPIO Pull-up/down Clock Registers control the actuation of internal pull-downs on -// the respective GPIO pins. These registers must be used in conjunction with the GPPUD -// register to effect GPIO Pull-up/down changes. The following sequence of events is -// required: -// 1. Write to GPPUD to set the required control signal (i.e. Pull-up or Pull-Down or neither -// to remove the current Pull-up/down) -// 2. Wait 150 cycles ? this provides the required set-up time for the control signal -// 3. Write to GPPUDCLK0/1 to clock the control signal into the GPIO pads you wish to -// modify ? NOTE only the pads which receive a clock will be modified, all others will -// retain their previous state. -// 4. Wait 150 cycles ? this provides the required hold time for the control signal -// 5. Write to GPPUD to remove the control signal -// 6. Write to GPPUDCLK0/1 to remove the clock -// -// RPi has P1-03 and P1-05 with 1k8 pullup resistor -// -// RPI 4 uses a different PUD method - no clock - -*/ -void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud) -{ - if( pud_type_rpi4 ) - { - int shiftbits = (pin & 0xf) << 1; - uint32_t bits; - uint32_t pull; - - switch (pud) - { - case BCM2835_GPIO_PUD_OFF: pull = 0; break; - case BCM2835_GPIO_PUD_UP: pull = 1; break; - case BCM2835_GPIO_PUD_DOWN: pull = 2; break; - default: return; - } - - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUPPDN0/4 + (pin >> 4); - - bits = bcm2835_peri_read_nb( paddr ); - bits &= ~(3 << shiftbits); - bits |= (pull << shiftbits); - - bcm2835_peri_write_nb( paddr, bits ); - - } else - { - bcm2835_gpio_pud(pud); - delayMicroseconds(10); - bcm2835_gpio_pudclk(pin, 1); - delayMicroseconds(10); - bcm2835_gpio_pud(BCM2835_GPIO_PUD_OFF); - bcm2835_gpio_pudclk(pin, 0); -} - -} - - -uint8_t bcm2835_gpio_get_pud(uint8_t pin) -{ - uint8_t ret = BCM2835_GPIO_PUD_ERROR; - - if( pud_type_rpi4 ) - { - uint32_t bits; - volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUPPDN0/4 + (pin >> 4); - bits = (bcm2835_peri_read_nb( paddr ) >> ((pin & 0xf)<<1)) & 0x3; - - switch (bits) - { - case 0: ret = BCM2835_GPIO_PUD_OFF; break; - case 1: ret = BCM2835_GPIO_PUD_UP; break; - case 2: ret = BCM2835_GPIO_PUD_DOWN; break; - default: ret = BCM2835_GPIO_PUD_ERROR; - } - } - - return ret; -} - -static void bcm2835_aux_spi_reset(void) - { - volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4; - volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; - - bcm2835_peri_write(cntl1, 0); - bcm2835_peri_write(cntl0, BCM2835_AUX_SPI_CNTL0_CLEARFIFO); -} - -int bcm2835_spi_begin(void) -{ - volatile uint32_t* paddr; - - if (bcm2835_spi0 == MAP_FAILED) - return 0; /* bcm2835_init() failed, or not root */ - - /* Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them */ - bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); /* CE1 */ - bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); /* CE0 */ - bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_ALT0); /* MISO */ - bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_ALT0); /* MOSI */ - bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_ALT0); /* CLK */ - - /* Set the SPI CS register to the some sensible defaults */ - paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; - bcm2835_peri_write(paddr, 0); /* All 0s */ - - /* Clear TX and RX fifos */ - bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR); - - return 1; // OK -} - -void bcm2835_spi_end(void) -{ - /* Set all the SPI0 pins back to input */ - bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_INPT); /* CE1 */ - bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_INPT); /* CE0 */ - bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_INPT); /* MISO */ - bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_INPT); /* MOSI */ - bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_INPT); /* CLK */ -} - -void bcm2835_spi_setBitOrder(uint8_t order) -{ - bcm2835_spi_bit_order = order; -} - -/* defaults to 0, which means a divider of 65536. -// The divisor must be a power of 2. Odd numbers -// rounded down. The maximum SPI clock rate is -// of the APB clock -*/ -void bcm2835_spi_setClockDivider(uint16_t divider) -{ - volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CLK/4; - bcm2835_peri_write(paddr, divider); -} - -void bcm2835_spi_set_speed_hz(uint32_t speed_hz) -{ - uint16_t divider = (uint16_t) ((uint32_t) BCM2835_CORE_CLK_HZ / speed_hz); - divider &= 0xFFFE; - bcm2835_spi_setClockDivider(divider); -} - -void bcm2835_spi_setDataMode(uint8_t mode) -{ - volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; - /* Mask in the CPO and CPHA bits of CS */ - bcm2835_peri_set_bits(paddr, mode << 2, BCM2835_SPI0_CS_CPOL | BCM2835_SPI0_CS_CPHA); -} - -/* Writes (and reads) a single byte to SPI */ -uint8_t bcm2835_spi_transfer(uint8_t value) -{ - volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; - volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; - uint32_t ret; - - /* This is Polled transfer as per section 10.6.1 - // BUG ALERT: what happens if we get interupted in this section, and someone else - // accesses a different peripheral? - // Clear TX and RX fifos - */ - bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); - - /* Set TA = 1 */ - bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); - - /* Maybe wait for TXD */ - while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD)) - ; - - /* Write to FIFO, no barrier */ - bcm2835_peri_write_nb(fifo, bcm2835_correct_order(value)); - - /* Wait for DONE to be set */ - while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) - ; - - /* Read any byte that was sent back by the slave while we sere sending to it */ - ret = bcm2835_correct_order(bcm2835_peri_read_nb(fifo)); - - /* Set TA = 0, and also set the barrier */ - bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); - - return ret; -} - -/* Writes (and reads) an number of bytes to SPI */ -void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len) -{ - volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; - volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; - uint32_t TXCnt=0; - uint32_t RXCnt=0; - - /* This is Polled transfer as per section 10.6.1 - // BUG ALERT: what happens if we get interupted in this section, and someone else - // accesses a different peripheral? - */ - - /* Clear TX and RX fifos */ - bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); - - /* Set TA = 1 */ - bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); - - /* Use the FIFO's to reduce the interbyte times */ - while((TXCnt < len)||(RXCnt < len)) - { - /* TX fifo not full, so add some more bytes */ - while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))&&(TXCnt < len )) - { - bcm2835_peri_write_nb(fifo, bcm2835_correct_order(tbuf[TXCnt])); - TXCnt++; - } - /* Rx fifo not empty, so get the next received bytes */ - while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD))&&( RXCnt < len )) - { - rbuf[RXCnt] = bcm2835_correct_order(bcm2835_peri_read_nb(fifo)); - RXCnt++; - } - } - /* Wait for DONE to be set */ - while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) - ; - - /* Set TA = 0, and also set the barrier */ - bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); -} - -/* Writes an number of bytes to SPI */ -void bcm2835_spi_writenb(const char* tbuf, uint32_t len) -{ - volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; - volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; - uint32_t i; - - /* This is Polled transfer as per section 10.6.1 - // BUG ALERT: what happens if we get interupted in this section, and someone else - // accesses a different peripheral? - // Answer: an ISR is required to issue the required memory barriers. - */ - - /* Clear TX and RX fifos */ - bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); - - /* Set TA = 1 */ - bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); - - for (i = 0; i < len; i++) - { - /* Maybe wait for TXD */ - while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD)) - ; - - /* Write to FIFO, no barrier */ - bcm2835_peri_write_nb(fifo, bcm2835_correct_order(tbuf[i])); - - /* Read from FIFO to prevent stalling */ - while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD) - (void) bcm2835_peri_read_nb(fifo); - } - - /* Wait for DONE to be set */ - while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) { - while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD) - (void) bcm2835_peri_read_nb(fifo); - }; - - /* Set TA = 0, and also set the barrier */ - bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); -} - -/* Writes (and reads) an number of bytes to SPI -// Read bytes are copied over onto the transmit buffer -*/ -void bcm2835_spi_transfern(char* buf, uint32_t len) -{ - bcm2835_spi_transfernb(buf, buf, len); -} - -void bcm2835_spi_chipSelect(uint8_t cs) -{ - volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; - /* Mask in the CS bits of CS */ - bcm2835_peri_set_bits(paddr, cs, BCM2835_SPI0_CS_CS); -} - -void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active) -{ - volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; - uint8_t shift = 21 + cs; - /* Mask in the appropriate CSPOLn bit */ - bcm2835_peri_set_bits(paddr, active << shift, 1 << shift); -} - -void bcm2835_spi_write(uint16_t data) -{ -#if 0 - char buf[2]; - - buf[0] = data >> 8; - buf[1] = data & 0xFF; - - bcm2835_spi_transfern(buf, 2); -#else - volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; - volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; - - /* Clear TX and RX fifos */ - bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); - - /* Set TA = 1 */ - bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); - - /* Maybe wait for TXD */ - while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD)) - ; - - /* Write to FIFO */ - bcm2835_peri_write_nb(fifo, (uint32_t) data >> 8); - bcm2835_peri_write_nb(fifo, data & 0xFF); - - - /* Wait for DONE to be set */ - while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) - ; - - /* Set TA = 0, and also set the barrier */ - bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); -#endif -} - -int bcm2835_aux_spi_begin(void) -{ - volatile uint32_t* enable = bcm2835_aux + BCM2835_AUX_ENABLE/4; - volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4; - volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; - - if (bcm2835_spi1 == MAP_FAILED) - return 0; /* bcm2835_init() failed, or not root */ - - /* Set the SPI pins to the Alt 4 function to enable SPI1 access on them */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_36, BCM2835_GPIO_FSEL_ALT4); /* SPI1_CE2_N */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_35, BCM2835_GPIO_FSEL_ALT4); /* SPI1_MISO */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_38, BCM2835_GPIO_FSEL_ALT4); /* SPI1_MOSI */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_40, BCM2835_GPIO_FSEL_ALT4); /* SPI1_SCLK */ - - bcm2835_aux_spi_setClockDivider(bcm2835_aux_spi_CalcClockDivider(1000000)); // Default 1MHz SPI - - bcm2835_peri_write(enable, BCM2835_AUX_ENABLE_SPI0); - bcm2835_peri_write(cntl1, 0); - bcm2835_peri_write(cntl0, BCM2835_AUX_SPI_CNTL0_CLEARFIFO); - - return 1; /* OK */ -} - -void bcm2835_aux_spi_end(void) -{ - /* Set all the SPI1 pins back to input */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_36, BCM2835_GPIO_FSEL_INPT); /* SPI1_CE2_N */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_35, BCM2835_GPIO_FSEL_INPT); /* SPI1_MISO */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_38, BCM2835_GPIO_FSEL_INPT); /* SPI1_MOSI */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_40, BCM2835_GPIO_FSEL_INPT); /* SPI1_SCLK */ -} - -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) - -uint16_t bcm2835_aux_spi_CalcClockDivider(uint32_t speed_hz) -{ - uint16_t divider; - - if (speed_hz < (uint32_t) BCM2835_AUX_SPI_CLOCK_MIN) { - speed_hz = (uint32_t) BCM2835_AUX_SPI_CLOCK_MIN; - } else if (speed_hz > (uint32_t) BCM2835_AUX_SPI_CLOCK_MAX) { - speed_hz = (uint32_t) BCM2835_AUX_SPI_CLOCK_MAX; - } - - divider = (uint16_t) DIV_ROUND_UP(BCM2835_CORE_CLK_HZ, 2 * speed_hz) - 1; - - if (divider > (uint16_t) BCM2835_AUX_SPI_CNTL0_SPEED_MAX) { - return (uint16_t) BCM2835_AUX_SPI_CNTL0_SPEED_MAX; - } - - return divider; -} - -static uint32_t spi1_speed; - -void bcm2835_aux_spi_setClockDivider(uint16_t divider) -{ - spi1_speed = (uint32_t) divider; -} - -void bcm2835_aux_spi_write(uint16_t data) -{ - volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4; - volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; - volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4; - volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4; - - uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); - _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; - _cntl0 |= 16; // Shift length - - bcm2835_peri_write(cntl0, _cntl0); - bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN); - - while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL) - ; - - bcm2835_peri_write(io, (uint32_t) data << 16); -} - -void bcm2835_aux_spi_writenb(const char *tbuf, uint32_t len) { - volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4; - volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; - volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4; - volatile uint32_t* txhold = bcm2835_spi1 + BCM2835_AUX_SPI_TXHOLD/4; - volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4; - - char *tx = (char *) tbuf; - uint32_t tx_len = len; - uint32_t count; - uint32_t data; - uint32_t i; - uint8_t byte; - - uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); - _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_VAR_WIDTH; - - bcm2835_peri_write(cntl0, _cntl0); - bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN); - - while (tx_len > 0) { - - while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL) - ; - - count = MIN(tx_len, 3); - data = 0; - - for (i = 0; i < count; i++) { - byte = (tx != NULL) ? (uint8_t) *tx++ : (uint8_t) 0; - data |= byte << (8 * (2 - i)); - } - - data |= (count * 8) << 24; - tx_len -= count; - - if (tx_len != 0) { - bcm2835_peri_write(txhold, data); - } else { - bcm2835_peri_write(io, data); - } - - while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY) - ; - - (void) bcm2835_peri_read(io); - } -} - -void bcm2835_aux_spi_transfernb(const char *tbuf, char *rbuf, uint32_t len) { - volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4; - volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; - volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4; - volatile uint32_t* txhold = bcm2835_spi1 + BCM2835_AUX_SPI_TXHOLD/4; - volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4; - - char *tx = (char *)tbuf; - char *rx = (char *)rbuf; - uint32_t tx_len = len; - uint32_t rx_len = len; - uint32_t count; - uint32_t data; - uint32_t i; - uint8_t byte; - - uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); - _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_VAR_WIDTH; - - bcm2835_peri_write(cntl0, _cntl0); - bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN); - - while ((tx_len > 0) || (rx_len > 0)) { - - while (!(bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL) && (tx_len > 0)) { - count = MIN(tx_len, 3); - data = 0; - - for (i = 0; i < count; i++) { - byte = (tx != NULL) ? (uint8_t) *tx++ : (uint8_t) 0; - data |= byte << (8 * (2 - i)); - } - - data |= (count * 8) << 24; - tx_len -= count; - - if (tx_len != 0) { - bcm2835_peri_write(txhold, data); - } else { - bcm2835_peri_write(io, data); - } - - } - - while (!(bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_RX_EMPTY) && (rx_len > 0)) { - count = MIN(rx_len, 3); - data = bcm2835_peri_read(io); - - if (rbuf != NULL) { - switch (count) { - case 3: - *rx++ = (char)((data >> 16) & 0xFF); - /*@fallthrough@*/ - /* no break */ - case 2: - *rx++ = (char)((data >> 8) & 0xFF); - /*@fallthrough@*/ - /* no break */ - case 1: - *rx++ = (char)((data >> 0) & 0xFF); - } - } - - rx_len -= count; - } - - while (!(bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY) && (rx_len > 0)) { - count = MIN(rx_len, 3); - data = bcm2835_peri_read(io); - - if (rbuf != NULL) { - switch (count) { - case 3: - *rx++ = (char)((data >> 16) & 0xFF); - /*@fallthrough@*/ - /* no break */ - case 2: - *rx++ = (char)((data >> 8) & 0xFF); - /*@fallthrough@*/ - /* no break */ - case 1: - *rx++ = (char)((data >> 0) & 0xFF); - } - } - - rx_len -= count; - } - } -} - -void bcm2835_aux_spi_transfern(char *buf, uint32_t len) { - bcm2835_aux_spi_transfernb(buf, buf, len); -} - -/* Writes (and reads) a single byte to AUX SPI */ -uint8_t bcm2835_aux_spi_transfer(uint8_t value) -{ - volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4; - volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4; - volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4; - volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4; - - uint32_t data; - - uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT); - _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT; - _cntl0 |= BCM2835_AUX_SPI_CNTL0_CPHA_IN; - _cntl0 |= 8; // Shift length. - - uint32_t _cntl1 = BCM2835_AUX_SPI_CNTL1_MSBF_IN; - - bcm2835_peri_write(cntl1, _cntl1); - bcm2835_peri_write(cntl0, _cntl0); - - bcm2835_peri_write(io, (uint32_t) bcm2835_correct_order(value) << 24); - - while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY) - ; - - data = bcm2835_correct_order(bcm2835_peri_read(io) & 0xff); - - bcm2835_aux_spi_reset(); - - return data; -} - - -int bcm2835_i2c_begin(void) -{ - uint16_t cdiv; - - if ( bcm2835_bsc0 == MAP_FAILED - || bcm2835_bsc1 == MAP_FAILED) - return 0; /* bcm2835_init() failed, or not root */ - -#ifdef I2C_V1 - volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_DIV/4; - /* Set the I2C/BSC0 pins to the Alt 0 function to enable I2C access on them */ - bcm2835_gpio_fsel(RPI_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); /* SDA */ - bcm2835_gpio_fsel(RPI_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); /* SCL */ -#else - volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4; - /* Set the I2C/BSC1 pins to the Alt 0 function to enable I2C access on them */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); /* SDA */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); /* SCL */ -#endif - - /* Read the clock divider register */ - cdiv = bcm2835_peri_read(paddr); - /* Calculate time for transmitting one byte - // 1000000 = micros seconds in a second - // 9 = Clocks per byte : 8 bits + ACK - */ - i2c_byte_wait_us = ((float)cdiv / BCM2835_CORE_CLK_HZ) * 1000000 * 9; - - return 1; -} - -void bcm2835_i2c_end(void) -{ -#ifdef I2C_V1 - /* Set all the I2C/BSC0 pins back to input */ - bcm2835_gpio_fsel(RPI_GPIO_P1_03, BCM2835_GPIO_FSEL_INPT); /* SDA */ - bcm2835_gpio_fsel(RPI_GPIO_P1_05, BCM2835_GPIO_FSEL_INPT); /* SCL */ -#else - /* Set all the I2C/BSC1 pins back to input */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_INPT); /* SDA */ - bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_INPT); /* SCL */ -#endif -} - -void bcm2835_i2c_setSlaveAddress(uint8_t addr) -{ - /* Set I2C Device Address */ -#ifdef I2C_V1 - volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_A/4; -#else - volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_A/4; -#endif - bcm2835_peri_write(paddr, addr); -} - -/* defaults to 0x5dc, should result in a 166.666 kHz I2C clock frequency. -// The divisor must be a power of 2. Odd numbers -// rounded down. -*/ -void bcm2835_i2c_setClockDivider(uint16_t divider) -{ -#ifdef I2C_V1 - volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_DIV/4; -#else - volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4; -#endif - bcm2835_peri_write(paddr, divider); - /* Calculate time for transmitting one byte - // 1000000 = micros seconds in a second - // 9 = Clocks per byte : 8 bits + ACK - */ - i2c_byte_wait_us = ((float)divider / BCM2835_CORE_CLK_HZ) * 1000000 * 9; -} - -/* set I2C clock divider by means of a baudrate number */ -void bcm2835_i2c_set_baudrate(uint32_t baudrate) -{ - uint32_t divider; - /* use 0xFFFE mask to limit a max value and round down any odd number */ - divider = (BCM2835_CORE_CLK_HZ / baudrate) & 0xFFFE; - bcm2835_i2c_setClockDivider( (uint16_t)divider ); -} - -/* Writes an number of bytes to I2C */ -uint8_t bcm2835_i2c_write(const char * buf, uint32_t len) -{ -#ifdef I2C_V1 - volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4; - volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4; - volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4; - volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4; -#else - volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4; - volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4; - volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4; - volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4; -#endif - - uint32_t remaining = len; - uint32_t i = 0; - uint8_t reason = BCM2835_I2C_REASON_OK; - - /* Clear FIFO */ - bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 ); - /* Clear Status */ - bcm2835_peri_write(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); - /* Set Data Length */ - bcm2835_peri_write(dlen, len); - /* pre populate FIFO with max buffer */ - while( remaining && ( i < BCM2835_BSC_FIFO_SIZE ) ) - { - bcm2835_peri_write_nb(fifo, buf[i]); - i++; - remaining--; - } - - /* Enable device and start transfer */ - bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST); - - /* Transfer is over when BCM2835_BSC_S_DONE */ - while(!(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE )) - { - while ( remaining && (bcm2835_peri_read(status) & BCM2835_BSC_S_TXD )) - { - /* Write to FIFO */ - bcm2835_peri_write(fifo, buf[i]); - i++; - remaining--; - } - } - - /* Received a NACK */ - if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR) - { - reason = BCM2835_I2C_REASON_ERROR_NACK; - } - - /* Received Clock Stretch Timeout */ - else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT) - { - reason = BCM2835_I2C_REASON_ERROR_CLKT; - } - - /* Not all data is sent */ - else if (remaining) - { - reason = BCM2835_I2C_REASON_ERROR_DATA; - } - - bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); - - return reason; -} - -/* Read an number of bytes from I2C */ -uint8_t bcm2835_i2c_read(char* buf, uint32_t len) -{ -#ifdef I2C_V1 - volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4; - volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4; - volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4; - volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4; -#else - volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4; - volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4; - volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4; - volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4; -#endif - - uint32_t remaining = len; - uint32_t i = 0; - uint8_t reason = BCM2835_I2C_REASON_OK; - - /* Clear FIFO */ - bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 ); - /* Clear Status */ - bcm2835_peri_write_nb(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); - /* Set Data Length */ - bcm2835_peri_write_nb(dlen, len); - /* Start read */ - bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ); - - /* wait for transfer to complete */ - while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE)) - { - /* we must empty the FIFO as it is populated and not use any delay */ - while (remaining && bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD) - { - /* Read from FIFO, no barrier */ - buf[i] = bcm2835_peri_read_nb(fifo); - i++; - remaining--; - } - } - - /* transfer has finished - grab any remaining stuff in FIFO */ - while (remaining && (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD)) - { - /* Read from FIFO, no barrier */ - buf[i] = bcm2835_peri_read_nb(fifo); - i++; - remaining--; - } - - /* Received a NACK */ - if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR) - { - reason = BCM2835_I2C_REASON_ERROR_NACK; - } - - /* Received Clock Stretch Timeout */ - else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT) - { - reason = BCM2835_I2C_REASON_ERROR_CLKT; - } - - /* Not all data is received */ - else if (remaining) - { - reason = BCM2835_I2C_REASON_ERROR_DATA; - } - - bcm2835_peri_set_bits(status, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); - - return reason; -} - -/* Read an number of bytes from I2C sending a repeated start after writing -// the required register. Only works if your device supports this mode -*/ -uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len) -{ -#ifdef I2C_V1 - volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4; - volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4; - volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4; - volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4; -#else - volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4; - volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4; - volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4; - volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4; -#endif - uint32_t remaining = len; - uint32_t i = 0; - uint8_t reason = BCM2835_I2C_REASON_OK; - - /* Clear FIFO */ - bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 ); - /* Clear Status */ - bcm2835_peri_write(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); - /* Set Data Length */ - bcm2835_peri_write(dlen, 1); - /* Enable device and start transfer */ - bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN); - bcm2835_peri_write(fifo, regaddr[0]); - bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST); - - /* poll for transfer has started */ - while ( !( bcm2835_peri_read(status) & BCM2835_BSC_S_TA ) ) - { - /* Linux may cause us to miss entire transfer stage */ - if(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE) - break; - } - - /* Send a repeated start with read bit set in address */ - bcm2835_peri_write(dlen, len); - bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ ); - - /* Wait for write to complete and first byte back. */ - bcm2835_delayMicroseconds(i2c_byte_wait_us * 3); - - /* wait for transfer to complete */ - while (!(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE)) - { - /* we must empty the FIFO as it is populated and not use any delay */ - while (remaining && bcm2835_peri_read(status) & BCM2835_BSC_S_RXD) - { - /* Read from FIFO */ - buf[i] = bcm2835_peri_read(fifo); - i++; - remaining--; - } - } - - /* transfer has finished - grab any remaining stuff in FIFO */ - while (remaining && (bcm2835_peri_read(status) & BCM2835_BSC_S_RXD)) - { - /* Read from FIFO */ - buf[i] = bcm2835_peri_read(fifo); - i++; - remaining--; - } - - /* Received a NACK */ - if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR) - { - reason = BCM2835_I2C_REASON_ERROR_NACK; - } - - /* Received Clock Stretch Timeout */ - else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT) - { - reason = BCM2835_I2C_REASON_ERROR_CLKT; - } - - /* Not all data is sent */ - else if (remaining) - { - reason = BCM2835_I2C_REASON_ERROR_DATA; - } - - bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); - - return reason; -} - -/* Sending an arbitrary number of bytes before issuing a repeated start -// (with no prior stop) and reading a response. Some devices require this behavior. -*/ -uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint32_t buf_len) -{ -#ifdef I2C_V1 - volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4; - volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4; - volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4; - volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4; -#else - volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4; - volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4; - volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4; - volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4; -#endif - - uint32_t remaining = cmds_len; - uint32_t i = 0; - uint8_t reason = BCM2835_I2C_REASON_OK; - - /* Clear FIFO */ - bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 ); - - /* Clear Status */ - bcm2835_peri_write(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); - - /* Set Data Length */ - bcm2835_peri_write(dlen, cmds_len); - - /* pre populate FIFO with max buffer */ - while( remaining && ( i < BCM2835_BSC_FIFO_SIZE ) ) - { - bcm2835_peri_write_nb(fifo, cmds[i]); - i++; - remaining--; - } - - /* Enable device and start transfer */ - bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST); - - /* poll for transfer has started (way to do repeated start, from BCM2835 datasheet) */ - while ( !( bcm2835_peri_read(status) & BCM2835_BSC_S_TA ) ) - { - /* Linux may cause us to miss entire transfer stage */ - if(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE) - break; - } - - remaining = buf_len; - i = 0; - - /* Send a repeated start with read bit set in address */ - bcm2835_peri_write(dlen, buf_len); - bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ ); - - /* Wait for write to complete and first byte back. */ - bcm2835_delayMicroseconds(i2c_byte_wait_us * (cmds_len + 1)); - - /* wait for transfer to complete */ - while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE)) - { - /* we must empty the FIFO as it is populated and not use any delay */ - while (remaining && bcm2835_peri_read(status) & BCM2835_BSC_S_RXD) - { - /* Read from FIFO, no barrier */ - buf[i] = bcm2835_peri_read_nb(fifo); - i++; - remaining--; - } - } - - /* transfer has finished - grab any remaining stuff in FIFO */ - while (remaining && (bcm2835_peri_read(status) & BCM2835_BSC_S_RXD)) - { - /* Read from FIFO */ - buf[i] = bcm2835_peri_read(fifo); - i++; - remaining--; - } - - /* Received a NACK */ - if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR) - { - reason = BCM2835_I2C_REASON_ERROR_NACK; - } - - /* Received Clock Stretch Timeout */ - else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT) - { - reason = BCM2835_I2C_REASON_ERROR_CLKT; - } - - /* Not all data is sent */ - else if (remaining) - { - reason = BCM2835_I2C_REASON_ERROR_DATA; - } - - bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); - - return reason; -} - -/* Read the System Timer Counter (64-bits) */ -uint64_t bcm2835_st_read(void) -{ - volatile uint32_t* paddr; - uint32_t hi, lo; - uint64_t st; - - if (bcm2835_st==MAP_FAILED) - return 0; - - paddr = bcm2835_st + BCM2835_ST_CHI/4; - hi = bcm2835_peri_read(paddr); - - paddr = bcm2835_st + BCM2835_ST_CLO/4; - lo = bcm2835_peri_read(paddr); - - paddr = bcm2835_st + BCM2835_ST_CHI/4; - st = bcm2835_peri_read(paddr); - - /* Test for overflow */ - if (st == hi) - { - st <<= 32; - st += lo; - } - else - { - st <<= 32; - paddr = bcm2835_st + BCM2835_ST_CLO/4; - st += bcm2835_peri_read(paddr); - } - return st; -} - -/* Delays for the specified number of microseconds with offset */ -void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros) -{ - uint64_t compare = offset_micros + micros; - - while(bcm2835_st_read() < compare) - ; -} - -/* PWM */ - -void bcm2835_pwm_set_clock(uint32_t divisor) -{ - if ( bcm2835_clk == MAP_FAILED - || bcm2835_pwm == MAP_FAILED) - return; /* bcm2835_init() failed or not root */ - - /* From Gerts code */ - divisor &= 0xfff; - /* Stop PWM clock */ - bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x01); - bcm2835_delay(110); /* Prevents clock going slow */ - /* Wait for the clock to be not busy */ - while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0) - bcm2835_delay(1); - /* set the clock divider and enable PWM clock */ - bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisor << 12)); - bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x11); /* Source=osc and enable */ -} - -void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled) -{ - if ( bcm2835_clk == MAP_FAILED - || bcm2835_pwm == MAP_FAILED) - return; /* bcm2835_init() failed or not root */ - - uint32_t control = bcm2835_peri_read(bcm2835_pwm + BCM2835_PWM_CONTROL); - - if (channel == 0) - { - if (markspace) - control |= BCM2835_PWM0_MS_MODE; - else - control &= ~BCM2835_PWM0_MS_MODE; - if (enabled) - control |= BCM2835_PWM0_ENABLE; - else - control &= ~BCM2835_PWM0_ENABLE; - } - else if (channel == 1) - { - if (markspace) - control |= BCM2835_PWM1_MS_MODE; - else - control &= ~BCM2835_PWM1_MS_MODE; - if (enabled) - control |= BCM2835_PWM1_ENABLE; - else - control &= ~BCM2835_PWM1_ENABLE; - } - - /* If you use the barrier here, wierd things happen, and the commands dont work */ - bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM_CONTROL, control); - /* bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM_CONTROL, BCM2835_PWM0_ENABLE | BCM2835_PWM1_ENABLE | BCM2835_PWM0_MS_MODE | BCM2835_PWM1_MS_MODE); */ - -} - -void bcm2835_pwm_set_range(uint8_t channel, uint32_t range) -{ - if ( bcm2835_clk == MAP_FAILED - || bcm2835_pwm == MAP_FAILED) - return; /* bcm2835_init() failed or not root */ - - if (channel == 0) - bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM0_RANGE, range); - else if (channel == 1) - bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM1_RANGE, range); -} - -void bcm2835_pwm_set_data(uint8_t channel, uint32_t data) -{ - if ( bcm2835_clk == MAP_FAILED - || bcm2835_pwm == MAP_FAILED) - return; /* bcm2835_init() failed or not root */ - - if (channel == 0) - bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM0_DATA, data); - else if (channel == 1) - bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM1_DATA, data); -} - -/* Allocate page-aligned memory. */ -void *malloc_aligned(size_t size) -{ - void *mem; - errno = posix_memalign(&mem, BCM2835_PAGE_SIZE, size); - return (errno ? NULL : mem); -} - -/* Map 'size' bytes starting at 'off' in file 'fd' to memory. -// Return mapped address on success, MAP_FAILED otherwise. -// On error print message. -*/ -static void *mapmem(const char *msg, size_t size, int fd, off_t off) -{ - void *map = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, off); - if (map == MAP_FAILED) - fprintf(stderr, "bcm2835_init: %s mmap failed: %s\n", msg, strerror(errno)); - return map; -} - -static void unmapmem(void **pmem, size_t size) -{ - if (*pmem == MAP_FAILED) return; - munmap(*pmem, size); - *pmem = MAP_FAILED; -} - -/* Initialise this library. */ -int bcm2835_init(void) -{ - int memfd; - int ok; - FILE *fp; - - if (debug) - { - bcm2835_peripherals = (uint32_t*)BCM2835_PERI_BASE; - - bcm2835_pads = bcm2835_peripherals + BCM2835_GPIO_PADS/4; - bcm2835_clk = bcm2835_peripherals + BCM2835_CLOCK_BASE/4; - bcm2835_gpio = bcm2835_peripherals + BCM2835_GPIO_BASE/4; - bcm2835_pwm = bcm2835_peripherals + BCM2835_GPIO_PWM/4; - bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI0_BASE/4; - bcm2835_bsc0 = bcm2835_peripherals + BCM2835_BSC0_BASE/4; - bcm2835_bsc1 = bcm2835_peripherals + BCM2835_BSC1_BASE/4; - bcm2835_st = bcm2835_peripherals + BCM2835_ST_BASE/4; - bcm2835_aux = bcm2835_peripherals + BCM2835_AUX_BASE/4; - bcm2835_spi1 = bcm2835_peripherals + BCM2835_SPI1_BASE/4; - - return 1; /* Success */ - } - - /* Figure out the base and size of the peripheral address block - // using the device-tree. Required for RPi2/3/4, optional for RPi 1 - */ - if ((fp = fopen(BMC2835_RPI2_DT_FILENAME , "rb"))) - { - unsigned char buf[16]; - uint32_t base_address; - uint32_t peri_size; - if (fread(buf, 1, sizeof(buf), fp) >= 8) - { - base_address = (buf[4] << 24) | - (buf[5] << 16) | - (buf[6] << 8) | - (buf[7] << 0); - - peri_size = (buf[8] << 24) | - (buf[9] << 16) | - (buf[10] << 8) | - (buf[11] << 0); - - if (!base_address) - { - /* looks like RPI 4 */ - base_address = (buf[8] << 24) | - (buf[9] << 16) | - (buf[10] << 8) | - (buf[11] << 0); - - peri_size = (buf[12] << 24) | - (buf[13] << 16) | - (buf[14] << 8) | - (buf[15] << 0); - } - /* check for valid known range formats */ - if ((buf[0] == 0x7e) && - (buf[1] == 0x00) && - (buf[2] == 0x00) && - (buf[3] == 0x00) && - ((base_address == BCM2835_PERI_BASE) || (base_address == BCM2835_RPI2_PERI_BASE) || (base_address == BCM2835_RPI4_PERI_BASE))) - { - bcm2835_peripherals_base = (off_t)base_address; - bcm2835_peripherals_size = (size_t)peri_size; - if( base_address == BCM2835_RPI4_PERI_BASE ) - { - pud_type_rpi4 = 1; - } - } - - } - - fclose(fp); - } - /* else we are prob on RPi 1 with BCM2835, and use the hardwired defaults */ - - /* Now get ready to map the peripherals block - * If we are not root, try for the new /dev/gpiomem interface and accept - * the fact that we can only access GPIO - * else try for the /dev/mem interface and get access to everything - */ - memfd = -1; - ok = 0; - if (geteuid() == 0 -#ifdef BCM2835_HAVE_LIBCAP - || bcm2835_has_capability(CAP_SYS_RAWIO) -#endif - ) - { - /* Open the master /dev/mem device */ - if ((memfd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) - { - fprintf(stderr, "bcm2835_init: Unable to open /dev/mem: %s\n", - strerror(errno)) ; - goto exit; - } - - /* Base of the peripherals block is mapped to VM */ - bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, bcm2835_peripherals_base); - if (bcm2835_peripherals == MAP_FAILED) goto exit; - - /* Now compute the base addresses of various peripherals, - // which are at fixed offsets within the mapped peripherals block - // Caution: bcm2835_peripherals is uint32_t*, so divide offsets by 4 - */ - bcm2835_gpio = bcm2835_peripherals + BCM2835_GPIO_BASE/4; - bcm2835_pwm = bcm2835_peripherals + BCM2835_GPIO_PWM/4; - bcm2835_clk = bcm2835_peripherals + BCM2835_CLOCK_BASE/4; - bcm2835_pads = bcm2835_peripherals + BCM2835_GPIO_PADS/4; - bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI0_BASE/4; - bcm2835_bsc0 = bcm2835_peripherals + BCM2835_BSC0_BASE/4; /* I2C */ - bcm2835_bsc1 = bcm2835_peripherals + BCM2835_BSC1_BASE/4; /* I2C */ - bcm2835_st = bcm2835_peripherals + BCM2835_ST_BASE/4; - bcm2835_aux = bcm2835_peripherals + BCM2835_AUX_BASE/4; - bcm2835_spi1 = bcm2835_peripherals + BCM2835_SPI1_BASE/4; - - ok = 1; - } - else - { - /* Not root, try /dev/gpiomem */ - /* Open the master /dev/mem device */ - if ((memfd = open("/dev/gpiomem", O_RDWR | O_SYNC) ) < 0) - { - fprintf(stderr, "bcm2835_init: Unable to open /dev/gpiomem: %s\n", - strerror(errno)) ; - goto exit; - } - - /* Base of the peripherals block is mapped to VM */ - bcm2835_peripherals_base = 0; - bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, bcm2835_peripherals_base); - if (bcm2835_peripherals == MAP_FAILED) goto exit; - bcm2835_gpio = bcm2835_peripherals; - ok = 1; - } - -exit: - if (memfd >= 0) - close(memfd); - - if (!ok) - bcm2835_close(); - - return ok; -} - -/* Close this library and deallocate everything */ -int bcm2835_close(void) -{ - if (debug) return 1; /* Success */ - - unmapmem((void**) &bcm2835_peripherals, bcm2835_peripherals_size); - bcm2835_peripherals = MAP_FAILED; - bcm2835_gpio = MAP_FAILED; - bcm2835_pwm = MAP_FAILED; - bcm2835_clk = MAP_FAILED; - bcm2835_pads = MAP_FAILED; - bcm2835_spi0 = MAP_FAILED; - bcm2835_bsc0 = MAP_FAILED; - bcm2835_bsc1 = MAP_FAILED; - bcm2835_st = MAP_FAILED; - bcm2835_aux = MAP_FAILED; - bcm2835_spi1 = MAP_FAILED; - return 1; /* Success */ -} - -#ifdef BCM2835_TEST -/* this is a simple test program that prints out what it will do rather than -// actually doing it -*/ -int main(int argc, char **argv) -{ - /* Be non-destructive */ - bcm2835_set_debug(1); - - if (!bcm2835_init()) - return 1; - - /* Configure some GPIO pins fo some testing - // Set RPI pin P1-11 to be an output - */ - bcm2835_gpio_fsel(RPI_GPIO_P1_11, BCM2835_GPIO_FSEL_OUTP); - /* Set RPI pin P1-15 to be an input */ - bcm2835_gpio_fsel(RPI_GPIO_P1_15, BCM2835_GPIO_FSEL_INPT); - /* with a pullup */ - bcm2835_gpio_set_pud(RPI_GPIO_P1_15, BCM2835_GPIO_PUD_UP); - /* And a low detect enable */ - bcm2835_gpio_len(RPI_GPIO_P1_15); - /* and input hysteresis disabled on GPIOs 0 to 27 */ - bcm2835_gpio_set_pad(BCM2835_PAD_GROUP_GPIO_0_27, BCM2835_PAD_SLEW_RATE_UNLIMITED|BCM2835_PAD_DRIVE_8mA); - -#if 1 - /* Blink */ - while (1) - { - /* Turn it on */ - bcm2835_gpio_write(RPI_GPIO_P1_11, HIGH); - - /* wait a bit */ - bcm2835_delay(500); - - /* turn it off */ - bcm2835_gpio_write(RPI_GPIO_P1_11, LOW); - - /* wait a bit */ - bcm2835_delay(500); - } -#endif - -#if 0 - /* Read input */ - while (1) - { - /* Read some data */ - uint8_t value = bcm2835_gpio_lev(RPI_GPIO_P1_15); - printf("read from pin 15: %d\n", value); - - /* wait a bit */ - bcm2835_delay(500); - } -#endif - -#if 0 - /* Look for a low event detection - // eds will be set whenever pin 15 goes low - */ - while (1) - { - if (bcm2835_gpio_eds(RPI_GPIO_P1_15)) - { - /* Now clear the eds flag by setting it to 1 */ - bcm2835_gpio_set_eds(RPI_GPIO_P1_15); - printf("low event detect for pin 15\n"); - } - - /* wait a bit */ - bcm2835_delay(500); - } -#endif - - if (!bcm2835_close()) - return 1; - - return 0; -} -#endif - - - diff --git a/RF24/utility/RPi/bcm2835.h b/RF24/utility/RPi/bcm2835.h deleted file mode 100644 index bd5e340c01705720f797a6f73d3e3a2a2d273c74..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/bcm2835.h +++ /dev/null @@ -1,2029 +0,0 @@ -/* bcm2835.h - - C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi - - Author: Mike McCauley - Copyright (C) 2011-2013 Mike McCauley - $Id: bcm2835.h,v 1.26 2020/01/11 05:07:13 mikem Exp mikem $ -*/ - -/*! \mainpage C library for Broadcom BCM 2835 as used in Raspberry Pi - - This is a C library for Raspberry Pi (RPi). It provides access to - GPIO and other IO functions on the Broadcom BCM 2835 chip, as used in the RaspberryPi, - allowing access to the GPIO pins on the - 26 pin IDE plug on the RPi board so you can control and interface with various external devices. - - It provides functions for reading digital inputs and setting digital outputs, using SPI and I2C, - and for accessing the system timers. - Pin event detection is supported by polling (interrupts are not supported). - - Works on all versions upt to and including RPI 4. - Works with all versions of Debian up to and including Debian Buster 10. - - It is C++ compatible, and installs as a header file and non-shared library on - any Linux-based distro (but clearly is no use except on Raspberry Pi or another board with - BCM 2835). - - The version of the package that this documentation refers to can be downloaded - from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.64.tar.gz - You can find the latest version at http://www.airspayce.com/mikem/bcm2835 - - Several example programs are provided. - - Based on data in http://elinux.org/RPi_Low-level_peripherals and - http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf - and http://www.scribd.com/doc/101830961/GPIO-Pads-Control2 - - You can also find online help and discussion at http://groups.google.com/group/bcm2835 - Please use that group for all questions and discussions on this topic. - Do not contact the author directly, unless it is to discuss commercial licensing. - Before asking a question or reporting a bug, please read - - http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question - - http://www.catb.org/esr/faqs/smart-questions.html - - http://www.chiark.greenend.org.uk/~shgtatham/bugs.html - - Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian - and Occidentalisv01, 2016-02-09 Raspbian Jessie. - CAUTION: it has been observed that when detect enables such as bcm2835_gpio_len() - are used and the pin is pulled LOW - it can cause temporary hangs on 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian - and Occidentalisv01. - Reason for this is not yet determined, but we suspect that an interrupt handler is - hitting a hard loop on those OSs. - If you must use bcm2835_gpio_len() and friends, make sure you disable the pins with - bcm2835_gpio_clr_len() and friends after use. - - \par Running as root - - Prior to the release of Raspbian Jessie in Feb 2016, access to any - peripheral device via /dev/mem on the RPi required the process to - run as root. Raspbian Jessie permits non-root users to access the - GPIO peripheral (only) via /dev/gpiomem, and this library supports - that limited mode of operation. - - If the library runs with effective UID of 0 (ie root), then - bcm2835_init() will attempt to open /dev/mem, and, if successful, it - will permit use of all peripherals and library functions. - - If the library runs with any other effective UID (ie not root), then - bcm2835_init() will attempt to open /dev/gpiomem, and, if - successful, will only permit GPIO operations. In particular, - bcm2835_spi_begin() and bcm2835_i2c_begin() will return false and all - other non-gpio operations may fail silently or crash. - - If your program needs acccess to /dev/mem but not as root, - and if you have the libcap-dev package installed on the target, - you can compile this library to use - libcap2 so that it tests whether the exceutable has the cap_sys_rawio capability, and therefore - permission to access /dev/mem. - To enable this ability, uncomment the #define BCM2835_HAVE_LIBCAP in bcm2835.h or - -DBCM2835_HAVE_LIBCAP on your compiler command line. - After your program has been compiled: - \code - sudo setcap cap_sys_rawio+ep *myprogname* - \endcode - You also need to do these steps on the host once, to support libcap and not-root read/write access - to /dev/mem: - 1. Install libcap support - \code - sudo apt-get install libcap2 libcap-dev - 2. Add current user to kmem group - \code - sudo adduser $USER kmem - \endcode - 3. Allow write access to /dev/mem by members of kmem group - \code - echo 'SUBSYSTEM=="mem", KERNEL=="mem", GROUP="kmem", MODE="0660"' | sudo tee /etc/udev/rules.d/98-mem.rules - \endcode - \code - sudo reboot - \endcode - - \par Installation - - This library consists of a single non-shared library and header file, which will be - installed in the usual places by make install - - \code - # download the latest version of the library, say bcm2835-1.xx.tar.gz, then: - tar zxvf bcm2835-1.xx.tar.gz - cd bcm2835-1.xx - ./configure - make - sudo make check - sudo make install - \endcode - - \par Physical Addresses - - The functions bcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_set_bits() - are low level peripheral register access functions. They are designed to use - physical addresses as described in section 1.2.3 ARM physical addresses - of the BCM2835 ARM Peripherals manual. - Physical addresses range from 0x20000000 to 0x20FFFFFF for peripherals. The bus - addresses for peripherals are set up to map onto the peripheral bus address range starting at - 0x7E000000. Thus a peripheral advertised in the manual at bus address 0x7Ennnnnn is available at - physical address 0x20nnnnnn. - - On RPI 2, the peripheral addresses are different and the bcm2835 library gets them - from reading /proc/device-tree/soc/ranges. This is only availble with recent versions of the kernel on RPI 2. - - After initialisation, the base address of the various peripheral - registers are available with the following - externals: - bcm2835_gpio - bcm2835_pwm - bcm2835_clk - bcm2835_pads - bcm2835_spio0 - bcm2835_st - bcm2835_bsc0 - bcm2835_bsc1 - bcm2835_aux - bcm2835_spi1 - - \par Raspberry Pi 2 (RPI2) - - For this library to work correctly on RPI2, you MUST have the device tree support enabled in the kernel. - You should also ensure you are using the latest version of Linux. The library has been tested on RPI2 - with 2015-02-16-raspbian-wheezy and ArchLinuxARM-rpi-2 as of 2015-03-29. - - When device tree suport is enabled, the file /proc/device-tree/soc/ranges will appear in the file system, - and the bcm2835 module relies on its presence to correctly run on RPI2 (it is optional for RPI1). - Without device tree support enabled and the presence of this file, it will not work on RPI2. - - To enable device tree support: - - \code - sudo raspi-config - under Advanced Options - enable Device Tree - Reboot. - \endcode - - \par Pin Numbering - - The GPIO pin numbering as used by RPi is different to and inconsistent with the underlying - BCM 2835 chip pin numbering. http://elinux.org/RPi_BCM2835_GPIOs - - RPi has a 26 pin IDE header that provides access to some of the GPIO pins on the BCM 2835, - as well as power and ground pins. Not all GPIO pins on the BCM 2835 are available on the - IDE header. - - RPi Version 2 also has a P5 connector with 4 GPIO pins, 5V, 3.3V and Gnd. - - The functions in this library are designed to be passed the BCM 2835 GPIO pin number and _not_ - the RPi pin number. There are symbolic definitions for each of the available pins - that you should use for convenience. See \ref RPiGPIOPin. - - \par SPI Pins - - The bcm2835_spi_* functions allow you to control the BCM 2835 SPI0 interface, - allowing you to send and received data by SPI (Serial Peripheral Interface). - For more information about SPI, see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus - - When bcm2835_spi_begin() is called it changes the bahaviour of the SPI interface pins from their - default GPIO behaviour in order to support SPI. While SPI is in use, you will not be able - to control the state of the SPI pins through the usual bcm2835_spi_gpio_write(). - When bcm2835_spi_end() is called, the SPI pins will all revert to inputs, and can then be - configured and controled with the usual bcm2835_gpio_* calls. - - The Raspberry Pi GPIO pins used for SPI are: - - - P1-19 (MOSI) - - P1-21 (MISO) - - P1-23 (CLK) - - P1-24 (CE0) - - P1-26 (CE1) - - Although it is possible to select high speeds for the SPI interface, up to 125MHz (see bcm2835_spi_setClockDivider()) - you should not expect to actually achieve those sorts of speeds with the RPi wiring. Our tests on RPi 2 show that the - SPI CLK line when unloaded has a resonant frequency of about 40MHz, and when loaded, the MOSI and MISO lines - ring at an even lower frequency. Measurements show that SPI waveforms are very poor and unusable at 62 and 125MHz. - Dont expect any speed faster than 31MHz to work reliably. - - The bcm2835_aux_spi_* functions allow you to control the BCM 2835 SPI1 interface, - allowing you to send and received data by SPI (Serial Peripheral Interface). - - The Raspberry Pi GPIO pins used for AUX SPI (SPI1) are: - - - P1-38 (MOSI) - - P1-35 (MISO) - - P1-40 (CLK) - - P1-36 (CE2) - - \par I2C Pins - - The bcm2835_i2c_* functions allow you to control the BCM 2835 BSC interface, - allowing you to send and received data by I2C ("eye-squared cee"; generically referred to as "two-wire interface") . - For more information about I?C, see http://en.wikipedia.org/wiki/I%C2%B2C - - The Raspberry Pi V2 GPIO pins used for I2C are: - - - P1-03 (SDA) - - P1-05 (SLC) - - \par PWM - - The BCM2835 supports hardware PWM on a limited subset of GPIO pins. This bcm2835 library provides - functions for configuring and controlling PWM output on these pins. - - The BCM2835 contains 2 independent PWM channels (0 and 1), each of which be connnected to a limited subset of - GPIO pins. The following GPIO pins may be connected to the following PWM channels (from section 9.5): - \code - GPIO PIN RPi pin PWM Channel ALT FUN - 12 0 0 - 13 1 0 - 18 1-12 0 5 - 19 1 5 - 40 0 0 - 41 1 0 - 45 1 0 - 52 0 1 - 53 1 1 - \endcode - In order for a GPIO pin to emit output from its PWM channel, it must be set to the Alt Function given above. - Note carefully that current versions of the Raspberry Pi only expose one of these pins (GPIO 18 = RPi Pin 1-12) - on the IO headers, and therefore this is the only IO pin on the RPi that can be used for PWM. - Further it must be set to ALT FUN 5 to get PWM output. - - Both PWM channels are driven by the same PWM clock, whose clock dvider can be varied using - bcm2835_pwm_set_clock(). Each channel can be separately enabled with bcm2835_pwm_set_mode(). - The average output of the PWM channel is determined by the ratio of DATA/RANGE for that channel. - Use bcm2835_pwm_set_range() to set the range and bcm2835_pwm_set_data() to set the data in that ratio - - Each PWM channel can run in either Balanced or Mark-Space mode. In Balanced mode, the hardware - sends a combination of clock pulses that results in an overall DATA pulses per RANGE pulses. - In Mark-Space mode, the hardware sets the output HIGH for DATA clock pulses wide, followed by - LOW for RANGE-DATA clock pulses. - - The PWM clock can be set to control the PWM pulse widths. The PWM clock is derived from - a 19.2MHz clock. You can set any divider, but some common ones are provided by the BCM2835_PWM_CLOCK_DIVIDER_* - values of \ref bcm2835PWMClockDivider. - - For example, say you wanted to drive a DC motor with PWM at about 1kHz, - and control the speed in 1/1024 increments from - 0/1024 (stopped) through to 1024/1024 (full on). In that case you might set the - clock divider to be 16, and the RANGE to 1024. The pulse repetition frequency will be - 1.2MHz/1024 = 1171.875Hz. - - \par Interactions with other systems - - In order for bcm2835 library SPI to work, you may need to disable the SPI kernel module using: - - \code - sudo raspi-config - under Advanced Options - enable Device Tree - under Advanced Options - disable SPI - Reboot. - \endcode - - Since bcm2835 accesses the lowest level hardware interfaces (in eh intererests of speed and flexibility) - there can be intercations with other low level software trying to do similar things. - - It seems that with "latest" 8.0 Jessie 4.9.24-v7+ kernel PWM just won't - work unless you disable audio. There's a line - \code - dtparam=audio=on - \endcode - in the /boot/config.txt. - Comment it out like this: - \code - #dtparam=audio=on - \endcode - - \par Real Time performance constraints - - The bcm2835 is a library for user programs (i.e. they run in 'userland'). - Such programs are not part of the kernel and are usually - subject to paging and swapping by the kernel while it does other things besides running your program. - This means that you should not expect to get real-time performance or - real-time timing constraints from such programs. In particular, there is no guarantee that the - bcm2835_delay() and bcm2835_delayMicroseconds() will return after exactly the time requested. - In fact, depending on other activity on the host, IO etc, you might get significantly longer delay times - than the one you asked for. So please dont expect to get exactly the time delay you request. - - Arjan reports that you can prevent swapping on Linux with the following code fragment: - - \code - #define <sched.h> - #define <sys/mman.h> - - struct sched_param sp; - memset(&sp, 0, sizeof(sp)); - sp.sched_priority = sched_get_priority_max(SCHED_FIFO); - sched_setscheduler(0, SCHED_FIFO, &sp); - mlockall(MCL_CURRENT | MCL_FUTURE); - \endcode - - \par Crashing on some versions of Raspbian - Some people have reported that various versions of Rasbian will crash or hang - if certain GPIO pins are toggled: https://github.com/raspberrypi/linux/issues/2550 - when using bcm2835. - A workaround is to add this line to your /boot/config.txt: - \code - dtoverlay=gpio-no-irq - \endcode - - \par Bindings to other languages - - mikem has made Perl bindings available at CPAN: - http://search.cpan.org/~mikem/Device-BCM2835-1.9/lib/Device/BCM2835.pm - Matthew Baker has kindly made Python bindings available at: - https: github.com/mubeta06/py-libbcm2835 - Gary Marks has created a Serial Peripheral Interface (SPI) command-line utility - for Raspberry Pi, based on the bcm2835 library. The - utility, spincl, is licensed under Open Source GNU GPLv3 by iP Solutions (http://ipsolutionscorp.com), as a - free download with source included: http://ipsolutionscorp.com/raspberry-pi-spi-utility/ - - \par Open Source Licensing GPL V3 - - This is the appropriate option if you want to share the source code of your - application with everyone you distribute it to, and you also want to give them - the right to share who uses it. If you wish to use this software under Open - Source Licensing, you must contribute all your source code to the open source - community in accordance with the GPL Version 3 when your application is - distributed. See https://www.gnu.org/licenses/gpl-3.0.html and COPYING - - \par Commercial Licensing - - This is the appropriate option if you are creating proprietary applications - and you are not prepared to distribute and share the source code of your - application. To purchase a commercial license, contact info@airspayce.com - - \par Acknowledgements - - Some of this code has been inspired by Dom and Gert. - The I2C code has been inspired by Alan Barr. - - \par Revision History - - \version 1.0 Initial release - - \version 1.1 Minor bug fixes - - \version 1.2 Added support for SPI - - \version 1.3 Added bcm2835_spi_transfern() - - \version 1.4 Fixed a problem that prevented SPI CE1 being used. Reported by David Robinson. - - \version 1.5 Added bcm2835_close() to deinit the library. Suggested by C?sar Ortiz - - \version 1.6 Document testing on 2012-07-15-wheezy-raspbian and Occidentalisv01 - Functions bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen() - bcm2835_gpio_len(), bcm2835_gpio_aren() and bcm2835_gpio_afen() now - changes only the pin specified. Other pins that were already previously - enabled stay enabled. - Added bcm2835_gpio_clr_ren(), bcm2835_gpio_clr_fen(), bcm2835_gpio_clr_hen() - bcm2835_gpio_clr_len(), bcm2835_gpio_clr_aren(), bcm2835_gpio_clr_afen() - to clear the enable for individual pins, suggested by Andreas Sundstrom. - - \version 1.7 Added bcm2835_spi_transfernb to support different buffers for read and write. - - \version 1.8 Improvements to read barrier, as suggested by maddin. - - \version 1.9 Improvements contributed by mikew: - I noticed that it was mallocing memory for the mmaps on /dev/mem. - It's not necessary to do that, you can just mmap the file directly, - so I've removed the mallocs (and frees). - I've also modified delayMicroseconds() to use nanosleep() for long waits, - and a busy wait on a high resolution timer for the rest. This is because - I've found that calling nanosleep() takes at least 100-200 us. - You need to link using '-lrt' using this version. - I've added some unsigned casts to the debug prints to silence compiler - warnings I was getting, fixed some typos, and changed the value of - BCM2835_PAD_HYSTERESIS_ENABLED to 0x08 as per Gert van Loo's doc at - http://www.scribd.com/doc/101830961/GPIO-Pads-Control2 - Also added a define for the passwrd value that Gert says is needed to - change pad control settings. - - \version 1.10 Changed the names of the delay functions to bcm2835_delay() - and bcm2835_delayMicroseconds() to prevent collisions with wiringPi. - Macros to map delay()-> bcm2835_delay() and - Macros to map delayMicroseconds()-> bcm2835_delayMicroseconds(), which - can be disabled by defining BCM2835_NO_DELAY_COMPATIBILITY - - \version 1.11 Fixed incorrect link to download file - - \version 1.12 New GPIO pin definitions for RPi version 2 (which has a different GPIO mapping) - - \version 1.13 New GPIO pin definitions for RPi version 2 plug P5 - Hardware base pointers are now available (after initialisation) externally as bcm2835_gpio - bcm2835_pwm bcm2835_clk bcm2835_pads bcm2835_spi0. - - \version 1.14 Now compiles even if CLOCK_MONOTONIC_RAW is not available, uses CLOCK_MONOTONIC instead. - Fixed errors in documentation of SPI divider frequencies based on 250MHz clock. - Reported by Ben Simpson. - - \version 1.15 Added bcm2835_close() to end of examples as suggested by Mark Wolfe. - - \version 1.16 Added bcm2835_gpio_set_multi, bcm2835_gpio_clr_multi and bcm2835_gpio_write_multi - to allow a mask of pins to be set all at once. Requested by Sebastian Loncar. - - \version 1.17 Added bcm2835_gpio_write_mask. Requested by Sebastian Loncar. - - \version 1.18 Added bcm2835_i2c_* functions. Changes to bcm2835_delayMicroseconds: - now uses the RPi system timer counter, instead of clock_gettime, for improved accuracy. - No need to link with -lrt now. Contributed by Arjan van Vught. - \version 1.19 Removed inlines added by previous patch since they don't seem to work everywhere. - Reported by olly. - - \version 1.20 Patch from Mark Dootson to close /dev/mem after access to the peripherals has been granted. - - \version 1.21 delayMicroseconds is now not susceptible to 32 bit timer overruns. - Patch courtesy Jeremy Mortis. - - \version 1.22 Fixed incorrect definition of BCM2835_GPFEN0 which broke the ability to set - falling edge events. Reported by Mark Dootson. - - \version 1.23 Added bcm2835_i2c_set_baudrate and bcm2835_i2c_read_register_rs. - Improvements to bcm2835_i2c_read and bcm2835_i2c_write functions - to fix ocasional reads not completing. Patched by Mark Dootson. - - \version 1.24 Mark Dootson p[atched a problem with his previously submitted code - under high load from other processes. - - \version 1.25 Updated author and distribution location details to airspayce.com - - \version 1.26 Added missing unmapmem for pads in bcm2835_close to prevent a memory leak. - Reported by Hartmut Henkel. - - \version 1.27 bcm2835_gpio_set_pad() no longer needs BCM2835_PAD_PASSWRD: it is - now automatically included. - Added support for PWM mode with bcm2835_pwm_* functions. - - \version 1.28 Fixed a problem where bcm2835_spi_writenb() would have problems with transfers of more than - 64 bytes dues to read buffer filling. Patched by Peter Würtz. - - \version 1.29 Further fix to SPI from Peter Würtz. - - \version 1.30 10 microsecond delays from bcm2835_spi_transfer and bcm2835_spi_transfern for - significant performance improvements, Patch by Alan Watson. - - \version 1.31 Fix a GCC warning about dummy variable, patched by Alan Watson. Thanks. - - \version 1.32 Added option I2C_V1 definition to compile for version 1 RPi. - By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected. - Contributed by Malcolm Wiles based on work by Arvi Govindaraj. - - \version 1.33 Added command line utilities i2c and gpio to examples. Contributed by Shahrooz Shahparnia. - - \version 1.34 Added bcm2835_i2c_write_read_rs() which writes an arbitrary number of bytes, - sends a repeat start, and reads from the device. Contributed by Eduardo Steinhorst. - - \version 1.35 Fix build errors when compiled under Qt. Also performance improvements with SPI transfers. Contributed b Udo Klaas. - - \version 1.36 Make automake's test runner detect that we're skipping tests when not root, the second - one makes us skip the test when using fakeroot (as used when building - Debian packages). Contributed by Guido Günther. - - \version 1.37 Moved confiure.in to configure.ac as receommnded by autoreconf.<br> - Improvements to bcm2835_st_read to account for possible timer overflow, contributed by 'Ed'.<br> - Added definitions for Raspberry Pi B+ J8 header GPIO pins.<br> - - \version 1.38 Added bcm2835_regbase for the benefit of C# wrappers, patch by Frank Hommers <br> - - \version 1.39 Beta version of RPi2 compatibility. Not tested here on RPi2 hardware. - Testers please confirm correct operation on RPi2.<br> - Unnecessary 'volatile' qualifiers removed from all variables and signatures.<br> - Removed unsupportable PWM dividers, based on a report from Christophe Cecillon.<br> - Minor improvements to spi.c example.<br> - - \version 1.40 Correct operation on RPi2 has been confirmed.<br> - Fixed a number of compiler errors and warnings that occur when bcm2835.h is included - in code compiled with -Wall -Woverflow -Wstrict-overflow -Wshadow -Wextra -pedantic. - Reported by tlhackque.<br> - Fixed a problem where calling bcm2835_delayMicroseconds loops forever when debug is set. Reported by tlhackque.<br> - Reinstated use of volatile in 2 functions where there was a danger of lost reads or writes. Reported by tlhackque.<br> - - \version 1.41 Added BCM2835_VERSION macro and new function bcm2835_version(); Requested by tlhackque.<br> - Improvements to peripheral memory barriers as suggested by tlhackque.<br> - Reinstated some necessary volatile declarations as requested by tlhackque.<br> - - \version 1.42 Further improvements to memory barriers with the patient assistance and patches of tlhackque.<br> - - \version 1.43 Fixed problems with compiling barriers on RPI 2 with Arch Linux and gcc 4.9.2. - Reported and patched by Lars Christensen.<br> - Testing on RPI 2, with ArchLinuxARM-rpi-2-latest and 2015-02-16-raspbian-wheezy.<br> - - \version 1.44 Added documention about the need for device tree to be enabled on RPI2.<br> - Improvements to detection of availability of DMB instruction based on value of __ARM_ARCH macro.<br> - - \version 1.45 Fixed an error in the pad group offsets that would prevent bcm2835_gpio_set_pad() - and bcm2835_gpio_pad() working correctly with non-0 pad groups. Reported by Guido. - - \version 1.46 2015-09-18 - Added symbolic definitions for remaining pins on 40 pin GPIO header on RPi 2. <br> - - \version 1.47 2015-11-18 - Fixed possibly incorrect reads in bcm2835_i2c_read_register_rs, patch from Eckhardt Ulrich.<br> - - \version 1.48 2015-12-08 - Added patch from Eckhardt Ulrich that fixed problems that could cause hanging with bcm2835_i2c_read_register_rs - and others. - - \version 1.49 2016-01-05 - Added patch from Jonathan Perkin with new functions bcm2835_gpio_eds_multi() and bcm2835_gpio_set_eds_multi(). - - \version 1.50 2016-02-28 - Added support for running as non-root, permitting access to GPIO only. Functions - bcm2835_spi_begin() and bcm2835_i2c_begin() will now return 0 if not running as root - (which prevents access to the SPI and I2C peripherals, amongst others). - Testing on Raspbian Jessie. - - \version 1.51 2016-11-03 - Added documentation about SPI clock divider and resulting SPI speeds on RPi3. - Fixed a problem where seg fault could occur in bcm2835_delayMicroseconds() if not running as root. Patch from Pok. - - \version 1.52 2017-02-03 - Added link to commercial license purchasing. - - \version 1.53 2018-01-14 - Added support for AUX SPI (SPI1) - Contributed by Arjan van Vught (http://www.raspberrypi-dmx.org/) - - \version 1.54 2018-01-17 - Fixed compile errors in new AUX spi code under some circumstances. - - \version 1.55 2018-01-20 - Fixed version numbers. - Fixed some warnings. - - \version 1.56 2018-06-10 - Supports bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_LSBFIRST), after which SPI bytes are reversed on read or write. - Based on a suggestion by Damiano Benedetti. - - \version 1.57 2018-08-28 - Added SPI function bcm2835_spi_set_speed_hz(uint32_t speed_hz); - Contributed by Arjan van Vught (http://www.raspberrypi-dmx.org/) - - \version 1.58 2018-11-29 - Added examples/spiram, which shows how to use the included little library (spiram.c and spiram.h) - to read and write SPI RAM chips such as 23K256-I/P - - \version 1.59 2019-05-22 - Fixed a bug in bcm2835_i2c_read reported by Charles Hayward where a noisy I2C line cold cause a seg fault by - reading too many characters. - - \version 1.60 2019-07-23 - Applied patch from Mark Dootson for RPi 4 compatibility. Thanks Mark. Not tested here on RPi4, but others report it works. - Tested as still working correctly on earlier RPi models. Tested with Debian Buster on earlier models - - \version 1.61 2020-01-11 - Fixed errors in the documentation for bcm2835_spi_write. - Fixes issue seen on Raspberry Pi 4 boards where 64-bit off_t is used by - default via -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64. The offset was - being incorrectly converted, this way is clearer and fixes the problem. Contributed by Jonathan Perkin. - - \version 1.62 2020-01-12 - Fixed a problem that could cause compile failures with size_t and off_t - - \version 1.63 2020-03-07 - Added bcm2835_aux_spi_transfer, contributed by Michivi - Adopted GPL V3 licensing - - \version 1.64 2020-04-11 - Fixed error in definitions of BCM2835_AUX_SPI_STAT_TX_LVL and BCM2835_AUX_SPI_STAT_RX_LVL. Patch from - Eric Marzec. Thanks. - - \version 1.65, 1.66 2020-04-16 - Added support for use of capability cap_sys_rawio to determine if access to /dev/mem is available for non-root - users. Contributed by Doug McFadyen. - - \version 1.67, 1.66 2020-06-11 - Fixed an error in bcm2835_i2c_read() where the status byte was not correctly updated with BCM2835_BSC_S_DONE - Reported by Zihan. Thanks. - - \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS -*/ - - -/* Defines for BCM2835 */ -#ifndef BCM2835_H -#define BCM2835_H - -#include <stdint.h> - -#define BCM2835_VERSION 10066 /* Version 1.66 */ - -// Define this if you want to use libcap2 to determine if you have the cap_sys_rawio capability -// and therefore the capability of opening /dev/mem, even if you are not root. -// See the comments above in the documentation for 'Running As Root' -//#define BCM2835_HAVE_LIBCAP - -/* RPi 2 is ARM v7, and has DMB instruction for memory barriers. - Older RPis are ARM v6 and don't, so a coprocessor instruction must be used instead. - However, not all versions of gcc in all distros support the dmb assembler instruction even on compatible processors. - This test is so any ARMv7 or higher processors with suitable GCC will use DMB. -*/ -#if __ARM_ARCH >= 7 -#define BCM2835_HAVE_DMB -#endif - -/*! \defgroup constants Constants for passing to and from library functions - The values here are designed to be passed to various functions in the bcm2835 library. - @{ -*/ - -/*! This means pin HIGH, true, 3.3volts on a pin. */ -#define HIGH 0x1 -/*! This means pin LOW, false, 0volts on a pin. */ -#define LOW 0x0 - -/*! Return the minimum of 2 numbers */ -#ifndef MIN -#define MIN(a, b) (a < b ? a : b) -#endif - -/*! Speed of the core clock core_clk */ -#define BCM2835_CORE_CLK_HZ 250000000 /*!< 250 MHz */ - -/*! On all recent OSs, the base of the peripherals is read from a /proc file */ -#define BMC2835_RPI2_DT_FILENAME "/proc/device-tree/soc/ranges" - -/*! Physical addresses for various peripheral register sets - Base Physical Address of the BCM 2835 peripheral registers - Note this is different for the RPi2 BCM2836, where this is derived from /proc/device-tree/soc/ranges - If /proc/device-tree/soc/ranges exists on a RPi 1 OS, it would be expected to contain the - following numbers: -*/ -/*! Peripherals block base address on RPi 1 */ -#define BCM2835_PERI_BASE 0x20000000 -/*! Size of the peripherals block on RPi 1 */ -#define BCM2835_PERI_SIZE 0x01000000 -/*! Alternate base address for RPI 2 / 3 */ -#define BCM2835_RPI2_PERI_BASE 0x3F000000 -/*! Alternate base address for RPI 4 */ -#define BCM2835_RPI4_PERI_BASE 0xFE000000 -/*! Alternate size for RPI 4 */ -#define BCM2835_RPI4_PERI_SIZE 0x01800000 - -/*! Offsets for the bases of various peripherals within the peripherals block - / Base Address of the System Timer registers -*/ -#define BCM2835_ST_BASE 0x3000 -/*! Base Address of the Pads registers */ -#define BCM2835_GPIO_PADS 0x100000 -/*! Base Address of the Clock/timer registers */ -#define BCM2835_CLOCK_BASE 0x101000 -/*! Base Address of the GPIO registers */ -#define BCM2835_GPIO_BASE 0x200000 -/*! Base Address of the SPI0 registers */ -#define BCM2835_SPI0_BASE 0x204000 -/*! Base Address of the BSC0 registers */ -#define BCM2835_BSC0_BASE 0x205000 -/*! Base Address of the PWM registers */ -#define BCM2835_GPIO_PWM 0x20C000 -/*! Base Address of the AUX registers */ -#define BCM2835_AUX_BASE 0x215000 -/*! Base Address of the AUX_SPI1 registers */ -#define BCM2835_SPI1_BASE 0x215080 -/*! Base Address of the AUX_SPI2 registers */ -#define BCM2835_SPI2_BASE 0x2150C0 -/*! Base Address of the BSC1 registers */ -#define BCM2835_BSC1_BASE 0x804000 - -#include <stdlib.h> - -/*! Physical address and size of the peripherals block - May be overridden on RPi2 -*/ -extern off_t bcm2835_peripherals_base; -/*! Size of the peripherals block to be mapped */ -extern size_t bcm2835_peripherals_size; - -/*! Virtual memory address of the mapped peripherals block */ -extern uint32_t *bcm2835_peripherals; - -/*! Base of the ST (System Timer) registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_st; - -/*! Base of the GPIO registers. - Available after bcm2835_init has been called -*/ -extern volatile uint32_t *bcm2835_gpio; - -/*! Base of the PWM registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_pwm; - -/*! Base of the CLK registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_clk; - -/*! Base of the PADS registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_pads; - -/*! Base of the SPI0 registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_spi0; - -/*! Base of the BSC0 registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_bsc0; - -/*! Base of the BSC1 registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_bsc1; - -/*! Base of the AUX registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_aux; - -/*! Base of the SPI1 registers. - Available after bcm2835_init has been called (as root) -*/ -extern volatile uint32_t *bcm2835_spi1; - - -/*! \brief bcm2835RegisterBase - Register bases for bcm2835_regbase() -*/ -typedef enum -{ - BCM2835_REGBASE_ST = 1, /*!< Base of the ST (System Timer) registers. */ - BCM2835_REGBASE_GPIO = 2, /*!< Base of the GPIO registers. */ - BCM2835_REGBASE_PWM = 3, /*!< Base of the PWM registers. */ - BCM2835_REGBASE_CLK = 4, /*!< Base of the CLK registers. */ - BCM2835_REGBASE_PADS = 5, /*!< Base of the PADS registers. */ - BCM2835_REGBASE_SPI0 = 6, /*!< Base of the SPI0 registers. */ - BCM2835_REGBASE_BSC0 = 7, /*!< Base of the BSC0 registers. */ - BCM2835_REGBASE_BSC1 = 8, /*!< Base of the BSC1 registers. */ - BCM2835_REGBASE_AUX = 9, /*!< Base of the AUX registers. */ - BCM2835_REGBASE_SPI1 = 10 /*!< Base of the SPI1 registers. */ -} bcm2835RegisterBase; - -/*! Size of memory page on RPi */ -#define BCM2835_PAGE_SIZE (4*1024) -/*! Size of memory block on RPi */ -#define BCM2835_BLOCK_SIZE (4*1024) - - -/* Defines for GPIO - The BCM2835 has 54 GPIO pins. - BCM2835 data sheet, Page 90 onwards. -*/ -/*! GPIO register offsets from BCM2835_GPIO_BASE. - Offsets into the GPIO Peripheral block in bytes per 6.1 Register View -*/ -#define BCM2835_GPFSEL0 0x0000 /*!< GPIO Function Select 0 */ -#define BCM2835_GPFSEL1 0x0004 /*!< GPIO Function Select 1 */ -#define BCM2835_GPFSEL2 0x0008 /*!< GPIO Function Select 2 */ -#define BCM2835_GPFSEL3 0x000c /*!< GPIO Function Select 3 */ -#define BCM2835_GPFSEL4 0x0010 /*!< GPIO Function Select 4 */ -#define BCM2835_GPFSEL5 0x0014 /*!< GPIO Function Select 5 */ -#define BCM2835_GPSET0 0x001c /*!< GPIO Pin Output Set 0 */ -#define BCM2835_GPSET1 0x0020 /*!< GPIO Pin Output Set 1 */ -#define BCM2835_GPCLR0 0x0028 /*!< GPIO Pin Output Clear 0 */ -#define BCM2835_GPCLR1 0x002c /*!< GPIO Pin Output Clear 1 */ -#define BCM2835_GPLEV0 0x0034 /*!< GPIO Pin Level 0 */ -#define BCM2835_GPLEV1 0x0038 /*!< GPIO Pin Level 1 */ -#define BCM2835_GPEDS0 0x0040 /*!< GPIO Pin Event Detect Status 0 */ -#define BCM2835_GPEDS1 0x0044 /*!< GPIO Pin Event Detect Status 1 */ -#define BCM2835_GPREN0 0x004c /*!< GPIO Pin Rising Edge Detect Enable 0 */ -#define BCM2835_GPREN1 0x0050 /*!< GPIO Pin Rising Edge Detect Enable 1 */ -#define BCM2835_GPFEN0 0x0058 /*!< GPIO Pin Falling Edge Detect Enable 0 */ -#define BCM2835_GPFEN1 0x005c /*!< GPIO Pin Falling Edge Detect Enable 1 */ -#define BCM2835_GPHEN0 0x0064 /*!< GPIO Pin High Detect Enable 0 */ -#define BCM2835_GPHEN1 0x0068 /*!< GPIO Pin High Detect Enable 1 */ -#define BCM2835_GPLEN0 0x0070 /*!< GPIO Pin Low Detect Enable 0 */ -#define BCM2835_GPLEN1 0x0074 /*!< GPIO Pin Low Detect Enable 1 */ -#define BCM2835_GPAREN0 0x007c /*!< GPIO Pin Async. Rising Edge Detect 0 */ -#define BCM2835_GPAREN1 0x0080 /*!< GPIO Pin Async. Rising Edge Detect 1 */ -#define BCM2835_GPAFEN0 0x0088 /*!< GPIO Pin Async. Falling Edge Detect 0 */ -#define BCM2835_GPAFEN1 0x008c /*!< GPIO Pin Async. Falling Edge Detect 1 */ -#define BCM2835_GPPUD 0x0094 /*!< GPIO Pin Pull-up/down Enable */ -#define BCM2835_GPPUDCLK0 0x0098 /*!< GPIO Pin Pull-up/down Enable Clock 0 */ -#define BCM2835_GPPUDCLK1 0x009c /*!< GPIO Pin Pull-up/down Enable Clock 1 */ - -/* 2711 has a different method for pin pull-up/down/enable */ -#define BCM2835_GPPUPPDN0 0x00e4 /* Pin pull-up/down for pins 15:0 */ -#define BCM2835_GPPUPPDN1 0x00e8 /* Pin pull-up/down for pins 31:16 */ -#define BCM2835_GPPUPPDN2 0x00ec /* Pin pull-up/down for pins 47:32 */ -#define BCM2835_GPPUPPDN3 0x00f0 /* Pin pull-up/down for pins 57:48 */ - -/*! \brief bcm2835PortFunction - Port function select modes for bcm2835_gpio_fsel() -*/ -typedef enum -{ - BCM2835_GPIO_FSEL_INPT = 0x00, /*!< Input 0b000 */ - BCM2835_GPIO_FSEL_OUTP = 0x01, /*!< Output 0b001 */ - BCM2835_GPIO_FSEL_ALT0 = 0x04, /*!< Alternate function 0 0b100 */ - BCM2835_GPIO_FSEL_ALT1 = 0x05, /*!< Alternate function 1 0b101 */ - BCM2835_GPIO_FSEL_ALT2 = 0x06, /*!< Alternate function 2 0b110, */ - BCM2835_GPIO_FSEL_ALT3 = 0x07, /*!< Alternate function 3 0b111 */ - BCM2835_GPIO_FSEL_ALT4 = 0x03, /*!< Alternate function 4 0b011 */ - BCM2835_GPIO_FSEL_ALT5 = 0x02, /*!< Alternate function 5 0b010 */ - BCM2835_GPIO_FSEL_MASK = 0x07 /*!< Function select bits mask 0b111 */ -} bcm2835FunctionSelect; - -/*! \brief bcm2835PUDControl - Pullup/Pulldown defines for bcm2835_gpio_pud() -*/ -typedef enum -{ - BCM2835_GPIO_PUD_OFF = 0x00, /*!< Off ? disable pull-up/down 0b00 */ - BCM2835_GPIO_PUD_DOWN = 0x01, /*!< Enable Pull Down control 0b01 */ - BCM2835_GPIO_PUD_UP = 0x02 /*!< Enable Pull Up control 0b10 */ -} bcm2835PUDControl; - -/* need a value for pud functions that can't work unless RPI 4 */ -#define BCM2835_GPIO_PUD_ERROR 0x08 - -/*! Pad control register offsets from BCM2835_GPIO_PADS */ -#define BCM2835_PADS_GPIO_0_27 0x002c /*!< Pad control register for pads 0 to 27 */ -#define BCM2835_PADS_GPIO_28_45 0x0030 /*!< Pad control register for pads 28 to 45 */ -#define BCM2835_PADS_GPIO_46_53 0x0034 /*!< Pad control register for pads 46 to 53 */ - -/*! Pad Control masks */ -#define BCM2835_PAD_PASSWRD (0x5A << 24) /*!< Password to enable setting pad mask */ -#define BCM2835_PAD_SLEW_RATE_UNLIMITED 0x10 /*!< Slew rate unlimited */ -#define BCM2835_PAD_HYSTERESIS_ENABLED 0x08 /*!< Hysteresis enabled */ -#define BCM2835_PAD_DRIVE_2mA 0x00 /*!< 2mA drive current */ -#define BCM2835_PAD_DRIVE_4mA 0x01 /*!< 4mA drive current */ -#define BCM2835_PAD_DRIVE_6mA 0x02 /*!< 6mA drive current */ -#define BCM2835_PAD_DRIVE_8mA 0x03 /*!< 8mA drive current */ -#define BCM2835_PAD_DRIVE_10mA 0x04 /*!< 10mA drive current */ -#define BCM2835_PAD_DRIVE_12mA 0x05 /*!< 12mA drive current */ -#define BCM2835_PAD_DRIVE_14mA 0x06 /*!< 14mA drive current */ -#define BCM2835_PAD_DRIVE_16mA 0x07 /*!< 16mA drive current */ - -/*! \brief bcm2835PadGroup - Pad group specification for bcm2835_gpio_pad() -*/ -typedef enum -{ - BCM2835_PAD_GROUP_GPIO_0_27 = 0, /*!< Pad group for GPIO pads 0 to 27 */ - BCM2835_PAD_GROUP_GPIO_28_45 = 1, /*!< Pad group for GPIO pads 28 to 45 */ - BCM2835_PAD_GROUP_GPIO_46_53 = 2 /*!< Pad group for GPIO pads 46 to 53 */ -} bcm2835PadGroup; - -/*! \brief GPIO Pin Numbers - - Here we define Raspberry Pin GPIO pins on P1 in terms of the underlying BCM GPIO pin numbers. - These can be passed as a pin number to any function requiring a pin. - Not all pins on the RPi 26 bin IDE plug are connected to GPIO pins - and some can adopt an alternate function. - RPi version 2 has some slightly different pinouts, and these are values RPI_V2_*. - RPi B+ has yet differnet pinouts and these are defined in RPI_BPLUS_*. - At bootup, pins 8 and 10 are set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively - When SPI0 is in use (ie after bcm2835_spi_begin()), SPI0 pins are dedicated to SPI - and cant be controlled independently. - If you are using the RPi Compute Module, just use the GPIO number: there is no need to use one of these - symbolic names -*/ -typedef enum -{ - RPI_GPIO_P1_03 = 0, /*!< Version 1, Pin P1-03 */ - RPI_GPIO_P1_05 = 1, /*!< Version 1, Pin P1-05 */ - RPI_GPIO_P1_07 = 4, /*!< Version 1, Pin P1-07 */ - RPI_GPIO_P1_08 = 14, /*!< Version 1, Pin P1-08, defaults to alt function 0 UART0_TXD */ - RPI_GPIO_P1_10 = 15, /*!< Version 1, Pin P1-10, defaults to alt function 0 UART0_RXD */ - RPI_GPIO_P1_11 = 17, /*!< Version 1, Pin P1-11 */ - RPI_GPIO_P1_12 = 18, /*!< Version 1, Pin P1-12, can be PWM channel 0 in ALT FUN 5 */ - RPI_GPIO_P1_13 = 21, /*!< Version 1, Pin P1-13 */ - RPI_GPIO_P1_15 = 22, /*!< Version 1, Pin P1-15 */ - RPI_GPIO_P1_16 = 23, /*!< Version 1, Pin P1-16 */ - RPI_GPIO_P1_18 = 24, /*!< Version 1, Pin P1-18 */ - RPI_GPIO_P1_19 = 10, /*!< Version 1, Pin P1-19, MOSI when SPI0 in use */ - RPI_GPIO_P1_21 = 9, /*!< Version 1, Pin P1-21, MISO when SPI0 in use */ - RPI_GPIO_P1_22 = 25, /*!< Version 1, Pin P1-22 */ - RPI_GPIO_P1_23 = 11, /*!< Version 1, Pin P1-23, CLK when SPI0 in use */ - RPI_GPIO_P1_24 = 8, /*!< Version 1, Pin P1-24, CE0 when SPI0 in use */ - RPI_GPIO_P1_26 = 7, /*!< Version 1, Pin P1-26, CE1 when SPI0 in use */ - - /* RPi Version 2 */ - RPI_V2_GPIO_P1_03 = 2, /*!< Version 2, Pin P1-03 */ - RPI_V2_GPIO_P1_05 = 3, /*!< Version 2, Pin P1-05 */ - RPI_V2_GPIO_P1_07 = 4, /*!< Version 2, Pin P1-07 */ - RPI_V2_GPIO_P1_08 = 14, /*!< Version 2, Pin P1-08, defaults to alt function 0 UART0_TXD */ - RPI_V2_GPIO_P1_10 = 15, /*!< Version 2, Pin P1-10, defaults to alt function 0 UART0_RXD */ - RPI_V2_GPIO_P1_11 = 17, /*!< Version 2, Pin P1-11 */ - RPI_V2_GPIO_P1_12 = 18, /*!< Version 2, Pin P1-12, can be PWM channel 0 in ALT FUN 5 */ - RPI_V2_GPIO_P1_13 = 27, /*!< Version 2, Pin P1-13 */ - RPI_V2_GPIO_P1_15 = 22, /*!< Version 2, Pin P1-15 */ - RPI_V2_GPIO_P1_16 = 23, /*!< Version 2, Pin P1-16 */ - RPI_V2_GPIO_P1_18 = 24, /*!< Version 2, Pin P1-18 */ - RPI_V2_GPIO_P1_19 = 10, /*!< Version 2, Pin P1-19, MOSI when SPI0 in use */ - RPI_V2_GPIO_P1_21 = 9, /*!< Version 2, Pin P1-21, MISO when SPI0 in use */ - RPI_V2_GPIO_P1_22 = 25, /*!< Version 2, Pin P1-22 */ - RPI_V2_GPIO_P1_23 = 11, /*!< Version 2, Pin P1-23, CLK when SPI0 in use */ - RPI_V2_GPIO_P1_24 = 8, /*!< Version 2, Pin P1-24, CE0 when SPI0 in use */ - RPI_V2_GPIO_P1_26 = 7, /*!< Version 2, Pin P1-26, CE1 when SPI0 in use */ - RPI_V2_GPIO_P1_29 = 5, /*!< Version 2, Pin P1-29 */ - RPI_V2_GPIO_P1_31 = 6, /*!< Version 2, Pin P1-31 */ - RPI_V2_GPIO_P1_32 = 12, /*!< Version 2, Pin P1-32 */ - RPI_V2_GPIO_P1_33 = 13, /*!< Version 2, Pin P1-33 */ - RPI_V2_GPIO_P1_35 = 19, /*!< Version 2, Pin P1-35, can be PWM channel 1 in ALT FUN 5 */ - RPI_V2_GPIO_P1_36 = 16, /*!< Version 2, Pin P1-36 */ - RPI_V2_GPIO_P1_37 = 26, /*!< Version 2, Pin P1-37 */ - RPI_V2_GPIO_P1_38 = 20, /*!< Version 2, Pin P1-38 */ - RPI_V2_GPIO_P1_40 = 21, /*!< Version 2, Pin P1-40 */ - - /* RPi Version 2, new plug P5 */ - RPI_V2_GPIO_P5_03 = 28, /*!< Version 2, Pin P5-03 */ - RPI_V2_GPIO_P5_04 = 29, /*!< Version 2, Pin P5-04 */ - RPI_V2_GPIO_P5_05 = 30, /*!< Version 2, Pin P5-05 */ - RPI_V2_GPIO_P5_06 = 31, /*!< Version 2, Pin P5-06 */ - - /* RPi B+ J8 header, also RPi 2 40 pin GPIO header */ - RPI_BPLUS_GPIO_J8_03 = 2, /*!< B+, Pin J8-03 */ - RPI_BPLUS_GPIO_J8_05 = 3, /*!< B+, Pin J8-05 */ - RPI_BPLUS_GPIO_J8_07 = 4, /*!< B+, Pin J8-07 */ - RPI_BPLUS_GPIO_J8_08 = 14, /*!< B+, Pin J8-08, defaults to alt function 0 UART0_TXD */ - RPI_BPLUS_GPIO_J8_10 = 15, /*!< B+, Pin J8-10, defaults to alt function 0 UART0_RXD */ - RPI_BPLUS_GPIO_J8_11 = 17, /*!< B+, Pin J8-11 */ - RPI_BPLUS_GPIO_J8_12 = 18, /*!< B+, Pin J8-12, can be PWM channel 0 in ALT FUN 5 */ - RPI_BPLUS_GPIO_J8_13 = 27, /*!< B+, Pin J8-13 */ - RPI_BPLUS_GPIO_J8_15 = 22, /*!< B+, Pin J8-15 */ - RPI_BPLUS_GPIO_J8_16 = 23, /*!< B+, Pin J8-16 */ - RPI_BPLUS_GPIO_J8_18 = 24, /*!< B+, Pin J8-18 */ - RPI_BPLUS_GPIO_J8_19 = 10, /*!< B+, Pin J8-19, MOSI when SPI0 in use */ - RPI_BPLUS_GPIO_J8_21 = 9, /*!< B+, Pin J8-21, MISO when SPI0 in use */ - RPI_BPLUS_GPIO_J8_22 = 25, /*!< B+, Pin J8-22 */ - RPI_BPLUS_GPIO_J8_23 = 11, /*!< B+, Pin J8-23, CLK when SPI0 in use */ - RPI_BPLUS_GPIO_J8_24 = 8, /*!< B+, Pin J8-24, CE0 when SPI0 in use */ - RPI_BPLUS_GPIO_J8_26 = 7, /*!< B+, Pin J8-26, CE1 when SPI0 in use */ - RPI_BPLUS_GPIO_J8_29 = 5, /*!< B+, Pin J8-29, */ - RPI_BPLUS_GPIO_J8_31 = 6, /*!< B+, Pin J8-31, */ - RPI_BPLUS_GPIO_J8_32 = 12, /*!< B+, Pin J8-32, */ - RPI_BPLUS_GPIO_J8_33 = 13, /*!< B+, Pin J8-33, */ - RPI_BPLUS_GPIO_J8_35 = 19, /*!< B+, Pin J8-35, can be PWM channel 1 in ALT FUN 5 */ - RPI_BPLUS_GPIO_J8_36 = 16, /*!< B+, Pin J8-36, */ - RPI_BPLUS_GPIO_J8_37 = 26, /*!< B+, Pin J8-37, */ - RPI_BPLUS_GPIO_J8_38 = 20, /*!< B+, Pin J8-38, */ - RPI_BPLUS_GPIO_J8_40 = 21 /*!< B+, Pin J8-40, */ -} RPiGPIOPin; - -/* Defines for AUX - GPIO register offsets from BCM2835_AUX_BASE. -*/ -#define BCM2835_AUX_IRQ 0x0000 /*!< xxx */ -#define BCM2835_AUX_ENABLE 0x0004 /*!< */ - -#define BCM2835_AUX_ENABLE_UART1 0x01 /*!< */ -#define BCM2835_AUX_ENABLE_SPI0 0x02 /*!< SPI0 (SPI1 in the device) */ -#define BCM2835_AUX_ENABLE_SPI1 0x04 /*!< SPI1 (SPI2 in the device) */ - - -#define BCM2835_AUX_SPI_CNTL0 0x0000 /*!< */ -#define BCM2835_AUX_SPI_CNTL1 0x0004 /*!< */ -#define BCM2835_AUX_SPI_STAT 0x0008 /*!< */ -#define BCM2835_AUX_SPI_PEEK 0x000C /*!< Read but do not take from FF */ -#define BCM2835_AUX_SPI_IO 0x0020 /*!< Write = TX, read=RX */ -#define BCM2835_AUX_SPI_TXHOLD 0x0030 /*!< Write = TX keep CS, read=RX */ - -#define BCM2835_AUX_SPI_CLOCK_MIN 30500 /*!< 30,5kHz */ -#define BCM2835_AUX_SPI_CLOCK_MAX 125000000 /*!< 125Mhz */ - -#define BCM2835_AUX_SPI_CNTL0_SPEED 0xFFF00000 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_SPEED_MAX 0xFFF /*!< */ -#define BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT 20 /*!< */ - -#define BCM2835_AUX_SPI_CNTL0_CS0_N 0x000C0000 /*!< CS 0 low */ -#define BCM2835_AUX_SPI_CNTL0_CS1_N 0x000A0000 /*!< CS 1 low */ -#define BCM2835_AUX_SPI_CNTL0_CS2_N 0x00060000 /*!< CS 2 low */ - -#define BCM2835_AUX_SPI_CNTL0_POSTINPUT 0x00010000 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_VAR_CS 0x00008000 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_VAR_WIDTH 0x00004000 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_DOUTHOLD 0x00003000 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_ENABLE 0x00000800 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_CPHA_IN 0x00000400 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_CLEARFIFO 0x00000200 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_CPHA_OUT 0x00000100 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_CPOL 0x00000080 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_MSBF_OUT 0x00000040 /*!< */ -#define BCM2835_AUX_SPI_CNTL0_SHIFTLEN 0x0000003F /*!< */ - -#define BCM2835_AUX_SPI_CNTL1_CSHIGH 0x00000700 /*!< */ -#define BCM2835_AUX_SPI_CNTL1_IDLE 0x00000080 /*!< */ -#define BCM2835_AUX_SPI_CNTL1_TXEMPTY 0x00000040 /*!< */ -#define BCM2835_AUX_SPI_CNTL1_MSBF_IN 0x00000002 /*!< */ -#define BCM2835_AUX_SPI_CNTL1_KEEP_IN 0x00000001 /*!< */ - -#define BCM2835_AUX_SPI_STAT_TX_LVL 0xF0000000 /*!< */ -#define BCM2835_AUX_SPI_STAT_RX_LVL 0x00F00000 /*!< */ -#define BCM2835_AUX_SPI_STAT_TX_FULL 0x00000400 /*!< */ -#define BCM2835_AUX_SPI_STAT_TX_EMPTY 0x00000200 /*!< */ -#define BCM2835_AUX_SPI_STAT_RX_FULL 0x00000100 /*!< */ -#define BCM2835_AUX_SPI_STAT_RX_EMPTY 0x00000080 /*!< */ -#define BCM2835_AUX_SPI_STAT_BUSY 0x00000040 /*!< */ -#define BCM2835_AUX_SPI_STAT_BITCOUNT 0x0000003F /*!< */ - -/* Defines for SPI - GPIO register offsets from BCM2835_SPI0_BASE. - Offsets into the SPI Peripheral block in bytes per 10.5 SPI Register Map -*/ -#define BCM2835_SPI0_CS 0x0000 /*!< SPI Master Control and Status */ -#define BCM2835_SPI0_FIFO 0x0004 /*!< SPI Master TX and RX FIFOs */ -#define BCM2835_SPI0_CLK 0x0008 /*!< SPI Master Clock Divider */ -#define BCM2835_SPI0_DLEN 0x000c /*!< SPI Master Data Length */ -#define BCM2835_SPI0_LTOH 0x0010 /*!< SPI LOSSI mode TOH */ -#define BCM2835_SPI0_DC 0x0014 /*!< SPI DMA DREQ Controls */ - -/* Register masks for SPI0_CS */ -#define BCM2835_SPI0_CS_LEN_LONG 0x02000000 /*!< Enable Long data word in Lossi mode if DMA_LEN is set */ -#define BCM2835_SPI0_CS_DMA_LEN 0x01000000 /*!< Enable DMA mode in Lossi mode */ -#define BCM2835_SPI0_CS_CSPOL2 0x00800000 /*!< Chip Select 2 Polarity */ -#define BCM2835_SPI0_CS_CSPOL1 0x00400000 /*!< Chip Select 1 Polarity */ -#define BCM2835_SPI0_CS_CSPOL0 0x00200000 /*!< Chip Select 0 Polarity */ -#define BCM2835_SPI0_CS_RXF 0x00100000 /*!< RXF - RX FIFO Full */ -#define BCM2835_SPI0_CS_RXR 0x00080000 /*!< RXR RX FIFO needs Reading (full) */ -#define BCM2835_SPI0_CS_TXD 0x00040000 /*!< TXD TX FIFO can accept Data */ -#define BCM2835_SPI0_CS_RXD 0x00020000 /*!< RXD RX FIFO contains Data */ -#define BCM2835_SPI0_CS_DONE 0x00010000 /*!< Done transfer Done */ -#define BCM2835_SPI0_CS_TE_EN 0x00008000 /*!< Unused */ -#define BCM2835_SPI0_CS_LMONO 0x00004000 /*!< Unused */ -#define BCM2835_SPI0_CS_LEN 0x00002000 /*!< LEN LoSSI enable */ -#define BCM2835_SPI0_CS_REN 0x00001000 /*!< REN Read Enable */ -#define BCM2835_SPI0_CS_ADCS 0x00000800 /*!< ADCS Automatically Deassert Chip Select */ -#define BCM2835_SPI0_CS_INTR 0x00000400 /*!< INTR Interrupt on RXR */ -#define BCM2835_SPI0_CS_INTD 0x00000200 /*!< INTD Interrupt on Done */ -#define BCM2835_SPI0_CS_DMAEN 0x00000100 /*!< DMAEN DMA Enable */ -#define BCM2835_SPI0_CS_TA 0x00000080 /*!< Transfer Active */ -#define BCM2835_SPI0_CS_CSPOL 0x00000040 /*!< Chip Select Polarity */ -#define BCM2835_SPI0_CS_CLEAR 0x00000030 /*!< Clear FIFO Clear RX and TX */ -#define BCM2835_SPI0_CS_CLEAR_RX 0x00000020 /*!< Clear FIFO Clear RX */ -#define BCM2835_SPI0_CS_CLEAR_TX 0x00000010 /*!< Clear FIFO Clear TX */ -#define BCM2835_SPI0_CS_CPOL 0x00000008 /*!< Clock Polarity */ -#define BCM2835_SPI0_CS_CPHA 0x00000004 /*!< Clock Phase */ -#define BCM2835_SPI0_CS_CS 0x00000003 /*!< Chip Select */ - -/*! \brief bcm2835SPIBitOrder SPI Bit order - Specifies the SPI data bit ordering for bcm2835_spi_setBitOrder() -*/ -typedef enum -{ - BCM2835_SPI_BIT_ORDER_LSBFIRST = 0, /*!< LSB First */ - BCM2835_SPI_BIT_ORDER_MSBFIRST = 1 /*!< MSB First */ -}bcm2835SPIBitOrder; - -/*! \brief SPI Data mode - Specify the SPI data mode to be passed to bcm2835_spi_setDataMode() -*/ -typedef enum -{ - BCM2835_SPI_MODE0 = 0, /*!< CPOL = 0, CPHA = 0 */ - BCM2835_SPI_MODE1 = 1, /*!< CPOL = 0, CPHA = 1 */ - BCM2835_SPI_MODE2 = 2, /*!< CPOL = 1, CPHA = 0 */ - BCM2835_SPI_MODE3 = 3 /*!< CPOL = 1, CPHA = 1 */ -}bcm2835SPIMode; - -/*! \brief bcm2835SPIChipSelect - Specify the SPI chip select pin(s) -*/ -typedef enum -{ - BCM2835_SPI_CS0 = 0, /*!< Chip Select 0 */ - BCM2835_SPI_CS1 = 1, /*!< Chip Select 1 */ - BCM2835_SPI_CS2 = 2, /*!< Chip Select 2 (ie pins CS1 and CS2 are asserted) */ - BCM2835_SPI_CS_NONE = 3 /*!< No CS, control it yourself */ -} bcm2835SPIChipSelect; - -/*! \brief bcm2835SPIClockDivider - Specifies the divider used to generate the SPI clock from the system clock. - Figures below give the divider, clock period and clock frequency. - Clock divided is based on nominal core clock rate of 250MHz on RPi1 and RPi2, and 400MHz on RPi3. - It is reported that (contrary to the documentation) any even divider may used. - The frequencies shown for each divider have been confirmed by measurement on RPi1 and RPi2. - The system clock frequency on RPi3 is different, so the frequency you get from a given divider will be different. - See comments in 'SPI Pins' for information about reliable SPI speeds. - Note: it is possible to change the core clock rate of the RPi 3 back to 250MHz, by putting - \code - core_freq=250 - \endcode - in the config.txt -*/ -typedef enum -{ - BCM2835_SPI_CLOCK_DIVIDER_65536 = 0, /*!< 65536 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_32768 = 32768, /*!< 32768 = 7.629394531kHz on Rpi2, 12.20703125kHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_16384 = 16384, /*!< 16384 = 15.25878906kHz on Rpi2, 24.4140625kHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_8192 = 8192, /*!< 8192 = 30.51757813kHz on Rpi2, 48.828125kHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_4096 = 4096, /*!< 4096 = 61.03515625kHz on Rpi2, 97.65625kHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_2048 = 2048, /*!< 2048 = 122.0703125kHz on Rpi2, 195.3125kHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_1024 = 1024, /*!< 1024 = 244.140625kHz on Rpi2, 390.625kHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_512 = 512, /*!< 512 = 488.28125kHz on Rpi2, 781.25kHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_256 = 256, /*!< 256 = 976.5625kHz on Rpi2, 1.5625MHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_128 = 128, /*!< 128 = 1.953125MHz on Rpi2, 3.125MHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_64 = 64, /*!< 64 = 3.90625MHz on Rpi2, 6.250MHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_32 = 32, /*!< 32 = 7.8125MHz on Rpi2, 12.5MHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_16 = 16, /*!< 16 = 15.625MHz on Rpi2, 25MHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_8 = 8, /*!< 8 = 31.25MHz on Rpi2, 50MHz on RPI3 */ - BCM2835_SPI_CLOCK_DIVIDER_4 = 4, /*!< 4 = 62.5MHz on Rpi2, 100MHz on RPI3. Dont expect this speed to work reliably. */ - BCM2835_SPI_CLOCK_DIVIDER_2 = 2, /*!< 2 = 125MHz on Rpi2, 200MHz on RPI3, fastest you can get. Dont expect this speed to work reliably.*/ - BCM2835_SPI_CLOCK_DIVIDER_1 = 1 /*!< 1 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3, same as 0/65536 */ -} bcm2835SPIClockDivider; - -/* Defines for I2C - GPIO register offsets from BCM2835_BSC*_BASE. - Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map -*/ -#define BCM2835_BSC_C 0x0000 /*!< BSC Master Control */ -#define BCM2835_BSC_S 0x0004 /*!< BSC Master Status */ -#define BCM2835_BSC_DLEN 0x0008 /*!< BSC Master Data Length */ -#define BCM2835_BSC_A 0x000c /*!< BSC Master Slave Address */ -#define BCM2835_BSC_FIFO 0x0010 /*!< BSC Master Data FIFO */ -#define BCM2835_BSC_DIV 0x0014 /*!< BSC Master Clock Divider */ -#define BCM2835_BSC_DEL 0x0018 /*!< BSC Master Data Delay */ -#define BCM2835_BSC_CLKT 0x001c /*!< BSC Master Clock Stretch Timeout */ - -/* Register masks for BSC_C */ -#define BCM2835_BSC_C_I2CEN 0x00008000 /*!< I2C Enable, 0 = disabled, 1 = enabled */ -#define BCM2835_BSC_C_INTR 0x00000400 /*!< Interrupt on RX */ -#define BCM2835_BSC_C_INTT 0x00000200 /*!< Interrupt on TX */ -#define BCM2835_BSC_C_INTD 0x00000100 /*!< Interrupt on DONE */ -#define BCM2835_BSC_C_ST 0x00000080 /*!< Start transfer, 1 = Start a new transfer */ -#define BCM2835_BSC_C_CLEAR_1 0x00000020 /*!< Clear FIFO Clear */ -#define BCM2835_BSC_C_CLEAR_2 0x00000010 /*!< Clear FIFO Clear */ -#define BCM2835_BSC_C_READ 0x00000001 /*!< Read transfer */ - -/* Register masks for BSC_S */ -#define BCM2835_BSC_S_CLKT 0x00000200 /*!< Clock stretch timeout */ -#define BCM2835_BSC_S_ERR 0x00000100 /*!< ACK error */ -#define BCM2835_BSC_S_RXF 0x00000080 /*!< RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full */ -#define BCM2835_BSC_S_TXE 0x00000040 /*!< TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full */ -#define BCM2835_BSC_S_RXD 0x00000020 /*!< RXD FIFO contains data */ -#define BCM2835_BSC_S_TXD 0x00000010 /*!< TXD FIFO can accept data */ -#define BCM2835_BSC_S_RXR 0x00000008 /*!< RXR FIFO needs reading (full) */ -#define BCM2835_BSC_S_TXW 0x00000004 /*!< TXW FIFO needs writing (full) */ -#define BCM2835_BSC_S_DONE 0x00000002 /*!< Transfer DONE */ -#define BCM2835_BSC_S_TA 0x00000001 /*!< Transfer Active */ - -#define BCM2835_BSC_FIFO_SIZE 16 /*!< BSC FIFO size */ - -/*! \brief bcm2835I2CClockDivider - Specifies the divider used to generate the I2C clock from the system clock. - Clock divided is based on nominal base clock rate of 250MHz -*/ -typedef enum -{ - BCM2835_I2C_CLOCK_DIVIDER_2500 = 2500, /*!< 2500 = 10us = 100 kHz */ - BCM2835_I2C_CLOCK_DIVIDER_626 = 626, /*!< 622 = 2.504us = 399.3610 kHz */ - BCM2835_I2C_CLOCK_DIVIDER_150 = 150, /*!< 150 = 60ns = 1.666 MHz (default at reset) */ - BCM2835_I2C_CLOCK_DIVIDER_148 = 148 /*!< 148 = 59ns = 1.689 MHz */ -} bcm2835I2CClockDivider; - -/*! \brief bcm2835I2CReasonCodes - Specifies the reason codes for the bcm2835_i2c_write and bcm2835_i2c_read functions. -*/ -typedef enum -{ - BCM2835_I2C_REASON_OK = 0x00, /*!< Success */ - BCM2835_I2C_REASON_ERROR_NACK = 0x01, /*!< Received a NACK */ - BCM2835_I2C_REASON_ERROR_CLKT = 0x02, /*!< Received Clock Stretch Timeout */ - BCM2835_I2C_REASON_ERROR_DATA = 0x04 /*!< Not all data is sent / received */ -} bcm2835I2CReasonCodes; - -/* Defines for ST - GPIO register offsets from BCM2835_ST_BASE. - Offsets into the ST Peripheral block in bytes per 12.1 System Timer Registers - The System Timer peripheral provides four 32-bit timer channels and a single 64-bit free running counter. - BCM2835_ST_CLO is the System Timer Counter Lower bits register. - The system timer free-running counter lower register is a read-only register that returns the current value - of the lower 32-bits of the free running counter. - BCM2835_ST_CHI is the System Timer Counter Upper bits register. - The system timer free-running counter upper register is a read-only register that returns the current value - of the upper 32-bits of the free running counter. -*/ -#define BCM2835_ST_CS 0x0000 /*!< System Timer Control/Status */ -#define BCM2835_ST_CLO 0x0004 /*!< System Timer Counter Lower 32 bits */ -#define BCM2835_ST_CHI 0x0008 /*!< System Timer Counter Upper 32 bits */ - -/*! @} */ - - -/* Defines for PWM, word offsets (ie 4 byte multiples) */ -#define BCM2835_PWM_CONTROL 0 -#define BCM2835_PWM_STATUS 1 -#define BCM2835_PWM_DMAC 2 -#define BCM2835_PWM0_RANGE 4 -#define BCM2835_PWM0_DATA 5 -#define BCM2835_PWM_FIF1 6 -#define BCM2835_PWM1_RANGE 8 -#define BCM2835_PWM1_DATA 9 - -/* Defines for PWM Clock, word offsets (ie 4 byte multiples) */ -#define BCM2835_PWMCLK_CNTL 40 -#define BCM2835_PWMCLK_DIV 41 -#define BCM2835_PWM_PASSWRD (0x5A << 24) /*!< Password to enable setting PWM clock */ - -#define BCM2835_PWM1_MS_MODE 0x8000 /*!< Run in Mark/Space mode */ -#define BCM2835_PWM1_USEFIFO 0x2000 /*!< Data from FIFO */ -#define BCM2835_PWM1_REVPOLAR 0x1000 /*!< Reverse polarity */ -#define BCM2835_PWM1_OFFSTATE 0x0800 /*!< Ouput Off state */ -#define BCM2835_PWM1_REPEATFF 0x0400 /*!< Repeat last value if FIFO empty */ -#define BCM2835_PWM1_SERIAL 0x0200 /*!< Run in serial mode */ -#define BCM2835_PWM1_ENABLE 0x0100 /*!< Channel Enable */ - -#define BCM2835_PWM0_MS_MODE 0x0080 /*!< Run in Mark/Space mode */ -#define BCM2835_PWM_CLEAR_FIFO 0x0040 /*!< Clear FIFO */ -#define BCM2835_PWM0_USEFIFO 0x0020 /*!< Data from FIFO */ -#define BCM2835_PWM0_REVPOLAR 0x0010 /*!< Reverse polarity */ -#define BCM2835_PWM0_OFFSTATE 0x0008 /*!< Ouput Off state */ -#define BCM2835_PWM0_REPEATFF 0x0004 /*!< Repeat last value if FIFO empty */ -#define BCM2835_PWM0_SERIAL 0x0002 /*!< Run in serial mode */ -#define BCM2835_PWM0_ENABLE 0x0001 /*!< Channel Enable */ - -/*! \brief bcm2835PWMClockDivider - Specifies the divider used to generate the PWM clock from the system clock. - Figures below give the divider, clock period and clock frequency. - Clock divided is based on nominal PWM base clock rate of 19.2MHz - The frequencies shown for each divider have been confirmed by measurement -*/ -typedef enum -{ - BCM2835_PWM_CLOCK_DIVIDER_2048 = 2048, /*!< 2048 = 9.375kHz */ - BCM2835_PWM_CLOCK_DIVIDER_1024 = 1024, /*!< 1024 = 18.75kHz */ - BCM2835_PWM_CLOCK_DIVIDER_512 = 512, /*!< 512 = 37.5kHz */ - BCM2835_PWM_CLOCK_DIVIDER_256 = 256, /*!< 256 = 75kHz */ - BCM2835_PWM_CLOCK_DIVIDER_128 = 128, /*!< 128 = 150kHz */ - BCM2835_PWM_CLOCK_DIVIDER_64 = 64, /*!< 64 = 300kHz */ - BCM2835_PWM_CLOCK_DIVIDER_32 = 32, /*!< 32 = 600.0kHz */ - BCM2835_PWM_CLOCK_DIVIDER_16 = 16, /*!< 16 = 1.2MHz */ - BCM2835_PWM_CLOCK_DIVIDER_8 = 8, /*!< 8 = 2.4MHz */ - BCM2835_PWM_CLOCK_DIVIDER_4 = 4, /*!< 4 = 4.8MHz */ - BCM2835_PWM_CLOCK_DIVIDER_2 = 2, /*!< 2 = 9.6MHz, fastest you can get */ - BCM2835_PWM_CLOCK_DIVIDER_1 = 1 /*!< 1 = 4.6875kHz, same as divider 4096 */ -} bcm2835PWMClockDivider; - -/* Historical name compatibility */ -#ifndef BCM2835_NO_DELAY_COMPATIBILITY -#define delay(x) bcm2835_delay(x) -#define delayMicroseconds(x) bcm2835_delayMicroseconds(x) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - /*! \defgroup init Library initialisation and management - These functions allow you to intialise and control the bcm2835 library - @{ - */ - - /*! Initialise the library by opening /dev/mem (if you are root) - or /dev/gpiomem (if you are not) - and getting pointers to the - internal memory for BCM 2835 device registers. You must call this (successfully) - before calling any other - functions in this library (except bcm2835_set_debug). - If bcm2835_init() fails by returning 0, - calling any other function may result in crashes or other failures. - If bcm2835_init() succeeds but you are not running as root, then only gpio operations - are permitted, and calling any other functions may result in crashes or other failures. . - Prints messages to stderr in case of errors. - \return 1 if successful else 0 - */ - extern int bcm2835_init(void); - - /*! Close the library, deallocating any allocated memory and closing /dev/mem - \return 1 if successful else 0 - */ - extern int bcm2835_close(void); - - /*! Sets the debug level of the library. - A value of 1 prevents mapping to /dev/mem, and makes the library print out - what it would do, rather than accessing the GPIO registers. - A value of 0, the default, causes normal operation. - Call this before calling bcm2835_init(); - \param[in] debug The new debug level. 1 means debug - */ - extern void bcm2835_set_debug(uint8_t debug); - - /*! Returns the version number of the library, same as BCM2835_VERSION - \return the current library version number - */ - extern unsigned int bcm2835_version(void); - - /*! @} */ - - /*! \defgroup lowlevel Low level register access - These functions provide low level register access, and should not generally - need to be used - - @{ - */ - - /*! Gets the base of a register - \param[in] regbase You can use one of the common values BCM2835_REGBASE_* - in \ref bcm2835RegisterBase - \return the register base - \sa Physical Addresses - */ - extern uint32_t* bcm2835_regbase(uint8_t regbase); - - /*! Reads 32 bit value from a peripheral address WITH a memory barrier before and after each read. - This is safe, but slow. The MB before protects this read from any in-flight reads that didn't - use a MB. The MB after protects subsequent reads from another peripheral. - - \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. - \return the value read from the 32 bit register - \sa Physical Addresses - */ - extern uint32_t bcm2835_peri_read(volatile uint32_t* paddr); - - /*! Reads 32 bit value from a peripheral address WITHOUT the read barriers - You should only use this when: - o your code has previously called bcm2835_peri_read() for a register - within the same peripheral, and no read or write to another peripheral has occurred since. - o your code has called bcm2835_memory_barrier() since the last access to ANOTHER peripheral. - - \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. - \return the value read from the 32 bit register - \sa Physical Addresses - */ - extern uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr); - - - /*! Writes 32 bit value from a peripheral address WITH a memory barrier before and after each write - This is safe, but slow. The MB before ensures that any in-flight write to another peripheral - completes before this write is issued. The MB after ensures that subsequent reads and writes - to another peripheral will see the effect of this write. - - This is a tricky optimization; if you aren't sure, use the barrier version. - - \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. - \param[in] value The 32 bit value to write - \sa Physical Addresses - */ - extern void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value); - - /*! Writes 32 bit value from a peripheral address without the write barrier - You should only use this when: - o your code has previously called bcm2835_peri_write() for a register - within the same peripheral, and no other peripheral access has occurred since. - o your code has called bcm2835_memory_barrier() since the last access to ANOTHER peripheral. - - This is a tricky optimization; if you aren't sure, use the barrier version. - - \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. - \param[in] value The 32 bit value to write - \sa Physical Addresses - */ - extern void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value); - - /*! Alters a number of bits in a 32 peripheral regsiter. - It reads the current valu and then alters the bits defines as 1 in mask, - according to the bit value in value. - All other bits that are 0 in the mask are unaffected. - Use this to alter a subset of the bits in a register. - Memory barriers are used. Note that this is not atomic; an interrupt - routine can cause unexpected results. - \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. - \param[in] value The 32 bit value to write, masked in by mask. - \param[in] mask Bitmask that defines the bits that will be altered in the register. - \sa Physical Addresses - */ - extern void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask); - /*! @} end of lowlevel */ - - /*! \defgroup gpio GPIO register access - These functions allow you to control the GPIO interface. You can set the - function of each GPIO pin, read the input state and set the output state. - @{ - */ - - /*! Sets the Function Select register for the given pin, which configures - the pin as Input, Output or one of the 6 alternate functions. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - \param[in] mode Mode to set the pin to, one of BCM2835_GPIO_FSEL_* from \ref bcm2835FunctionSelect - */ - extern void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode); - - /*! Sets the specified pin output to - HIGH. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - \sa bcm2835_gpio_write() - */ - extern void bcm2835_gpio_set(uint8_t pin); - - /*! Sets the specified pin output to - LOW. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - \sa bcm2835_gpio_write() - */ - extern void bcm2835_gpio_clr(uint8_t pin); - - /*! Sets any of the first 32 GPIO output pins specified in the mask to - HIGH. - \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) - \sa bcm2835_gpio_write_multi() - */ - extern void bcm2835_gpio_set_multi(uint32_t mask); - - /*! Sets any of the first 32 GPIO output pins specified in the mask to - LOW. - \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) - \sa bcm2835_gpio_write_multi() - */ - extern void bcm2835_gpio_clr_multi(uint32_t mask); - - /*! Reads the current level on the specified - pin and returns either HIGH or LOW. Works whether or not the pin - is an input or an output. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - \return the current level either HIGH or LOW - */ - extern uint8_t bcm2835_gpio_lev(uint8_t pin); - - /*! Event Detect Status. - Tests whether the specified pin has detected a level or edge - as requested by bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen(), - bcm2835_gpio_len(), bcm2835_gpio_aren(), bcm2835_gpio_afen(). - Clear the flag for a given pin by calling bcm2835_gpio_set_eds(pin); - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - \return HIGH if the event detect status for the given pin is true. - */ - extern uint8_t bcm2835_gpio_eds(uint8_t pin); - - /*! Same as bcm2835_gpio_eds() but checks if any of the pins specified in - the mask have detected a level or edge. - \param[in] mask Mask of pins to check. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) - \return Mask of pins HIGH if the event detect status for the given pin is true. - */ - extern uint32_t bcm2835_gpio_eds_multi(uint32_t mask); - - /*! Sets the Event Detect Status register for a given pin to 1, - which has the effect of clearing the flag. Use this afer seeing - an Event Detect Status on the pin. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_set_eds(uint8_t pin); - - /*! Same as bcm2835_gpio_set_eds() but clears the flag for any pin which - is set in the mask. - \param[in] mask Mask of pins to clear. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) - */ - extern void bcm2835_gpio_set_eds_multi(uint32_t mask); - - /*! Enable Rising Edge Detect Enable for the specified pin. - When a rising edge is detected, sets the appropriate pin in Event Detect Status. - The GPRENn registers use - synchronous edge detection. This means the input signal is sampled using the - system clock and then it is looking for a ?011? pattern on the sampled signal. This - has the effect of suppressing glitches. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_ren(uint8_t pin); - - /*! Disable Rising Edge Detect Enable for the specified pin. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_clr_ren(uint8_t pin); - - /*! Enable Falling Edge Detect Enable for the specified pin. - When a falling edge is detected, sets the appropriate pin in Event Detect Status. - The GPRENn registers use - synchronous edge detection. This means the input signal is sampled using the - system clock and then it is looking for a ?100? pattern on the sampled signal. This - has the effect of suppressing glitches. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_fen(uint8_t pin); - - /*! Disable Falling Edge Detect Enable for the specified pin. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_clr_fen(uint8_t pin); - - /*! Enable High Detect Enable for the specified pin. - When a HIGH level is detected on the pin, sets the appropriate pin in Event Detect Status. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_hen(uint8_t pin); - - /*! Disable High Detect Enable for the specified pin. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_clr_hen(uint8_t pin); - - /*! Enable Low Detect Enable for the specified pin. - When a LOW level is detected on the pin, sets the appropriate pin in Event Detect Status. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_len(uint8_t pin); - - /*! Disable Low Detect Enable for the specified pin. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_clr_len(uint8_t pin); - - /*! Enable Asynchronous Rising Edge Detect Enable for the specified pin. - When a rising edge is detected, sets the appropriate pin in Event Detect Status. - Asynchronous means the incoming signal is not sampled by the system clock. As such - rising edges of very short duration can be detected. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_aren(uint8_t pin); - - /*! Disable Asynchronous Rising Edge Detect Enable for the specified pin. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_clr_aren(uint8_t pin); - - /*! Enable Asynchronous Falling Edge Detect Enable for the specified pin. - When a falling edge is detected, sets the appropriate pin in Event Detect Status. - Asynchronous means the incoming signal is not sampled by the system clock. As such - falling edges of very short duration can be detected. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_afen(uint8_t pin); - - /*! Disable Asynchronous Falling Edge Detect Enable for the specified pin. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - extern void bcm2835_gpio_clr_afen(uint8_t pin); - - /*! Sets the Pull-up/down register for the given pin. This is - used with bcm2835_gpio_pudclk() to set the Pull-up/down resistor for the given pin. - However, it is usually more convenient to use bcm2835_gpio_set_pud(). - \param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* from bcm2835PUDControl - On the RPI 4, although this function and bcm2835_gpio_pudclk() are supported for backward - compatibility, new code should always use bcm2835_gpio_set_pud(). - \sa bcm2835_gpio_set_pud() - */ - extern void bcm2835_gpio_pud(uint8_t pud); - - /*! Clocks the Pull-up/down value set earlier by bcm2835_gpio_pud() into the pin. - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - \param[in] on HIGH to clock the value from bcm2835_gpio_pud() into the pin. - LOW to remove the clock. - - On the RPI 4, although this function and bcm2835_gpio_pud() are supported for backward - compatibility, new code should always use bcm2835_gpio_set_pud(). - - \sa bcm2835_gpio_set_pud() - */ - extern void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on); - - /*! Reads and returns the Pad Control for the given GPIO group. - Caution: requires root access. - \param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_* - \return Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup - */ - extern uint32_t bcm2835_gpio_pad(uint8_t group); - - /*! Sets the Pad Control for the given GPIO group. - Caution: requires root access. - \param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_* - \param[in] control Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup. Note - that it is not necessary to include BCM2835_PAD_PASSWRD in the mask as this - is automatically included. - */ - extern void bcm2835_gpio_set_pad(uint8_t group, uint32_t control); - - /*! Delays for the specified number of milliseconds. - Uses nanosleep(), and therefore does not use CPU until the time is up. - However, you are at the mercy of nanosleep(). From the manual for nanosleep(): - If the interval specified in req is not an exact multiple of the granularity - underlying clock (see time(7)), then the interval will be - rounded up to the next multiple. Furthermore, after the sleep completes, - there may still be a delay before the CPU becomes free to once - again execute the calling thread. - \param[in] millis Delay in milliseconds - */ - extern void bcm2835_delay (unsigned int millis); - - /*! Delays for the specified number of microseconds. - Uses a combination of nanosleep() and a busy wait loop on the BCM2835 system timers, - However, you are at the mercy of nanosleep(). From the manual for nanosleep(): - If the interval specified in req is not an exact multiple of the granularity - underlying clock (see time(7)), then the interval will be - rounded up to the next multiple. Furthermore, after the sleep completes, - there may still be a delay before the CPU becomes free to once - again execute the calling thread. - For times less than about 450 microseconds, uses a busy wait on the System Timer. - It is reported that a delay of 0 microseconds on RaspberryPi will in fact - result in a delay of about 80 microseconds. Your mileage may vary. - \param[in] micros Delay in microseconds - */ - extern void bcm2835_delayMicroseconds (uint64_t micros); - - /*! Sets the output state of the specified pin - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - \param[in] on HIGH sets the output to HIGH and LOW to LOW. - */ - extern void bcm2835_gpio_write(uint8_t pin, uint8_t on); - - /*! Sets any of the first 32 GPIO output pins specified in the mask to the state given by on - \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) - \param[in] on HIGH sets the output to HIGH and LOW to LOW. - */ - extern void bcm2835_gpio_write_multi(uint32_t mask, uint8_t on); - - /*! Sets the first 32 GPIO output pins specified in the mask to the value given by value - \param[in] value values required for each bit masked in by mask, eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) - \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) - */ - extern void bcm2835_gpio_write_mask(uint32_t value, uint32_t mask); - - /*! Sets the Pull-up/down mode for the specified pin. This is more convenient than - clocking the mode in with bcm2835_gpio_pud() and bcm2835_gpio_pudclk(). - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - \param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* from bcm2835PUDControl - */ - extern void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud); - - /*! On the BCM2711 based RPI 4, gets the current Pull-up/down mode for the specified pin. - Returns one of BCM2835_GPIO_PUD_* from bcm2835PUDControl. - On earlier RPI versions not based on the BCM2711, returns BCM2835_GPIO_PUD_ERROR - \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. - */ - - extern uint8_t bcm2835_gpio_get_pud(uint8_t pin); - - /*! @} */ - - /*! \defgroup spi SPI access - These functions let you use SPI0 (Serial Peripheral Interface) to - interface with an external SPI device. - @{ - */ - - /*! Start SPI operations. - Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1) - to alternate function ALT0, which enables those pins for SPI interface. - You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to - their default functions. - \sa bcm2835_spi_end() - \return 1 if successful, 0 otherwise (perhaps because you are not running as root) - */ - extern int bcm2835_spi_begin(void); - - /*! End SPI operations. - SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1) - are returned to their default INPUT behaviour. - */ - extern void bcm2835_spi_end(void); - - /*! Sets the SPI bit order - Set the bit order to be used for transmit and receive. The bcm2835 SPI0 only supports BCM2835_SPI_BIT_ORDER_MSB, - so if you select BCM2835_SPI_BIT_ORDER_LSB, the bytes will be reversed in software. - The library defaults to BCM2835_SPI_BIT_ORDER_MSB. - \param[in] order The desired bit order, one of BCM2835_SPI_BIT_ORDER_*, - see \ref bcm2835SPIBitOrder - */ - extern void bcm2835_spi_setBitOrder(uint8_t order); - - /*! Sets the SPI clock divider and therefore the - SPI clock speed. - \param[in] divider The desired SPI clock divider, one of BCM2835_SPI_CLOCK_DIVIDER_*, - see \ref bcm2835SPIClockDivider - */ - extern void bcm2835_spi_setClockDivider(uint16_t divider); - - /*! Sets the SPI clock divider by converting the speed parameter to - the equivalent SPI clock divider. ( see \sa bcm2835_spi_setClockDivider) - \param[in] speed_hz The desired SPI clock speed in Hz - */ - extern void bcm2835_spi_set_speed_hz(uint32_t speed_hz); - - /*! Sets the SPI data mode - Sets the clock polariy and phase - \param[in] mode The desired data mode, one of BCM2835_SPI_MODE*, - see \ref bcm2835SPIMode - */ - extern void bcm2835_spi_setDataMode(uint8_t mode); - - /*! Sets the chip select pin(s) - When an bcm2835_spi_transfer() is made, the selected pin(s) will be asserted during the - transfer. - \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave. - One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect - */ - extern void bcm2835_spi_chipSelect(uint8_t cs); - - /*! Sets the chip select pin polarity for a given pin - When an bcm2835_spi_transfer() occurs, the currently selected chip select pin(s) - will be asserted to the - value given by active. When transfers are not happening, the chip select pin(s) - return to the complement (inactive) value. - \param[in] cs The chip select pin to affect - \param[in] active Whether the chip select pin is to be active HIGH - */ - extern void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active); - - /*! Transfers one byte to and from the currently selected SPI slave. - Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect) - during the transfer. - Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO. - Returns the read data byte from the slave. - Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual - \param[in] value The 8 bit data byte to write to MOSI - \return The 8 bit byte simultaneously read from MISO - \sa bcm2835_spi_transfern() - */ - extern uint8_t bcm2835_spi_transfer(uint8_t value); - - /*! Transfers any number of bytes to and from the currently selected SPI slave. - Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect) - during the transfer. - Clocks the len 8 bit bytes out on MOSI, and simultaneously clocks in data from MISO. - The data read read from the slave is placed into rbuf. rbuf must be at least len bytes long - Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual - \param[in] tbuf Buffer of bytes to send. - \param[out] rbuf Received bytes will by put in this buffer - \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received - \sa bcm2835_spi_transfer() - */ - extern void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len); - - /*! Transfers any number of bytes to and from the currently selected SPI slave - using bcm2835_spi_transfernb. - The returned data from the slave replaces the transmitted data in the buffer. - \param[in,out] buf Buffer of bytes to send. Received bytes will replace the contents - \param[in] len Number of bytes int eh buffer, and the number of bytes to send/received - \sa bcm2835_spi_transfer() - */ - extern void bcm2835_spi_transfern(char* buf, uint32_t len); - - /*! Transfers any number of bytes to the currently selected SPI slave. - Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect) - during the transfer. - \param[in] buf Buffer of bytes to send. - \param[in] len Number of bytes in the buf buffer, and the number of bytes to send - */ - extern void bcm2835_spi_writenb(const char* buf, uint32_t len); - - /*! Transfers half-word to the currently selected SPI slave. - Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect) - during the transfer. - Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO. - Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual - \param[in] data The 8 bit data byte to write to MOSI - \sa bcm2835_spi_writenb() - */ - extern void bcm2835_spi_write(uint16_t data); - - /*! Start AUX SPI operations. - Forces RPi AUX SPI pins P1-38 (MOSI), P1-38 (MISO), P1-40 (CLK) and P1-36 (CE2) - to alternate function ALT4, which enables those pins for SPI interface. - \return 1 if successful, 0 otherwise (perhaps because you are not running as root) - */ - extern int bcm2835_aux_spi_begin(void); - - /*! End AUX SPI operations. - SPI1 pins P1-38 (MOSI), P1-38 (MISO), P1-40 (CLK) and P1-36 (CE2) - are returned to their default INPUT behaviour. - */ - extern void bcm2835_aux_spi_end(void); - - /*! Sets the AUX SPI clock divider and therefore the AUX SPI clock speed. - \param[in] divider The desired AUX SPI clock divider. - */ - extern void bcm2835_aux_spi_setClockDivider(uint16_t divider); - - /*! - * Calculates the input for \sa bcm2835_aux_spi_setClockDivider - * @param speed_hz A value between \sa BCM2835_AUX_SPI_CLOCK_MIN and \sa BCM2835_AUX_SPI_CLOCK_MAX - * @return Input for \sa bcm2835_aux_spi_setClockDivider - */ - extern uint16_t bcm2835_aux_spi_CalcClockDivider(uint32_t speed_hz); - - /*! Transfers half-word to the AUX SPI slave. - Asserts the currently selected CS pins during the transfer. - \param[in] data The 8 bit data byte to write to MOSI - \return The 16 bit byte simultaneously read from MISO - \sa bcm2835_spi_transfern() - */ - extern void bcm2835_aux_spi_write(uint16_t data); - - /*! Transfers any number of bytes to the AUX SPI slave. - Asserts the CE2 pin during the transfer. - \param[in] buf Buffer of bytes to send. - \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send - */ - extern void bcm2835_aux_spi_writenb(const char *buf, uint32_t len); - - /*! Transfers any number of bytes to and from the AUX SPI slave - using bcm2835_aux_spi_transfernb. - The returned data from the slave replaces the transmitted data in the buffer. - \param[in,out] buf Buffer of bytes to send. Received bytes will replace the contents - \param[in] len Number of bytes in the buffer, and the number of bytes to send/received - \sa bcm2835_aux_spi_transfer() - */ - extern void bcm2835_aux_spi_transfern(char *buf, uint32_t len); - - /*! Transfers any number of bytes to and from the AUX SPI slave. - Asserts the CE2 pin during the transfer. - Clocks the len 8 bit bytes out on MOSI, and simultaneously clocks in data from MISO. - The data read read from the slave is placed into rbuf. rbuf must be at least len bytes long - \param[in] tbuf Buffer of bytes to send. - \param[out] rbuf Received bytes will by put in this buffer - \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received - */ - extern void bcm2835_aux_spi_transfernb(const char *tbuf, char *rbuf, uint32_t len); - - /*! Transfers one byte to and from the AUX SPI slave. - Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO. - Returns the read data byte from the slave. - \param[in] value The 8 bit data byte to write to MOSI - \return The 8 bit byte simultaneously read from MISO - \sa bcm2835_aux_spi_transfern() - */ - extern uint8_t bcm2835_aux_spi_transfer(uint8_t value); - - /*! @} */ - - /*! \defgroup i2c I2C access - These functions let you use I2C (The Broadcom Serial Control bus with the Philips - I2C bus/interface version 2.1 January 2000.) to interface with an external I2C device. - @{ - */ - - /*! Start I2C operations. - Forces RPi I2C pins P1-03 (SDA) and P1-05 (SCL) - to alternate function ALT0, which enables those pins for I2C interface. - You should call bcm2835_i2c_end() when all I2C functions are complete to return the pins to - their default functions - \return 1 if successful, 0 otherwise (perhaps because you are not running as root) - \sa bcm2835_i2c_end() - */ - extern int bcm2835_i2c_begin(void); - - /*! End I2C operations. - I2C pins P1-03 (SDA) and P1-05 (SCL) - are returned to their default INPUT behaviour. - */ - extern void bcm2835_i2c_end(void); - - /*! Sets the I2C slave address. - \param[in] addr The I2C slave address. - */ - extern void bcm2835_i2c_setSlaveAddress(uint8_t addr); - - /*! Sets the I2C clock divider and therefore the I2C clock speed. - \param[in] divider The desired I2C clock divider, one of BCM2835_I2C_CLOCK_DIVIDER_*, - see \ref bcm2835I2CClockDivider - */ - extern void bcm2835_i2c_setClockDivider(uint16_t divider); - - /*! Sets the I2C clock divider by converting the baudrate parameter to - the equivalent I2C clock divider. ( see \sa bcm2835_i2c_setClockDivider) - For the I2C standard 100khz you would set baudrate to 100000 - The use of baudrate corresponds to its use in the I2C kernel device - driver. (Of course, bcm2835 has nothing to do with the kernel driver) - */ - extern void bcm2835_i2c_set_baudrate(uint32_t baudrate); - - /*! Transfers any number of bytes to the currently selected I2C slave. - (as previously set by \sa bcm2835_i2c_setSlaveAddress) - \param[in] buf Buffer of bytes to send. - \param[in] len Number of bytes in the buf buffer, and the number of bytes to send. - \return reason see \ref bcm2835I2CReasonCodes - */ - extern uint8_t bcm2835_i2c_write(const char * buf, uint32_t len); - - /*! Transfers any number of bytes from the currently selected I2C slave. - (as previously set by \sa bcm2835_i2c_setSlaveAddress) - \param[in] buf Buffer of bytes to receive. - \param[in] len Number of bytes in the buf buffer, and the number of bytes to received. - \return reason see \ref bcm2835I2CReasonCodes - */ - extern uint8_t bcm2835_i2c_read(char* buf, uint32_t len); - - /*! Allows reading from I2C slaves that require a repeated start (without any prior stop) - to read after the required slave register has been set. For example, the popular - MPL3115A2 pressure and temperature sensor. Note that your device must support or - require this mode. If your device does not require this mode then the standard - combined: - \sa bcm2835_i2c_write - \sa bcm2835_i2c_read - are a better choice. - Will read from the slave previously set by \sa bcm2835_i2c_setSlaveAddress - \param[in] regaddr Buffer containing the slave register you wish to read from. - \param[in] buf Buffer of bytes to receive. - \param[in] len Number of bytes in the buf buffer, and the number of bytes to received. - \return reason see \ref bcm2835I2CReasonCodes - */ - extern uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len); - - /*! Allows sending an arbitrary number of bytes to I2C slaves before issuing a repeated - start (with no prior stop) and reading a response. - Necessary for devices that require such behavior, such as the MLX90620. - Will write to and read from the slave previously set by \sa bcm2835_i2c_setSlaveAddress - \param[in] cmds Buffer containing the bytes to send before the repeated start condition. - \param[in] cmds_len Number of bytes to send from cmds buffer - \param[in] buf Buffer of bytes to receive. - \param[in] buf_len Number of bytes to receive in the buf buffer. - \return reason see \ref bcm2835I2CReasonCodes - */ - extern uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint32_t buf_len); - - /*! @} */ - - /*! \defgroup st System Timer access - Allows access to and delays using the System Timer Counter. - @{ - */ - - /*! Read the System Timer Counter register. - \return the value read from the System Timer Counter Lower 32 bits register - */ - extern uint64_t bcm2835_st_read(void); - - /*! Delays for the specified number of microseconds with offset. - \param[in] offset_micros Offset in microseconds - \param[in] micros Delay in microseconds - */ - extern void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros); - - /*! @} */ - - /*! \defgroup pwm Pulse Width Modulation - Allows control of 2 independent PWM channels. A limited subset of GPIO pins - can be connected to one of these 2 channels, allowing PWM control of GPIO pins. - You have to set the desired pin into a particular Alt Fun to PWM output. See the PWM - documentation on the Main Page. - @{ - */ - - /*! Sets the PWM clock divisor, - to control the basic PWM pulse widths. - \param[in] divisor Divides the basic 19.2MHz PWM clock. You can use one of the common - values BCM2835_PWM_CLOCK_DIVIDER_* in \ref bcm2835PWMClockDivider - */ - extern void bcm2835_pwm_set_clock(uint32_t divisor); - - /*! Sets the mode of the given PWM channel, - allowing you to control the PWM mode and enable/disable that channel - \param[in] channel The PWM channel. 0 or 1. - \param[in] markspace Set true if you want Mark-Space mode. 0 for Balanced mode. - \param[in] enabled Set true to enable this channel and produce PWM pulses. - */ - extern void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled); - - /*! Sets the maximum range of the PWM output. - The data value can vary between 0 and this range to control PWM output - \param[in] channel The PWM channel. 0 or 1. - \param[in] range The maximum value permitted for DATA. - */ - extern void bcm2835_pwm_set_range(uint8_t channel, uint32_t range); - - /*! Sets the PWM pulse ratio to emit to DATA/RANGE, - where RANGE is set by bcm2835_pwm_set_range(). - \param[in] channel The PWM channel. 0 or 1. - \param[in] data Controls the PWM output ratio as a fraction of the range. - Can vary from 0 to RANGE. - */ - extern void bcm2835_pwm_set_data(uint8_t channel, uint32_t data); - - /*! @} */ -#ifdef __cplusplus -} -#endif - -#endif /* BCM2835_H */ - -/*! @example blink.c - Blinks RPi GPIO pin 11 on and off -*/ - -/*! @example input.c - Reads the state of an RPi input pin -*/ - -/*! @example event.c - Shows how to use event detection on an input pin -*/ - -/*! @example spi.c - Shows how to use SPI interface to transfer a byte to and from an SPI device -*/ - -/*! @example spin.c - Shows how to use SPI interface to transfer a number of bytes to and from an SPI device -*/ - -/*! @example pwm.c - Shows how to use PWM to control GPIO pins -*/ - -/*! @example i2c.c -Command line utility for executing i2c commands with the -Broadcom bcm2835. Contributed by Shahrooz Shahparnia. -*/ - -/*! example gpio.c - Command line utility for executing gpio commands with the - Broadcom bcm2835. Contributed by Shahrooz Shahparnia. -*/ - -/*! example spimem_test.c - Shows how to use the included little library (spiram.c and spiram.h) - to read and write SPI RAM chips such as 23K256-I/P -*/ diff --git a/RF24/utility/RPi/compatibility.cpp b/RF24/utility/RPi/compatibility.cpp deleted file mode 100644 index 7363ec282140764a1cdef3e257bc2e6580ae5bae..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/compatibility.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "compatibility.h" -#include <chrono> - -auto start = std::chrono::steady_clock::now(); - -uint32_t millis(void) -{ - auto end = std::chrono::steady_clock::now(); - - return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); -} diff --git a/RF24/utility/RPi/compatibility.h b/RF24/utility/RPi/compatibility.h deleted file mode 100644 index 58562beaca3d44d6cdcf761f2d909617cc6366dd..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/compatibility.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef RF24_UTILITY_RPI_COMPATIBLITY_H_ -#define RF24_UTILITY_RPI_COMPATIBLITY_H_ - -#include <sys/time.h> -#include <stdint.h> -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif -extern uint32_t millis(void); - -#ifdef __cplusplus -} -#endif - -#endif // RF24_UTILITY_RPI_COMPATIBLITY_H_ diff --git a/RF24/utility/RPi/includes.h b/RF24/utility/RPi/includes.h deleted file mode 100644 index d73f5cf636453a3c649895a9ffc83e3f2034fac5..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/includes.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef RF24_UTILITY_INCLUDES_H_ -#define RF24_UTILITY_INCLUDES_H_ - -#define RF24_RPi - -#include "RPi/bcm2835.h" -#include "RPi/RF24_arch_config.h" -#ifndef RF24_NO_INTERRUPT - #include "RPi/interrupt.h" -#endif - -#endif // RF24_UTILITY_INCLUDES_H_ diff --git a/RF24/utility/RPi/interrupt.cpp b/RF24/utility/RPi/interrupt.cpp deleted file mode 100644 index 31a5f894ec9e118f306e2196633361c4014d9eaf..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/interrupt.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* -Interrupt functions -*/ - -#include "interrupt.h" -#include <pigpio.h> - -int attachInterrupt(int pin, int mode, void (*function)(void)) -{ - gpioInitialise(); - return gpioSetISRFunc(pin, mode, 0, (gpioISRFunc_t)function); -} - -int detachInterrupt(int pin) -{ - return gpioSetISRFunc(pin, 0, 0, NULL); -} - -void rfNoInterrupts() -{ -} - -void rfInterrupts() -{ -} \ No newline at end of file diff --git a/RF24/utility/RPi/interrupt.h b/RF24/utility/RPi/interrupt.h deleted file mode 100644 index f52117b55e418d71c9e2090b33af4208291d7c14..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/interrupt.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Interrupt functions -*/ -#ifndef __RF24_INTERRUPT_H__ -#define __RF24_INTERRUPT_H__ - -#include "RF24_arch_config.h" -#include <pigpio.h> - -#define INT_EDGE_SETUP 0 -#define INT_EDGE_FALLING FALLING_EDGE -#define INT_EDGE_RISING RISING_EDGE -#define INT_EDGE_BOTH EITHER_EDGE - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * attachInterrupt (Original: wiringPiISR): - * Pi Specific. - * Take the details and create an interrupt handler that will do a call- - * back to the user supplied function. - ********************************************************************************* - */ -extern int attachInterrupt(int pin, int mode, void (*function)(void)); - -/* - * detachInterrupt: - * Pi Specific detachInterrupt. - * Will cancel the interrupt thread, close the filehandle and - * setting wiringPi back to 'none' mode. - ********************************************************************************* - */ -extern int detachInterrupt(int pin); - -/* Deprecated, no longer functional -*/ -extern void rfNoInterrupts(); - -/* Deprecated, no longer functional -*/ -extern void rfInterrupts(); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/RF24/utility/RPi/spi.cpp b/RF24/utility/RPi/spi.cpp deleted file mode 100644 index 794931e00266cc49dcb10274911b5ed231d7ce9d..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/spi.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "spi.h" -#include <pthread.h> -#include <unistd.h> -#include <stdexcept> - -static pthread_mutex_t spiMutex = PTHREAD_MUTEX_INITIALIZER; -bool bcmIsInitialized = false; - -SPI::SPI() -{ -} - -void SPI::begin(int busNo, uint32_t spi_speed) -{ - if (!bcmIsInitialized) { - if (!bcm2835_init()) { - return; - } - } - bcmIsInitialized = true; - bcm2835_spi_begin(); -} - -void SPI::beginTransaction(SPISettings settings) -{ - if (geteuid() != 0) { - throw std::runtime_error("Process should run as root"); - } - pthread_mutex_lock(&spiMutex); - setBitOrder(settings.border); - setDataMode(settings.dmode); - setClockDivider(settings.clck); -} - -void SPI::endTransaction() -{ - pthread_mutex_unlock(&spiMutex); -} - -void SPI::setBitOrder(uint8_t bit_order) -{ - bcm2835_spi_setBitOrder(bit_order); -} - -void SPI::setDataMode(uint8_t data_mode) -{ - bcm2835_spi_setDataMode(data_mode); -} - -void SPI::setClockDivider(uint32_t spi_speed) -{ - //bcm2835_spi_setClockDivider(spi_speed); - bcm2835_spi_set_speed_hz(spi_speed); -} - -void SPI::chipSelect(int csn_pin) -{ - bcm2835_spi_chipSelect(csn_pin); - delayMicroseconds(5); -} - -SPI::~SPI() -{ -} diff --git a/RF24/utility/RPi/spi.h b/RF24/utility/RPi/spi.h deleted file mode 100644 index 895ebe4e8e1b70a224c2306db9337715cc17b758..0000000000000000000000000000000000000000 --- a/RF24/utility/RPi/spi.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * TMRh20 2015 - * SPI layer for RF24 <-> BCM2835 - */ -/** - * @file spi.h - * Class declaration for SPI helper files - */ -#ifndef RF24_UTILITY_RPI_SPI_H_ -#define RF24_UTILITY_RPI_SPI_H_ - -#include <stdio.h> -#include "bcm2835.h" -#include "../../RF24_config.h" - -#define SPI_HAS_TRANSACTION -#define MSBFIRST BCM2835_SPI_BIT_ORDER_MSBFIRST -#define SPI_MODE0 BCM2835_SPI_MODE0 -//#define RF24_SPI_SPEED 10000000 //BCM2835_SPI_SPEED_4MHZ - -class SPISettings -{ -public: - SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) - { - init(clock, bitOrder, dataMode); - } - - SPISettings() - { - init(RF24_SPI_SPEED, MSBFIRST, SPI_MODE0); - } - - uint32_t clck; - uint8_t border; - uint8_t dmode; - -private: - void init(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) - { - clck = clock; - border = bitOrder; - dmode = dataMode; - } - - friend class SPIClass; -}; - -class SPI -{ -public: - SPI(); - - virtual ~SPI(); - - inline static uint8_t transfer(uint8_t _data); - - inline static void transfernb(char* tbuf, char* rbuf, uint32_t len); - - inline static void transfern(char* buf, uint32_t len); - - static void begin(int busNo, uint32_t spi_speed = RF24_SPI_SPEED); - - static void end(); - - static void setBitOrder(uint8_t bit_order); - - static void setDataMode(uint8_t data_mode); - - static void setClockDivider(uint32_t spi_speed); - - static void chipSelect(int csn_pin); - - static void beginTransaction(SPISettings settings); - - static void endTransaction(); -}; - -uint8_t SPI::transfer(uint8_t _data) -{ - uint8_t data = bcm2835_spi_transfer(_data); - return data; -} - -void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len) -{ - bcm2835_spi_transfernb(tbuf, rbuf, len); -} - -void SPI::transfern(char* buf, uint32_t len) -{ - transfernb(buf, buf, len); -} - -#endif // RF24_UTILITY_RPI_SPI_H_ diff --git a/RF24/utility/SPIDEV/RF24_arch_config.h b/RF24/utility/SPIDEV/RF24_arch_config.h deleted file mode 100644 index 93eefe313fda960e7348f280693d95c451da8856..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/RF24_arch_config.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - - */ -#ifndef RF24_UTILITY_SPIDEV_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_SPIDEV_RF24_ARCH_CONFIG_H_ - -#define RF24_LINUX - -#include <stddef.h> -#include "spi.h" -#include "gpio.h" -#include "compatibility.h" -#include <stdint.h> -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <sys/time.h> - -//#define RF24_SPI_SPEED RF24_SPIDEV_SPEED - -#define _BV(x) (1 << (x)) -#define _SPI spi - -//#undef SERIAL_DEBUG -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -// Avoid spurious warnings -#if 1 - #if !defined(NATIVE) && defined(ARDUINO) - #undef PROGMEM - #define PROGMEM __attribute__((section(".progmem.data"))) - #undef PSTR - #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0]; })) - #endif -#endif - -typedef uint16_t prog_uint16_t; -#define PSTR(x) (x) -#define printf_P printf -#define strlen_P strlen -#define PROGMEM -#define pgm_read_word(p) (*(const unsigned short*)(p)) -#define PRIPSTR "%s" -#define pgm_read_byte(p) (*(const unsigned char*)(p)) -#define pgm_read_ptr(p) (*(void* const*)(p)) - -// Function, constant map as a result of migrating from Arduino -#define LOW GPIO::OUTPUT_LOW -#define HIGH GPIO::OUTPUT_HIGH -#define INPUT GPIO::DIRECTION_IN -#define OUTPUT GPIO::DIRECTION_OUT -#define digitalWrite(pin, value) GPIO::write(pin, value) -#define pinMode(pin, direction) GPIO::open(pin, direction) -#define delay(milisec) __msleep(milisec) -#define delayMicroseconds(usec) __usleep(usec) -#define millis() __millis() - -#endif // RF24_UTILITY_SPIDEV_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/SPIDEV/compatibility.cpp b/RF24/utility/SPIDEV/compatibility.cpp deleted file mode 100644 index 6b96f65887fdd52b2ade4f7e611bc3cc226b3b5d..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/compatibility.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "compatibility.h" - -long long mtime, seconds, useconds; -//static struct timeval start, end; -//struct timespec start, end; -#include <time.h> -#include <chrono> -/**********************************************************************/ -/** - * This function is added in order to simulate arduino delay() function - * @param milisec - */ -void __msleep(int milisec) -{ - struct timespec req; // = {0}; - req.tv_sec = (time_t)milisec / 1000; - req.tv_nsec = (milisec % 1000) * 1000000L; - //nanosleep(&req, (struct timespec *)NULL); - clock_nanosleep(CLOCK_REALTIME, 0, &req, NULL); -} - -void __usleep(int microsec) -{ - struct timespec req; // = {0}; - req.tv_sec = (time_t)microsec / 1000000; - req.tv_nsec = (microsec / 1000000) * 1000; - //nanosleep(&req, (struct timespec *)NULL); - clock_nanosleep(CLOCK_REALTIME, 0, &req, NULL); -} - -/** - * This function is added in order to simulate arduino millis() function - */ - -bool timerStarted = false; - -void __start_timer() -{ -} - -auto start = std::chrono::steady_clock::now(); - -uint32_t __millis() -{ - auto end = std::chrono::steady_clock::now(); - - return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); -} diff --git a/RF24/utility/SPIDEV/compatibility.h b/RF24/utility/SPIDEV/compatibility.h deleted file mode 100644 index 70153233e44a3c0068246aa4c8f5c9b7665992f2..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/compatibility.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file compatiblity.h - * @author purinda - * - * Created on 24 June 2012, 3:08 PM - * patch for safer monotonic clock & millis() correction for 64bit LDV 2018 - */ - -#ifndef RF24_UTILITY_SPIDEV_COMPATIBLITY_H_ -#define RF24_UTILITY_SPIDEV_COMPATIBLITY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdint.h> // for uintXX_t types -#include <stddef.h> -#include <time.h> -#include <sys/time.h> - -void __msleep(int milisec); - -void __usleep(int milisec); - -void __start_timer(); - -uint32_t __millis(); - -#ifdef __cplusplus -} -#endif - -#endif // RF24_UTILITY_SPIDEV_COMPATIBLITY_H_ diff --git a/RF24/utility/SPIDEV/gpio.cpp b/RF24/utility/SPIDEV/gpio.cpp deleted file mode 100644 index a8986009d3c562658614f40e9d076c58bc269a1c..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/gpio.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * https://github.com/mrshu/GPIOlib - * Copyright (c) 2011, Copyright (c) 2011 mr.Shu - * All rights reserved. - * - * Modified on 24 June 2012, 11:06 AM - * File: gpio.cpp - * Author: purinda (purinda@gmail.com) - * - * Patched for filedescriptor catching and error control by L Diaz 2018 - */ - -#include "gpio.h" -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> - -std::map<int, GPIOfdCache_t> GPIO::cache; - -GPIO::GPIO() -{ -} - -GPIO::~GPIO() -{ -} - -void GPIO::open(int port, int DDR) -{ - FILE* f; - f = fopen("/sys/class/gpio/export", "w"); - if (f == NULL) { - throw GPIOException("can't export GPIO pin .check access rights"); - } - fprintf(f, "%d\n", port); - fclose(f); - - int counter = 0; - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/direction", port); - - while ((f = fopen(file, "w")) == NULL) { //Wait 10 seconds for the file to be accessible if not open on first attempt - sleep(1); - counter++; - if (counter > 10) { - throw GPIOException("can't access /sys/class/gpio/gpio%d/direction GPIO pin. check access rights"); - /*perror("Could not open /sys/class/gpio/gpio%d/direction"); - exit(0); */ - } - } - int l = (DDR == 0) ? fprintf(f, "in\n") : fprintf(f, "out\n"); - if (!(l == 3 || l == 4)) { - fclose(f); - throw GPIOException("can't set direction on GPIO pin. check access rights"); - } - /* - if (DDR == 0) - fprintf(f, "in\n"); - else - printf(f, "out\n"); - */ - fclose(f); - - // Caches the GPIO descriptor; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - int flags = (DDR == 0) ? O_RDONLY : O_WRONLY; - int fd = ::open(file, flags); - if (fd < 0) { - throw GPIOException("Can't open the GPIO"); - } - else { - cache[port] = fd; // cache the fd; - lseek(fd, SEEK_SET, 0); - } -} - -void GPIO::close(int port) -{ - std::map<int, GPIOfdCache_t>::iterator i; - i = cache.find(port); - if (i != cache.end()) { - close(i->second); // close the cached fd - cache.erase(i); // Delete cache entry - } - // Do unexport - FILE* f; - f = fopen("/sys/class/gpio/unexport", "w"); - if (f != NULL) { - fprintf(f, "%d\n", port); - fclose(f); - } -} - -int GPIO::read(int port) -{ - std::map<int, GPIOfdCache_t>::iterator i; - int fd; - i = cache.find(port); - if (i == cache.end()) { // Fallback to open the gpio - GPIO::open(port, GPIO::DIRECTION_IN); - i = cache.find(port); - if (i == cache.end()) { - throw GPIOException("can't access to GPIO"); - } - else { - fd = i->second; - } - } - else { - fd = i->second; - } - - char c; - if (lseek(fd, 0, SEEK_SET) == 0 && ::read(fd, &c, 1) == 1) { - return (c == '0') ? 0 : 1; - } - else { - throw GPIOException("can't access to GPIO"); - } - - /* - FILE *f; - - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - f = fopen(file, "r"); - - int i; - fscanf(f, "%d", &i); - fclose(f); - return i; - */ -} - -void GPIO::write(int port, int value) -{ - std::map<int, GPIOfdCache_t>::iterator i; - int fd; - i = cache.find(port); - if (i == cache.end()) { // Fallback to open the gpio - GPIO::open(port, GPIO::DIRECTION_OUT); - i = cache.find(port); - if (i == cache.end()) { - throw GPIOException("can't access to GPIO"); - } - else { - fd = i->second; - } - } - else { - fd = i->second; - } - - if (lseek(fd, 0, SEEK_SET) != 0) { - throw GPIOException("can't access to GPIO"); - } - int l = (value == 0) ? ::write(fd, "0\n", 2) : ::write(fd, "1\n", 2); - if (l != 2) { - throw GPIOException("can't access to GPIO"); - } - - /* - FILE *f; - - char file[128]; - sprintf(file, "/sys/class/gpio/gpio%d/value", port); - f = fopen(file, "w"); - - if (value == 0) - fprintf(f, "0\n"); - else - fprintf(f, "1\n"); - - fclose(f); - */ -} diff --git a/RF24/utility/SPIDEV/gpio.h b/RF24/utility/SPIDEV/gpio.h deleted file mode 100644 index c802ce6ac708a4ecaecb596aeed8c8cb073caca7..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/gpio.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * https://github.com/mrshu/GPIOlib - * Copyright (c) 2011, Copyright (c) 2011 mr.Shu - * All rights reserved. - * - * Modified on 24 June 2012, 11:06 AM - * @file gpio.h - * Author: purinda (purinda@gmail.com) - * - * Class declaration for GPIO helper files - */ - -#ifndef RF24_UTILITY_SPIDEV_GPIO_H_ -#define RF24_UTILITY_SPIDEV_GPIO_H_ - -#include <cstdio> -#include <map> -#include <stdexcept> - -/** Specific excpetion for SPI errors */ -class GPIOException : public std::runtime_error -{ -public: - explicit GPIOException(const std::string& msg) - : std::runtime_error(msg) - { - } -}; - -typedef int GPIOfdCache_t; - -class GPIO -{ - -public: - static const int DIRECTION_OUT = 1; - static const int DIRECTION_IN = 0; - - static const int OUTPUT_HIGH = 1; - static const int OUTPUT_LOW = 0; - - GPIO(); - - static void open(int port, int DDR); - - static void close(int port); - - static int read(int port); - - static void write(int port, int value); - - virtual ~GPIO(); - -private: - /* fd cache */ - static std::map<int, GPIOfdCache_t> cache; -}; - -#endif // RF24_UTILITY_SPIDEV_GPIO_H_ diff --git a/RF24/utility/SPIDEV/includes.h b/RF24/utility/SPIDEV/includes.h deleted file mode 100644 index fd82fd5d8df407987f34682466d9d3fd58557efd..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/includes.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef RF24_UTILITY_INCLUDES_H_ -#define RF24_UTILITY_INCLUDES_H_ - -#define RF24_SPIDEV - -#include "SPIDEV/RF24_arch_config.h" -#ifndef RF24_NO_INTERRUPT - #include "SPIDEV/interrupt.h" -#endif - -#endif // RF24_UTILITY_INCLUDES_H_ diff --git a/RF24/utility/SPIDEV/interrupt.cpp b/RF24/utility/SPIDEV/interrupt.cpp deleted file mode 100644 index 4893dc51fbcf4c7a0aa3a1cbfc814b13bca65ac0..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/interrupt.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* -Interrupt functions -*/ - -#include "interrupt.h" -#include <pigpio.h> - -int attachInterrupt(int pin, int mode, void (*function)(void)) -{ - gpioInitialise(); - return gpioSetISRFunc(pin, mode, 0, (gpioISRFunc_t)function); -} - -int detachInterrupt(int pin) -{ - return gpioSetISRFunc(pin, 0, 0, NULL); -} - -void rfNoInterrupts() -{ -} - -void rfInterrupts() -{ -} diff --git a/RF24/utility/SPIDEV/interrupt.h b/RF24/utility/SPIDEV/interrupt.h deleted file mode 100644 index f52117b55e418d71c9e2090b33af4208291d7c14..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/interrupt.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Interrupt functions -*/ -#ifndef __RF24_INTERRUPT_H__ -#define __RF24_INTERRUPT_H__ - -#include "RF24_arch_config.h" -#include <pigpio.h> - -#define INT_EDGE_SETUP 0 -#define INT_EDGE_FALLING FALLING_EDGE -#define INT_EDGE_RISING RISING_EDGE -#define INT_EDGE_BOTH EITHER_EDGE - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * attachInterrupt (Original: wiringPiISR): - * Pi Specific. - * Take the details and create an interrupt handler that will do a call- - * back to the user supplied function. - ********************************************************************************* - */ -extern int attachInterrupt(int pin, int mode, void (*function)(void)); - -/* - * detachInterrupt: - * Pi Specific detachInterrupt. - * Will cancel the interrupt thread, close the filehandle and - * setting wiringPi back to 'none' mode. - ********************************************************************************* - */ -extern int detachInterrupt(int pin); - -/* Deprecated, no longer functional -*/ -extern void rfNoInterrupts(); - -/* Deprecated, no longer functional -*/ -extern void rfInterrupts(); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/RF24/utility/SPIDEV/spi.cpp b/RF24/utility/SPIDEV/spi.cpp deleted file mode 100644 index 4fb0113b995c0b4048837dd947b34ae9d23f1afb..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/spi.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @file spi.cpp - * @author Purinda Gunasekara <purinda@gmail.com> - * - * Created on 24 June 2012, 11:00 AM - * - * Patched for exception handling and selectable SPI SPEED by ldiaz 2018. - * - * Inspired from spidev test in linux kernel documentation - * www.kernel.org/doc/Documentation/spi/spidev_test.c - */ - -#include "spi.h" - -#include <fcntl.h> -#include <linux/spi/spidev.h> -#include <memory.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <unistd.h> - -#define RF24_SPIDEV_BITS 8 - -SPI::SPI() - : fd(-1), _spi_speed(RF24_SPI_SPEED) -{ -} - -void SPI::begin(int busNo, uint32_t spi_speed) -{ - - if (this->spiIsInitialized) { - return; - } - - /* set spidev accordingly to busNo like: - * busNo = 23 -> /dev/spidev2.3 - * - * a bit messy but simple - * */ - char device[] = "/dev/spidev0.0"; - device[11] += (busNo / 10) % 10; - device[13] += busNo % 10; - - if (this->fd >= 0) // check whether spi is already open - { - close(this->fd); - this->fd = -1; - } - - this->fd = open(device, O_RDWR); - if (this->fd < 0) { - throw SPIException("can't open device"); - } - /* - { - perror("can't open device"); - abort(); - - }*/ - this->spiIsInitialized = true; - init(spi_speed); -} - -void SPI::init(uint32_t speed) -{ - uint8_t bits = RF24_SPIDEV_BITS; - uint8_t mode = 0; - - int ret; - /* - * spi mode - */ - ret = ioctl(this->fd, SPI_IOC_WR_MODE, &mode); - if (ret == -1) { - throw SPIException("cant set WR spi mode"); - } - /*{ - perror("can't set spi mode"); - abort(); - }*/ - - ret = ioctl(this->fd, SPI_IOC_RD_MODE, &mode); - if (ret == -1) { - throw SPIException("can't set RD spi mode"); - } - /*{ - perror("can't set spi mode"); - abort(); - }*/ - - /* - * bits per word - */ - ret = ioctl(this->fd, SPI_IOC_WR_BITS_PER_WORD, &bits); - if (ret == -1) { - throw SPIException("can't set WR bits per word"); - } - /*{ - perror("can't set bits per word"); - abort(); - }*/ - - ret = ioctl(this->fd, SPI_IOC_RD_BITS_PER_WORD, &bits); - if (ret == -1) { - throw SPIException("can't set RD bits per word"); - } - /*{ - perror("can't set bits per word"); - abort(); - }*/ - /* - * max speed hz - */ - ret = ioctl(this->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); - if (ret == -1) { - throw SPIException("can't WR set max speed hz"); - } - /*{ - perror("can't set max speed hz"); - abort(); - }*/ - - ret = ioctl(this->fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); - if (ret == -1) { - throw SPIException("can't RD set max speed hz"); - } - /*{ - perror("can't set max speed hz"); - abort(); - }*/ - _spi_speed = speed; -} - -uint8_t SPI::transfer(uint8_t tx) -{ - struct spi_ioc_transfer tr; - memset(&tr, 0, sizeof(tr)); - tr.tx_buf = (unsigned long)&tx; - uint8_t rx; - tr.rx_buf = (unsigned long)℞ - tr.len = sizeof(tx); - tr.speed_hz = _spi_speed; //RF24_SPI_SPEED; - tr.delay_usecs = 0; - tr.bits_per_word = RF24_SPIDEV_BITS; - tr.cs_change = 0; - - int ret; - ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr); - if (ret < 1) { - throw SPIException("can't send spi message"); - } - /*{ - perror("can't send spi message"); - abort(); - }*/ - - return rx; -} - -void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len) -{ - struct spi_ioc_transfer tr; - memset(&tr, 0, sizeof(tr)); - tr.tx_buf = (unsigned long)tbuf; - tr.rx_buf = (unsigned long)rbuf; - tr.len = len; - tr.speed_hz = _spi_speed; //RF24_SPI_SPEED; - tr.delay_usecs = 0; - tr.bits_per_word = RF24_SPIDEV_BITS; - tr.cs_change = 0; - - int ret; - ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr); - if (ret < 1) { - throw SPIException("can't send spi message"); - } - /*{ - perror("can't send spi message"); - abort(); - }*/ -} - -void SPI::transfern(char* buf, uint32_t len) -{ - transfernb(buf, buf, len); -} - -SPI::~SPI() -{ - if (this->fd >= 0) { - close(this->fd); - } -} diff --git a/RF24/utility/SPIDEV/spi.h b/RF24/utility/SPIDEV/spi.h deleted file mode 100644 index 35efe2d7be280c3a2a203088552577c39b61f7fb..0000000000000000000000000000000000000000 --- a/RF24/utility/SPIDEV/spi.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file spi.h - * @author Purinda Gunasekara <purinda@gmail.com> - * - * Created on 24 June 2012, 11:00 AM - * - * Class declaration for SPI helper files - */ - -#ifndef RF24_UTILITY_SPIDEV_SPI_H_ -#define RF24_UTILITY_SPIDEV_SPI_H_ - -#include <inttypes.h> -#include <stdexcept> - -#include "../../RF24_config.h" // This is cyclical and should be fixed - -/** Specific excpetion for SPI errors */ -class SPIException : public std::runtime_error -{ -public: - explicit SPIException(const std::string& msg) - : std::runtime_error(msg) - { - } -}; - -class SPI -{ - -public: - SPI(); - - void begin(int busNo, uint32_t spi_speed = RF24_SPI_SPEED); - - uint8_t transfer(uint8_t tx); - - void transfernb(char* tbuf, char* rbuf, uint32_t len); - - void transfern(char* buf, uint32_t len); - - ~SPI(); - -private: - int fd; - uint32_t _spi_speed; - bool spiIsInitialized = false; - void init(uint32_t spi_speed = RF24_SPI_SPEED); -}; - -#endif // RF24_UTILITY_SPIDEV_SPI_H_ diff --git a/RF24/utility/Teensy/RF24_arch_config.h b/RF24/utility/Teensy/RF24_arch_config.h deleted file mode 100644 index 7ca162b45357f58a0420d0c5a8b2a625fd6939fd..0000000000000000000000000000000000000000 --- a/RF24/utility/Teensy/RF24_arch_config.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef RF24_UTILITY_TEENSY_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_TEENSY_RF24_ARCH_CONFIG_H_ -#if ARDUINO < 100 - - #include <WProgram.h> - -#else - #include <Arduino.h> -#endif - -#include <stddef.h> - -#include <stdint.h> -#include <stdio.h> -#include <string.h> - -#include <SPI.h> - -#define _SPI SPIClass -#define RF24_SPI_PTR - -#define printf Serial.printf - -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -#define PRIPSTR "%s" - -#endif // RF24_UTILITY_TEENSY_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/Template/RF24_arch_config.h b/RF24/utility/Template/RF24_arch_config.h deleted file mode 100644 index b6b3012cde995b9200c13c6f1b4c1f210d911fc7..0000000000000000000000000000000000000000 --- a/RF24/utility/Template/RF24_arch_config.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ - -/** - * @file RF24_arch_config.h - * General defines and includes for RF24/Linux - */ - -/** - * Example of RF24_arch_config.h for RF24 portability - * - * @defgroup Porting_General Porting: General - * @{ - */ - -#ifndef RF24_UTILITY_TEMPLATE_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_TEMPLATE_RF24_ARCH_CONFIG_H_ - -#define RF24_LINUX - -#include <stddef.h> -#include "spi.h" -#include "gpio.h" -#include "compatibility.h" -#include <stdint.h> -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <sys/time.h> - -#define _BV(x) (1 << (x)) -#define _SPI spi - -#undef SERIAL_DEBUG -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -// Avoid spurious warnings -#if !defined(NATIVE) && defined(ARDUINO) - #undef PROGMEM - #define PROGMEM __attribute__((section(".progmem.data"))) - #undef PSTR - #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0]; })) -#endif - -typedef uint16_t prog_uint16_t; -#define PSTR(x) (x) -#define printf_P printf -#define strlen_P strlen -#define PROGMEM -#define pgm_read_word(p) (*(const unsigned short*)(p)) -#define PRIPSTR "%s" -#define pgm_read_byte(p) (*(const unsigned char*)(p)) - -// Function, constant map as a result of migrating from Arduino -#define LOW GPIO::OUTPUT_LOW -#define HIGH GPIO::OUTPUT_HIGH -#define INPUT GPIO::DIRECTION_IN -#define OUTPUT GPIO::DIRECTION_OUT -#define digitalWrite(pin, value) GPIO::write(pin, value) -#define pinMode(pin, direction) GPIO::open(pin, direction) -#define delay(milisec) __msleep(milisec) -#define delayMicroseconds(usec) __usleep(usec) -#define millis() __millis() - -/**@}*/ - -#endif // RF24_UTILITY_TEMPLATE_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/Template/compatibility.h b/RF24/utility/Template/compatibility.h deleted file mode 100644 index 1441302e3f92ec67ce5754441ed1c60fd6867a83..0000000000000000000000000000000000000000 --- a/RF24/utility/Template/compatibility.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file compatibility.h - * Class declaration for SPI helper files - */ - -/** - * Example of compatibility.h class declaration for timing functions portability - * - * @defgroup Porting_Timing Porting: Timing - * @{ - */ - -#ifndef RF24_UTILITY_TEMPLATE_COMPATIBLITY_H_ -#define RF24_UTILITY_TEMPLATE_COMPATIBLITY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stddef.h> -#include <time.h> -#include <sys/time.h> - -void __msleep(int milisec); - -void __usleep(int milisec); - -void __start_timer(); - -long __millis(); - -#ifdef __cplusplus -} -#endif - -/**@}*/ - -#endif // RF24_UTILITY_TEMPLATE_COMPATIBLITY_H_ diff --git a/RF24/utility/Template/gpio.h b/RF24/utility/Template/gpio.h deleted file mode 100644 index dd03d5c5c4ca34cc3d4f1054fa90781a5389fe33..0000000000000000000000000000000000000000 --- a/RF24/utility/Template/gpio.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @file gpio.h - * Class declaration for SPI helper files - */ - -/** - * Example of gpio.h class declaration for GPIO portability - * - * @defgroup Porting_GPIO Porting: GPIO - * @{ - */ -#ifndef RF24_UTILITY_TEMPLATE_GPIO_H_ -#define RF24_UTILITY_TEMPLATE_GPIO_H_ - -#include <cstdio> - -#ifndef DOXYGEN_FORCED -// exclude this line from the docs to prevent displaying in the list of classes -class GPIO -#endif -{ - -public: - /* Constants */ - static const int DIRECTION_OUT = 1; - static const int DIRECTION_IN = 0; - - static const int OUTPUT_HIGH = 1; - static const int OUTPUT_LOW = 0; - - GPIO(); - - /** - * Similar to Arduino pinMode(pin,mode); - * @param port - * @param DDR - */ - static void open(int port, int DDR); - - /** - * - * @param port - */ - static void close(int port); - - /** - * Similar to Arduino digitalRead(pin); - * @param port - */ - static int read(int port); - - /** - * Similar to Arduino digitalWrite(pin,state); - * @param port - * @param value - */ - static void write(int port, int value); - -#ifndef DOXYGEN_FORCED - // exclude this line from the docs to prevent warnings docs generators - virtual ~GPIO(); -#endif -}; - -/**@}*/ - -#endif // RF24_UTILITY_TEMPLATE_GPIO_H_ diff --git a/RF24/utility/Template/includes.h b/RF24/utility/Template/includes.h deleted file mode 100644 index 064bfe2a34885ac1d890624c3e4adb64767e58ba..0000000000000000000000000000000000000000 --- a/RF24/utility/Template/includes.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @file includes.h - * Configuration defines for RF24/Linux - */ - -/** - * Example of includes.h for RF24 Linux portability - * - * @defgroup Porting_Includes Porting: Includes - * @{ - */ - -#ifndef RF24_UTILITY_INCLUDES_H_ -#define RF24_UTILITY_INCLUDES_H_ - -/** - * Define a specific platform for this configuration - */ -#define RF24_BBB - -/** - * Load the correct configuration for this platform - */ -#include "BBB/RF24_arch_config.h" - -/**@}*/ - -#endif // RF24_UTILITY_INCLUDES_H_ diff --git a/RF24/utility/Template/spi.h b/RF24/utility/Template/spi.h deleted file mode 100644 index 3f5abada20172f49d3c74c5eca82d94c5cd87c94..0000000000000000000000000000000000000000 --- a/RF24/utility/Template/spi.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file spi.h - * Class declaration for SPI helper files - */ - -/** - * Example of spi.h class declaration for SPI portability - * - * @defgroup Porting_SPI Porting: SPI - * @{ - */ -#ifndef RF24_UTILITY_TEMPLATE_SPI_H_ -#define RF24_UTILITY_TEMPLATE_SPI_H_ - -#include <string> -#include <stdint.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <getopt.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <inttypes.h> -#include <linux/types.h> -#include <linux/spi/spidev.h> - -using namespace std; - -#ifndef DOXYGEN_FORCED -// exclude this line from the docs to prevent displaying in the list of classes -class SPI -#endif -{ - -public: - /** - * SPI constructor - */ - SPI(); - - /** - * Start SPI - */ - void begin(int busNo); - - /** - * Transfer a single byte - * @param tx_ Byte to send - * @return Data returned via spi - */ - uint8_t transfer(uint8_t tx_); - - /** - * Transfer a buffer of data - * @param tbuf Transmit buffer - * @param rbuf Receive buffer - * @param len Length of the data - */ - void transfernb(char* tbuf, char* rbuf, uint32_t len); - - /** - * Transfer a buffer of data without an rx buffer - * @param buf Pointer to a buffer of data - * @param len Length of the data - */ - void transfern(char* buf, uint32_t len); - -#ifndef DOXYGEN_FORCED - // exclude this line from the docs to prevent warnings docs generators - virtual ~SPI(); -#endif - -private: - /** Default SPI device */ - string device; - /** SPI Mode set */ - uint8_t mode; - /** word size*/ - uint8_t bits; - /** Set SPI speed*/ - uint32_t speed; - int fd; - - void init(); -}; - -/**@}*/ - -#endif // RF24_UTILITY_TEMPLATE_SPI_H_ diff --git a/RF24/utility/pigpio/RF24_arch_config.h b/RF24/utility/pigpio/RF24_arch_config.h deleted file mode 100644 index 4f7d9e132293b5321e33c8a60dd59b5e9f5c3712..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/RF24_arch_config.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - - */ -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -#define RF24_LINUX - -#include <stddef.h> -#include "spi.h" -#include "gpio.h" -#include "compatibility.h" -#include <stdint.h> -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <sys/time.h> - -//#define RF24_SPI_SPEED RF24_SPIDEV_SPEED - -#define _BV(x) (1 << (x)) -#define _SPI spi - -//#undef SERIAL_DEBUG -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -// Avoid spurious warnings -#if 1 - #if !defined(NATIVE) && defined(ARDUINO) - #undef PROGMEM - #define PROGMEM __attribute__((section(".progmem.data"))) - #undef PSTR - #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0]; })) - #endif -#endif - -#if RF24_SPI_SPEED > 1000000 - #undef RF24_SPI_SPEED - #define RF24_SPI_SPEED 1000000 -#endif - -typedef uint16_t prog_uint16_t; -#define PSTR(x) (x) -#define printf_P printf -#define strlen_P strlen -#define PROGMEM -#define pgm_read_word(p) (*(const unsigned short*)(p)) -#define PRIPSTR "%s" -#define pgm_read_byte(p) (*(const unsigned char*)(p)) -#define pgm_read_ptr(p) (*(void* const*)(p)) - -// Function, constant map as a result of migrating from Arduino -#define LOW GPIO::OUTPUT_LOW -#define HIGH GPIO::OUTPUT_HIGH -#define INPUT GPIO::DIRECTION_IN -#define OUTPUT GPIO::DIRECTION_OUT -#define digitalWrite(pin, value) GPIO::write(pin, value) -#define pinMode(pin, direction) GPIO::open(pin, direction) -#define delay(milisec) __msleep(milisec) -#define delayMicroseconds(usec) __usleep(usec) -#define millis() __millis() - -#endif // __ARCH_CONFIG_H__ diff --git a/RF24/utility/pigpio/compatibility.cpp b/RF24/utility/pigpio/compatibility.cpp deleted file mode 100644 index c4e0e3355738c74755ec583c9bcc20fb09c81cac..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/compatibility.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "compatibility.h" - -long long mtime, seconds, useconds; -//static struct timeval start, end; -//struct timespec start, end; -#include <time.h> -#include <chrono> -/**********************************************************************/ -/** - * This function is added in order to simulate arduino delay() function - * @param milisec - */ -void __msleep(int milisec) -{ - struct timespec req; // = {0}; - req.tv_sec = (time_t)milisec / 1000; - req.tv_nsec = (milisec % 1000) * 1000000L; - //nanosleep(&req, (struct timespec *)NULL); - clock_nanosleep(CLOCK_REALTIME, 0, &req, NULL); -} - -void __usleep(int microsec) -{ - struct timespec req; // = {0}; - req.tv_sec = (time_t)microsec / 1000000; - req.tv_nsec = (microsec / 1000000) * 1000; - //nanosleep(&req, (struct timespec *)NULL); - clock_nanosleep(CLOCK_REALTIME, 0, &req, NULL); -} - -/** - * This function is added in order to simulate arduino millis() function - */ - -bool timerStarted = false; - -void __start_timer() -{ -} - -auto start = std::chrono::steady_clock::now(); - -uint32_t __millis() -{ - - auto end = std::chrono::steady_clock::now(); - - return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); -} diff --git a/RF24/utility/pigpio/compatibility.h b/RF24/utility/pigpio/compatibility.h deleted file mode 100644 index fff69d2a6ba53d29031f052b1f18f4e6926ba5a2..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/compatibility.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * File: compatiblity.h - * Author: purinda - * - * Created on 24 June 2012, 3:08 PM - * patch for safer monotonic clock & millis() correction for 64bit LDV 2018 - */ - -#ifndef COMPATIBLITY_H -#define COMPATIBLITY_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdint.h> // for uintXX_t types -#include <stddef.h> -#include <time.h> -#include <sys/time.h> - -void __msleep(int milisec); - -void __usleep(int milisec); - -void __start_timer(); - -uint32_t __millis(); - -#ifdef __cplusplus -} -#endif - -#endif /* COMPATIBLITY_H */ diff --git a/RF24/utility/pigpio/gpio.cpp b/RF24/utility/pigpio/gpio.cpp deleted file mode 100644 index 2634d57ecf6f2d1ec565819fe264cfc70c3d6cfc..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/gpio.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* -* GPIO Functions - */ - -#include "gpio.h" -#include <pigpio.h> - -bool initialized = 0; - -GPIO::GPIO() -{ -} - -GPIO::~GPIO() -{ - gpioTerminate(); -} - -void GPIO::open(int port, int DDR) -{ - if (!initialized) { - gpioInitialise(); - } - initialized = true; - gpioSetMode(port, PI_OUTPUT); -} - -void GPIO::close(int port) -{ -} - -int GPIO::read(int port) -{ - return gpioRead(port); -} - -void GPIO::write(int port, int value) -{ - gpioWrite(port, value); -} diff --git a/RF24/utility/pigpio/gpio.h b/RF24/utility/pigpio/gpio.h deleted file mode 100644 index 5dea0ec29339de330542c258f9516ca881acc296..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/gpio.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - */ - -#ifndef RF24_GPIO_H -#define RF24_GPIO_H - -#include <cstdio> -#include <map> -#include <stdexcept> - -/** Specific excpetion for SPI errors */ -class GPIOException : public std::runtime_error -{ -public: - explicit GPIOException(const std::string& msg) - : std::runtime_error(msg) - { - } -}; - -/** - * @file gpio.h - * @cond HIDDEN_SYMBOLS - * Class declaration for GPIO helper files - */ - -/** - * Example GPIO.h file - * - * @defgroup GPIO GPIO Example - * - * See RF24_arch_config.h for additional information - * @{ - */ - -class GPIO -{ -public: - /* Constants */ - static const int DIRECTION_OUT = 1; - static const int DIRECTION_IN = 0; - - static const int OUTPUT_HIGH = 1; - static const int OUTPUT_LOW = 0; - - GPIO(); - - /** - * Similar to Arduino pinMode(pin,mode); - * @param port - * @param DDR - */ - static void open(int port, int DDR); - - /** - * - * @param port - */ - static void close(int port); - - /** - * Similar to Arduino digitalRead(pin); - * @param port - */ - static int read(int port); - - /** - * Similar to Arduino digitalWrite(pin,state); - * @param port - * @param value - */ - static void write(int port, int value); - - virtual ~GPIO(); - -private: -}; -/** - * @endcond - */ -/**@}*/ -#endif /* H */ diff --git a/RF24/utility/pigpio/includes.h b/RF24/utility/pigpio/includes.h deleted file mode 100644 index b7e76d988670cb288452bee1cad04c2a09108ce6..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/includes.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __RF24_INCLUDES_H__ -#define __RF24_INCLUDES_H__ - -#define RF24_PIGPIO - -#include "pigpio/RF24_arch_config.h" -#ifndef RF24_NO_INTERRUPT - #include "pigpio/interrupt.h" -#endif - -#endif diff --git a/RF24/utility/pigpio/interrupt.cpp b/RF24/utility/pigpio/interrupt.cpp deleted file mode 100644 index 3b970c375904116cf8b6386031c0feaf7755b4eb..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/interrupt.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - -*/ - -#include "interrupt.h" -#include <pigpio.h> - -int attachInterrupt(int pin, int mode, void (*function)(void)) -{ - gpioInitialise(); - return gpioSetISRFunc(pin, mode, 0, (gpioISRFunc_t)function); -} - -int detachInterrupt(int pin) -{ - return gpioSetISRFunc(pin, 0, 0, NULL); -} - -void rfNoInterrupts() -{ -} - -void rfInterrupts() -{ -} \ No newline at end of file diff --git a/RF24/utility/pigpio/interrupt.h b/RF24/utility/pigpio/interrupt.h deleted file mode 100644 index fb2527ac0fa0c901301878be5514167724bd7311..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/interrupt.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -Interrupts functions extruded from wiringPi library by Oitzu. - -wiringPi Copyright (c) 2012 Gordon Henderson -https://projects.drogon.net/raspberry-pi/wiringpi -wiringPi is free software: GNU Lesser General Public License -see <http://www.gnu.org/licenses/> -*/ -#ifndef __RF24_INTERRUPT_H__ -#define __RF24_INTERRUPT_H__ - -#include "RF24_arch_config.h" -#include <pigpio.h> - -#define INT_EDGE_SETUP 0 -#define INT_EDGE_FALLING FALLING_EDGE -#define INT_EDGE_RISING RISING_EDGE -#define INT_EDGE_BOTH EITHER_EDGE - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * attachInterrupt (Original: wiringPiISR): - * Pi Specific. - * Take the details and create an interrupt handler that will do a call- - * back to the user supplied function. - ********************************************************************************* - */ -extern int attachInterrupt(int pin, int mode, void (*function)(void)); - -/* - * detachInterrupt: - * Pi Specific detachInterrupt. - * Will cancel the interrupt thread, close the filehandle and - * setting wiringPi back to 'none' mode. - ********************************************************************************* - */ -extern int detachInterrupt(int pin); - -/* Deprecated, no longer functional -*/ -extern void rfNoInterrupts(); - -/* Deprecated, no longer functional -*/ -extern void rfInterrupts(); - -#ifdef __cplusplus -} -#endif -#endif \ No newline at end of file diff --git a/RF24/utility/pigpio/spi.cpp b/RF24/utility/pigpio/spi.cpp deleted file mode 100644 index 3a962a96c48ca2283c31a9d644ec7cf452703692..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/spi.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - */ - -#include "spi.h" -#include <pigpio.h> - -SPI::SPI() -{ -} - -void SPI::begin(int busNo, uint32_t spi_speed) -{ - if (this->spiIsInitialized) { - return; - } - spiIsInitialized = true; - gpioInitialise(); - spiHandle = spiOpen(busNo, spi_speed, 0); -} - -void SPI::init(uint32_t speed) -{ -} - -uint8_t SPI::transfer(char tx) -{ - char rbuf = 0; - spiXfer(spiHandle, &tx, &rbuf, 1); - return rbuf; -} - -void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len) -{ - spiXfer(spiHandle, tbuf, rbuf, len); -} - -SPI::~SPI() -{ -} diff --git a/RF24/utility/pigpio/spi.h b/RF24/utility/pigpio/spi.h deleted file mode 100644 index 8db0e8755bbd78223871e69c86a6a4f5f50ad751..0000000000000000000000000000000000000000 --- a/RF24/utility/pigpio/spi.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - */ - -#ifndef SPI_H -#define SPI_H - -/** - * @file spi.h - * \cond HIDDEN_SYMBOLS - * Class declaration for SPI helper files - */ - -/** -* Example GPIO.h file -* -* @defgroup SPI SPI Example -* -* See RF24_arch_config.h for additional information -* @{ -*/ - -#include <inttypes.h> -#include <stdexcept> - -#include "../../RF24_config.h" - -/** Specific excpetion for SPI errors */ -class SPIException : public std::runtime_error -{ -public: - explicit SPIException(const std::string& msg) - : std::runtime_error(msg) - { - } -}; - -class SPI -{ - -public: - /** - * SPI constructor - */ - SPI(); - - /** - * Start SPI - */ - void begin(int busNo, uint32_t spi_speed); - - /** - * Transfer a single byte - * @param tx Byte to send - * @return Data returned via spi - */ - uint8_t transfer(char tx); - - /** - * Transfer a buffer of data - * @param tbuf Transmit buffer - * @param rbuf Receive buffer - * @param len Length of the data - */ - void transfernb(char* tbuf, char* rbuf, uint32_t len); - - /** - * Transfer a buffer of data without an rx buffer - * @param buf Pointer to a buffer of data - * @param len Length of the data - */ - void transfern(char* buf, uint32_t len) - { - transfernb(buf, buf, len); - } - - ~SPI(); - -private: - unsigned spiHandle; - bool spiIsInitialized = false; - void init(uint32_t spi_speed); -}; - -/** - * \endcond - */ -/*@}*/ -#endif /* SPI_H */ diff --git a/RF24/utility/rp2/CMakeLists.txt b/RF24/utility/rp2/CMakeLists.txt deleted file mode 100644 index ccc115cf5167ee5856194db670a46379c48700af..0000000000000000000000000000000000000000 --- a/RF24/utility/rp2/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -## Include this file if you want to use the RF24 library -## in YOUR (Pico) project. -## See examples_pico/CMakeLists.txt to see how it could be done - -cmake_minimum_required(VERSION 3.12) - -set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 17) - -# Define the RF24 core library -add_library(RF24 INTERFACE) - -target_sources(RF24 INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/../../RF24.cpp - ${CMAKE_CURRENT_LIST_DIR}/gpio.cpp - ${CMAKE_CURRENT_LIST_DIR}/spi.cpp -) - -target_include_directories(RF24 INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/../../ -) diff --git a/RF24/utility/rp2/RF24_arch_config.h b/RF24/utility/rp2/RF24_arch_config.h deleted file mode 100644 index 7d5a1a93dd2e150775fa0f06e7272f63a0fab0ce..0000000000000000000000000000000000000000 --- a/RF24/utility/rp2/RF24_arch_config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) - * 2021 Jannis Achstetter (kripton) - * 2021 Brendan Doherty (2bndy5) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ - -/** - * @file RF24_arch_config.h - * General defines and includes for RF24 using The Pico SDK - */ - -#ifndef RF24_UTILITY_RP2_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_RP2_RF24_ARCH_CONFIG_H_ - -#include "spi.h" -#include "gpio.h" -#include <string.h> -#include <stdio.h> - -/** Define a specific platform name for this configuration */ -#define RF24_RP2 - -#define _BV(x) (1 << (x)) -#define _SPI SPI -#define RF24_SPI_PTR - -static SPI spi; - -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -typedef uint16_t prog_uint16_t; -#define PSTR(x) (x) -#define printf_P printf -#define strlen_P strlen -#define PROGMEM -#define pgm_read_word(p) (*(const unsigned short*)(p)) -#define PRIPSTR "%s" -#define pgm_read_byte(p) (*(const unsigned char*)(p)) - -#define pgm_read_ptr(p) (*(void* const*)(p)) - -// Function, constant map as a result of migrating from Arduino -#define LOW GPIO::OUTPUT_LOW -#define HIGH GPIO::OUTPUT_HIGH -#define INPUT GPIO::DIRECTION_IN -#define OUTPUT GPIO::DIRECTION_OUT -#define digitalWrite(pin, value) GPIO::write(pin, value) -#define pinMode(pin, direction) GPIO::open(pin, direction) -#define delay(milisec) sleep_ms(milisec) -#define delayMicroseconds(usec) sleep_us(usec) -#define millis() to_ms_since_boot(get_absolute_time()) - -#endif // RF24_UTILITY_RP2_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/rp2/gpio.cpp b/RF24/utility/rp2/gpio.cpp deleted file mode 100644 index 4b3132e120af7ea99fa150deb4982f843bb11505..0000000000000000000000000000000000000000 --- a/RF24/utility/rp2/gpio.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "gpio.h" - -GPIO::GPIO() -{ -} - -void GPIO::open(int port, int DDR) -{ - gpio_init(port); - gpio_set_dir(port, DDR); -} - -void GPIO::close(int port) -{ - gpio_init(port); -} - -int GPIO::read(int port) -{ - return gpio_get(port); -} - -void GPIO::write(int port, int value) -{ - gpio_put(port, value); -} - -GPIO::~GPIO() -{ -} diff --git a/RF24/utility/rp2/gpio.h b/RF24/utility/rp2/gpio.h deleted file mode 100644 index 262a92d273b4d739d7c3c8e5d92e9274a90971fd..0000000000000000000000000000000000000000 --- a/RF24/utility/rp2/gpio.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file gpio.h - * Class declaration for SPI helper files - */ -#ifndef RF24_UTILITY_RP2_GPIO_H_ -#define RF24_UTILITY_RP2_GPIO_H_ - -#include <stdio.h> -#include "pico/stdlib.h" - -class GPIO -{ - -public: - static const int DIRECTION_OUT = 1; - static const int DIRECTION_IN = 0; - - static const int OUTPUT_HIGH = 1; - static const int OUTPUT_LOW = 0; - - GPIO(); - - static void open(int port, int DDR); - - static void close(int port); - - static int read(int port); - - static void write(int port, int value); - - virtual ~GPIO(); -}; - -#endif // RF24_UTILITY_RP2_GPIO_H_ diff --git a/RF24/utility/rp2/spi.cpp b/RF24/utility/rp2/spi.cpp deleted file mode 100644 index f60945198679c565e99f1c173a3c485aa799cd76..0000000000000000000000000000000000000000 --- a/RF24/utility/rp2/spi.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "spi.h" - -spi_inst_t* SPI::_hw_id; - -SPI::SPI() -{ -} - -void SPI::begin(spi_inst_t* hw_id) -{ - begin(hw_id, PICO_DEFAULT_SPI_SCK_PIN, PICO_DEFAULT_SPI_TX_PIN, PICO_DEFAULT_SPI_RX_PIN); -} - -void SPI::begin(spi_inst_t* hw_id, uint8_t _sck, uint8_t _tx, uint8_t _rx) -{ - _hw_id = hw_id; - gpio_set_function(_sck, GPIO_FUNC_SPI); - gpio_set_function(_tx, GPIO_FUNC_SPI); - gpio_set_function(_rx, GPIO_FUNC_SPI); -} - -uint8_t SPI::transfer(uint8_t tx_) -{ - uint8_t recv = 0; - spi_write_read_blocking(_hw_id, &tx_, &recv, 1); - return recv; -} - -void SPI::transfernb(const uint8_t* tbuf, uint8_t* rbuf, uint32_t len) -{ - spi_write_read_blocking(_hw_id, tbuf, rbuf, len); -} - -void SPI::transfern(const uint8_t* buf, uint32_t len) -{ - spi_write_blocking(_hw_id, buf, len); -} - -void SPI::beginTransaction(uint32_t _spi_speed) -{ - spi_init(_hw_id, _spi_speed); - spi_set_format(_hw_id, RF24_SPI_BYTE_SIZE, RF24_SPI_CPOL, RF24_SPI_CPHA, RF24_SPI_ENDIAN); -} - -void SPI::endTransaction() -{ - spi_deinit(_hw_id); -} - -SPI::~SPI() -{ -} diff --git a/RF24/utility/rp2/spi.h b/RF24/utility/rp2/spi.h deleted file mode 100644 index 2339b928f655c3e0059a136f5176caae9bff3b9e..0000000000000000000000000000000000000000 --- a/RF24/utility/rp2/spi.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file spi.h - * Class declaration for SPI wrapping the Pico SDK - */ -#ifndef RF24_UTILITY_RP2_SPI_H_ -#define RF24_UTILITY_RP2_SPI_H_ - -#include <stdio.h> -#include "pico/stdlib.h" -#include "hardware/spi.h" - -#define RF24_SPI_BYTE_SIZE 8 -#define RF24_SPI_ENDIAN SPI_MSB_FIRST -#define RF24_SPI_CPHA SPI_CPHA_0 -#define RF24_SPI_CPOL SPI_CPOL_0 - -// this SPI class uses beginTransaction() & endTransaction() to -// implement spi_init() & spi_deinit() -#define SPI_HAS_TRANSACTION 1 - -class SPI -{ - -public: - SPI(); - - /** - * Start SPI - * @param hw_id This is either `spi0` or `spi1` (provided by the Pico SDK) - * - * @note this function assumes using the default SPI pins defined for your - * board in "pico-sdk/src/boards/include/boards/*.h" files of the Pico SDK. - * @see begin(spi_inst_t, uint8_t, uint8_t, uint8_t) for using other pins as - * your SPI bus. - */ - static void begin(spi_inst_t* hw_id); - - /** - * Start SPI - * @param hw_id This is either `spi0` or `spi1` (provided by the Pico SDK) - * @param _sck The pin to be used as the SPI bus' sck - * @param _tx The pin to be used as the SPI bus' tx (MOSI) - * @param _rx The pin to be used as the SPI bus' rx (MISO) - * - * @note this function assumes using the default SPI pins defined for your - * board in "pico-sdk/src/boards/include/boards/*.h" files of the Pico SDK. - * @see The [Pico SDK has a chart of applicable pins](https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf#%5B%7B%22num%22%3A106%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C115%2C377.118%2Cnull%5D) - * that can be used for hardware driven SPI transactions. - */ - static void begin(spi_inst_t* hw_id, uint8_t _sck, uint8_t _tx, uint8_t _rx); - - static uint8_t transfer(uint8_t tx_); - - static void transfernb(const uint8_t* tbuf, uint8_t* rbuf, uint32_t len); - - static void transfern(const uint8_t* buf, uint32_t len); - - static void beginTransaction(uint32_t _spi_speed); - - /** deinit the SPI bus (using hw_id passed to begin()) */ - static void endTransaction(); - - virtual ~SPI(); - -private: - /** the ID of the hardware driven SPI bus */ - static spi_inst_t* _hw_id; -}; - -#endif // RF24_UTILITY_RP2_SPI_H_ diff --git a/RF24/utility/wiringPi/RF24_arch_config.h b/RF24/utility/wiringPi/RF24_arch_config.h deleted file mode 100644 index cc5570c1896050470f5294793914e08efa415ef5..0000000000000000000000000000000000000000 --- a/RF24/utility/wiringPi/RF24_arch_config.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. - - */ -#ifndef RF24_UTILITY_WIRINGPI_RF24_ARCH_CONFIG_H_ -#define RF24_UTILITY_WIRINGPI_RF24_ARCH_CONFIG_H_ - -#define RF24_LINUX - -#include <stddef.h> -#include "spi.h" -#include "wiringPi.h" -#include <stdint.h> -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <sys/time.h> - -#define _BV(x) (1 << (x)) -#define _SPI spi - -#undef SERIAL_DEBUG -#ifdef SERIAL_DEBUG - #define IF_SERIAL_DEBUG(x) ({ x; }) -#else - #define IF_SERIAL_DEBUG(x) -#endif - -// Avoid spurious warnings -#if !defined(NATIVE) && defined(ARDUINO) - #undef PROGMEM - #define PROGMEM __attribute__((section(".progmem.data"))) - #undef PSTR - #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0]; })) -#endif - -typedef uint16_t prog_uint16_t; -#define PSTR(x) (x) -#define printf_P printf -#define strlen_P strlen -#define PROGMEM -#define pgm_read_word(p) (*(const unsigned short*)(p)) -#define PRIPSTR "%s" -#define pgm_read_byte(p) (*(const unsigned char*)(p)) -#define pgm_read_ptr(p) (*(void* const*)(p)) - -#endif // RF24_UTILITY_WIRINGPI_RF24_ARCH_CONFIG_H_ diff --git a/RF24/utility/wiringPi/includes.h b/RF24/utility/wiringPi/includes.h deleted file mode 100644 index a64262fafa4e27aa3b6c6a5e250cd8cd86f9d51c..0000000000000000000000000000000000000000 --- a/RF24/utility/wiringPi/includes.h +++ /dev/null @@ -1,19 +0,0 @@ -/** -* @file includes.h -* Configuration defines for RF24/Linux -*/ - -#ifndef RF24_UTILITY_INCLUDES_H_ -#define RF24_UTILITY_INCLUDES_H_ - -/** - * Define RF24_WIRINGPI configuration for RaspberryPi platform - */ -#define RF24_WIRINGPI - -/** - * Load the correct configuration for this platform - */ -#include "wiringPi/RF24_arch_config.h" - -#endif // RF24_UTILITY_INCLUDES_H_ diff --git a/RF24/utility/wiringPi/spi.cpp b/RF24/utility/wiringPi/spi.cpp deleted file mode 100644 index d6abd4d8f4b858a25619001b4802f91090b4f359..0000000000000000000000000000000000000000 --- a/RF24/utility/wiringPi/spi.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * File: spi.cpp - * Author: - * - * Created on - * - * Inspired from spi speed test from wiringPi - * wiringPi/examples/spiSpeed.c - */ - -#include "spi.h" - -#include <wiringPi.h> -#include <wiringPiSPI.h> - -#include <stdlib.h> -#include <unistd.h> -#include <stdint.h> -#include <string.h> -#include <errno.h> - -#define RF24_SPI_CHANNEL 0 - -SPI::SPI() : fd(-1) -{ - printf("wiringPi RF24 DRIVER\n"); -} - -void SPI::begin(int csn_pin, uint32_t spi_speed) -{ - // initialize the wiringPiSPI - wiringPiSetup(); - if ((this->fd = wiringPiSPISetup(RF24_SPI_CHANNEL, spi_speed)) < 0) { - printf("Cannot configure the SPI device!\n"); - fflush(stdout); - abort(); - } - else { - printf("Configured SPI fd: %d - pin: %d\n", fd, csn_pin); - } -} - -uint8_t SPI::transfer(uint8_t tx) -{ - memset(&msgByte, 0, sizeof(msgByte)); - memcpy(&msgByte, &tx, sizeof(tx)); - - if (wiringPiSPIDataRW(RF24_SPI_CHANNEL, &msgByte, sizeof(tx)) < 0) { - printf("transfer(): Cannot send data: %s\n", strerror(errno)); - fflush(stdout); - abort(); - } - - return msgByte; -} - -void SPI::transfern(char* buf, uint32_t len) -{ - printf("transfern(tx: %s)\n", buf); - - if (wiringPiSPIDataRW(RF24_SPI_CHANNEL, (uint8_t*)buf, len) < 0) { - printf("transfern(): Cannot send data %s\n", strerror(errno)); - fflush(stdout); - abort(); - } -} - -void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len) -{ - // using an auxiliary buffer to keep tx and rx different - memset(msg, 0, sizeof(msg)); - memcpy(msg, tbuf, len); - - if (wiringPiSPIDataRW(RF24_SPI_CHANNEL, msg, len) < 0) { - printf("transfernb() Cannot send data %s\n", strerror(errno)); - fflush(stdout); - abort(); - } - - memcpy(rbuf, msg, len); -} - -SPI::~SPI() -{ - if (this->fd >= 0) { - close(this->fd); - this->fd = -1; - } -} diff --git a/RF24/utility/wiringPi/spi.h b/RF24/utility/wiringPi/spi.h deleted file mode 100644 index efafce09c0517eb1eb53165eb8f002b5ce919993..0000000000000000000000000000000000000000 --- a/RF24/utility/wiringPi/spi.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file spi.h - * Class declaration for SPI helper files - */ - -#ifndef RF24_UTILITY_WIRINGPI_SPI_H_ -#define RF24_UTILITY_WIRINGPI_SPI_H_ - -#include <stdio.h> -#include <inttypes.h> - -#include "../../RF24_config.h" // This is cyclical and should be fixed - -using namespace std; - -class SPI -{ - -public: - SPI(); - - void begin(int csn_pin, uint32_t spi_speed = RF24_SPI_SPEED); - - uint8_t transfer(uint8_t); - - void transfernb(char*, char*, uint32_t); - - void transfern(char*, const uint32_t); - - virtual ~SPI(); - -private: - int fd; - uint8_t msg[32 + 1]; - uint8_t msgByte; -}; - -#endif // RF24_UTILITY_WIRINGPI_SPI_H_ diff --git a/VL53L0X/LICENSE.txt b/VL53L0X/LICENSE.txt deleted file mode 100644 index 16b6dd0219e73573b153131899b4c7d7a9a4c12a..0000000000000000000000000000000000000000 --- a/VL53L0X/LICENSE.txt +++ /dev/null @@ -1,71 +0,0 @@ -Copyright (c) 2017-2022 Pololu Corporation. For more information, see - -https://www.pololu.com/ -https://forum.pololu.com/ - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -================================================================= - -Most of the functionality of this library is based on the VL53L0X -API provided by ST (STSW-IMG005), and some of the explanatory -comments are quoted or paraphrased from the API source code, API -user manual (UM2039), and the VL53L0X datasheet. - -The following applies to source code reproduced or derived from -the API: - ------------------------------------------------------------------ - -Copyright © 2016, STMicroelectronics International N.V. All -rights reserved. - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following -conditions are met: -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following -disclaimer in the documentation and/or other materials provided -with the distribution. -* Neither the name of STMicroelectronics nor the -names of its contributors may be used to endorse or promote -products derived from this software without specific prior -written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND -NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. -IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - ------------------------------------------------------------------ diff --git a/VL53L0X/README.md b/VL53L0X/README.md deleted file mode 100644 index 1c598aa965ab571b9a9352df575d75d6f0afcdaf..0000000000000000000000000000000000000000 --- a/VL53L0X/README.md +++ /dev/null @@ -1,170 +0,0 @@ -# VL53L0X library for Arduino -[www.pololu.com](https://www.pololu.com/) - -## Summary - -This is a library for the Arduino IDE that helps interface with ST's [VL53L0X time-of-flight distance sensor](https://www.pololu.com/product/2490). The library makes it simple to configure the sensor and read range data from it via I²C. - -## Supported platforms - -This library is designed to work with the Arduino IDE versions 1.6.x or later; we have not tested it with earlier versions. This library should support any Arduino-compatible board, including the [Pololu A-Star 32U4 controllers](https://www.pololu.com/category/149/a-star-programmable-controllers). - -## Getting started - -### Hardware - -A [VL53L0X carrier](https://www.pololu.com/product/2490) can be purchased from Pololu's website. Before continuing, careful reading of the [product page](https://www.pololu.com/product/2490) as well as the VL53L0X datasheet is recommended. - -Make the following connections between the Arduino and the VL53L0X board: - -#### 5V Arduino boards - -(including Arduino Uno, Leonardo, Mega; Pololu A-Star 32U4) - - Arduino VL53L0X board - ------- ------------- - 5V - VIN - GND - GND - SDA - SDA - SCL - SCL - -#### 3.3V Arduino boards - -(including Arduino Due) - - Arduino VL53L0X board - ------- ------------- - 3V3 - VIN - GND - GND - SDA - SDA - SCL - SCL - -### Software - -If you are using version 1.6.2 or later of the [Arduino software (IDE)](http://www.arduino.cc/en/Main/Software), you can use the Library Manager to install this library: - -1. In the Arduino IDE, open the "Sketch" menu, select "Include Library", then "Manage Libraries...". -2. Search for "VL53L0X". -3. Click the VL53L0X entry in the list. -4. Click "Install". - -If this does not work, you can manually install the library: - -1. Download the [latest release archive from GitHub](https://github.com/pololu/vl53l0x-arduino/releases) and decompress it. -2. Rename the folder "vl53l0x-arduino-master" to "VL53L0X". -3. Move the "VL53L0X" folder into the "libraries" directory inside your Arduino sketchbook directory. You can view your sketchbook location by opening the "File" menu and selecting "Preferences" in the Arduino IDE. If there is not already a "libraries" folder in that location, you should make the folder yourself. -4. After installing the library, restart the Arduino IDE. - -## Examples - -Several example sketches are available that show how to use the library. You can access them from the Arduino IDE by opening the "File" menu, selecting "Examples", and then selecting "VL53L0X". If you cannot find these examples, the library was probably installed incorrectly and you should retry the installation instructions above. - -## ST's VL53L0X API and this library - -Most of the functionality of this library is based on the [VL53L0X API](http://www.st.com/content/st_com/en/products/embedded-software/proximity-sensors-software/stsw-img005.html) provided by ST (STSW-IMG005), and some of the explanatory comments in the code are quoted or paraphrased from the API source code, API user manual (UM2039), and the VL53L0X datasheet. For more explanation about the library code and how it was derived from the API, see the comments in VL53L0X.cpp. - -This library is intended to provide a quicker and easier way to get started using the VL53L0X with an Arduino-compatible controller, in contrast to customizing and compiling ST's API for the Arduino. The library has a more streamlined interface, as well as smaller storage and memory footprints. However, it does not implement some of the more advanced functionality available in the API (for example, calibrating the sensor to work well under a cover glass), and it has less robust error checking. For advanced applications, especially when storage and memory are less of an issue, consider using the VL53L0X API directly. - -## Library reference - -* `uint8_t last_status`<br> - The status of the last I²C write transmission. See the [`Wire.endTransmission()` documentation](http://arduino.cc/en/Reference/WireEndTransmission) for return values. - -* `VL53L0X()`<br> - Constructor. - -* `void setBus(TwoWire * bus)`<br> - Configures this object to use the specified I²C bus. `bus` should be a pointer to a `TwoWire` object; the default bus is `Wire`, which is typically the first or only I²C bus on an Arduino. If your Arduino has more than one I²C bus and you have the VL53L0X connected to the second bus, which is typically called `Wire1`, you can call `sensor.setBus(&Wire1);`. - -* `TwoWire * getBus()`<br> - Returns a pointer to the I²C bus this object is using. - -* `void setAddress(uint8_t new_addr)`<br> - Changes the I²C slave device address of the VL53L0X to the given value (7-bit). - -* `uint8_t getAddress()`<br> - Returns the I²C address this object is using. - -* `bool init(bool io_2v8 = true)`<br> - Iniitializes and configures the sensor. If the optional argument `io_2v8` is true (the default if not specified), the sensor is configured for 2V8 mode (2.8 V I/O); if false, the sensor is left in 1V8 mode. The return value is a boolean indicating whether the initialization completed successfully. - -* `void writeReg(uint8_t reg, uint8_t value)`<br> - Writes an 8-bit sensor register with the given value. - - Register address constants are defined by the regAddr enumeration type in VL53L0X.h.<br> - Example use: `sensor.writeReg(VL53L0X::SYSRANGE_START, 0x01);` - -* `void writeReg16Bit(uint8_t reg, uint16_t value)`<br> - Writes a 16-bit sensor register with the given value. - -* `void writeReg32Bit(uint8_t reg, uint32_t value)`<br> - Writes a 32-bit sensor register with the given value. - -* `uint8_t readReg(uint8_t reg)`<br> - Reads an 8-bit sensor register and returns the value read. - -* `uint16_t readReg16Bit(uint8_t reg)`<br> - Reads a 16-bit sensor register and returns the value read. - -* `uint32_t readReg32Bit(uint8_t reg)`<br> - Reads a 32-bit sensor register and returns the value read. - -* `void writeMulti(uint8_t reg, uint8_t const * src, uint8_t count)`<br> - Writes an arbitrary number of bytes from the given array to the sensor, starting at the given register. - -* `void readMulti(uint8_t reg, uint8_t * dst, uint8_t count)`<br> - Reads an arbitrary number of bytes from the sensor, starting at the given register, into the given array. - -* `bool setSignalRateLimit(float limit_Mcps)`<br> - Sets the return signal rate limit to the given value in units of MCPS (mega counts per second). This is the minimum amplitude of the signal reflected from the target and received by the sensor necessary for it to report a valid reading. Setting a lower limit increases the potential range of the sensor but also increases the likelihood of getting an inaccurate reading because of reflections from objects other than the intended target. This limit is initialized to 0.25 MCPS by default. The return value is a boolean indicating whether the requested limit was valid. - -* `float getSignalRateLimit()`<br> - Returns the current return signal rate limit in MCPS. - -* `bool setMeasurementTimingBudget(uint32_t budget_us)`<br> - Sets the measurement timing budget to the given value in microseconds. This is the time allowed for one range measurement; a longer timing budget allows for more accurate measurements. The default budget is about 33000 microseconds, or 33 ms; the minimum is 20 ms. The return value is a boolean indicating whether the requested budget was valid. - -* `uint32_t getMeasurementTimingBudget()`<br> - Returns the current measurement timing budget in microseconds. - -* `bool setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks)` - Sets the VCSEL (vertical cavity surface emitting laser) pulse period for the given period type (`VL53L0X::VcselPeriodPreRange` or `VL53L0X::VcselPeriodFinalRange`) to the given value (in PCLKs). Longer periods increase the potential range of the sensor. Valid values are (even numbers only): - - Pre: 12 to 18 (initialized to 14 by default)<br> - Final: 8 to 14 (initialized to 10 by default) - - The return value is a boolean indicating whether the requested period was valid. - -* `uint8_t getVcselPulsePeriod(vcselPeriodType type)`<br> - Returns the current VCSEL pulse period for the given period type. - -* `void startContinuous(uint32_t period_ms = 0)`<br> - Starts continuous ranging measurements. If the optional argument `period_ms` is 0 (the default if not specified), continuous back-to-back mode is used (the sensor takes measurements as often as possible); if it is nonzero, continuous timed mode is used, with the specified inter-measurement period in milliseconds determining how often the sensor takes a measurement. - -* `void stopContinuous()`<br> - Stops continuous mode. - -* `uint16_t readRangeContinuousMillimeters()`<br> - Returns a range reading in millimeters when continuous mode is active. - -* `uint16_t readRangeSingleMillimeters()`<br> - Performs a single-shot ranging measurement and returns the reading in millimeters. - -* `void setTimeout(uint16_t timeout)`<br> - Sets a timeout period in milliseconds after which read operations will abort if the sensor is not ready. A value of 0 disables the timeout. - -* `uint16_t getTimeout()`<br> - Returns the current timeout period setting. - -* `bool timeoutOccurred()`<br> - Indicates whether a read timeout has occurred since the last call to `timeoutOccurred()`. - -## Version history - -* 1.3.1 (2022-04-05): Explicitly cast `Wire.write()` arguments to `uint8_t`. Removed 20ms hard limit for timing budget to match API 1.0.4. -* 1.3.0 (2020-09-24): Added support for alternative I²C buses (thanks KurtE). -* 1.2.0 (2019-10-31): Incorporated some updates from ST's VL53L0X API version 1.0.2 (this library was originally based on API version 1.0.0). -* 1.1.0 (2019-10-29): Improved `init()` and added a check for its return value in examples; fixed a few other issues. -* 1.0.2 (2017-06-27): Fixed a typo in a register modification in `getSpadInfo()` (thanks @tridge). -* 1.0.1 (2016-12-08): Fixed type error in `readReg32Bit()`. -* 1.0.0 (2016-08-12): Original release. diff --git a/VL53L0X/VL53L0X.cpp b/VL53L0X/VL53L0X.cpp deleted file mode 100644 index d06be37cbcd4d6b18b7c646fb3984be6f8b433a4..0000000000000000000000000000000000000000 --- a/VL53L0X/VL53L0X.cpp +++ /dev/null @@ -1,1034 +0,0 @@ -// Most of the functionality of this library is based on the VL53L0X API -// provided by ST (STSW-IMG005), and some of the explanatory comments are quoted -// or paraphrased from the API source code, API user manual (UM2039), and the -// VL53L0X datasheet. - -#include "VL53L0X.h" -#include <Wire.h> - -// Defines ///////////////////////////////////////////////////////////////////// - -// The Arduino two-wire interface uses a 7-bit number for the address, -// and sets the last bit correctly based on reads and writes -#define ADDRESS_DEFAULT 0b0101001 - -// Record the current time to check an upcoming timeout against -#define startTimeout() (timeout_start_ms = millis()) - -// Check if timeout is enabled (set to nonzero value) and has expired -#define checkTimeoutExpired() (io_timeout > 0 && ((uint16_t)(millis() - timeout_start_ms) > io_timeout)) - -// Decode VCSEL (vertical cavity surface emitting laser) pulse period in PCLKs -// from register value -// based on VL53L0X_decode_vcsel_period() -#define decodeVcselPeriod(reg_val) (((reg_val) + 1) << 1) - -// Encode VCSEL pulse period register value from period in PCLKs -// based on VL53L0X_encode_vcsel_period() -#define encodeVcselPeriod(period_pclks) (((period_pclks) >> 1) - 1) - -// Calculate macro period in *nanoseconds* from VCSEL period in PCLKs -// based on VL53L0X_calc_macro_period_ps() -// PLL_period_ps = 1655; macro_period_vclks = 2304 -#define calcMacroPeriod(vcsel_period_pclks) ((((uint32_t)2304 * (vcsel_period_pclks) * 1655) + 500) / 1000) - -// Constructors //////////////////////////////////////////////////////////////// - -VL53L0X::VL53L0X() - : bus(&Wire) - , address(ADDRESS_DEFAULT) - , io_timeout(0) // no timeout - , did_timeout(false) -{ -} - -// Public Methods ////////////////////////////////////////////////////////////// - -void VL53L0X::setAddress(uint8_t new_addr) -{ - writeReg(I2C_SLAVE_DEVICE_ADDRESS, new_addr & 0x7F); - address = new_addr; -} - -// Initialize sensor using sequence based on VL53L0X_DataInit(), -// VL53L0X_StaticInit(), and VL53L0X_PerformRefCalibration(). -// This function does not perform reference SPAD calibration -// (VL53L0X_PerformRefSpadManagement()), since the API user manual says that it -// is performed by ST on the bare modules; it seems like that should work well -// enough unless a cover glass is added. -// If io_2v8 (optional) is true or not given, the sensor is configured for 2V8 -// mode. -bool VL53L0X::init(bool io_2v8) -{ - // check model ID register (value specified in datasheet) - if (readReg(IDENTIFICATION_MODEL_ID) != 0xEE) { return false; } - - // VL53L0X_DataInit() begin - - // sensor uses 1V8 mode for I/O by default; switch to 2V8 mode if necessary - if (io_2v8) - { - writeReg(VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV, - readReg(VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV) | 0x01); // set bit 0 - } - - // "Set I2C standard mode" - writeReg(0x88, 0x00); - - writeReg(0x80, 0x01); - writeReg(0xFF, 0x01); - writeReg(0x00, 0x00); - stop_variable = readReg(0x91); - writeReg(0x00, 0x01); - writeReg(0xFF, 0x00); - writeReg(0x80, 0x00); - - // disable SIGNAL_RATE_MSRC (bit 1) and SIGNAL_RATE_PRE_RANGE (bit 4) limit checks - writeReg(MSRC_CONFIG_CONTROL, readReg(MSRC_CONFIG_CONTROL) | 0x12); - - // set final range signal rate limit to 0.25 MCPS (million counts per second) - setSignalRateLimit(0.25); - - writeReg(SYSTEM_SEQUENCE_CONFIG, 0xFF); - - // VL53L0X_DataInit() end - - // VL53L0X_StaticInit() begin - - uint8_t spad_count; - bool spad_type_is_aperture; - if (!getSpadInfo(&spad_count, &spad_type_is_aperture)) { return false; } - - // The SPAD map (RefGoodSpadMap) is read by VL53L0X_get_info_from_device() in - // the API, but the same data seems to be more easily readable from - // GLOBAL_CONFIG_SPAD_ENABLES_REF_0 through _6, so read it from there - uint8_t ref_spad_map[6]; - readMulti(GLOBAL_CONFIG_SPAD_ENABLES_REF_0, ref_spad_map, 6); - - // -- VL53L0X_set_reference_spads() begin (assume NVM values are valid) - - writeReg(0xFF, 0x01); - writeReg(DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00); - writeReg(DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C); - writeReg(0xFF, 0x00); - writeReg(GLOBAL_CONFIG_REF_EN_START_SELECT, 0xB4); - - uint8_t first_spad_to_enable = spad_type_is_aperture ? 12 : 0; // 12 is the first aperture spad - uint8_t spads_enabled = 0; - - for (uint8_t i = 0; i < 48; i++) - { - if (i < first_spad_to_enable || spads_enabled == spad_count) - { - // This bit is lower than the first one that should be enabled, or - // (reference_spad_count) bits have already been enabled, so zero this bit - ref_spad_map[i / 8] &= ~(1 << (i % 8)); - } - else if ((ref_spad_map[i / 8] >> (i % 8)) & 0x1) - { - spads_enabled++; - } - } - - writeMulti(GLOBAL_CONFIG_SPAD_ENABLES_REF_0, ref_spad_map, 6); - - // -- VL53L0X_set_reference_spads() end - - // -- VL53L0X_load_tuning_settings() begin - // DefaultTuningSettings from vl53l0x_tuning.h - - writeReg(0xFF, 0x01); - writeReg(0x00, 0x00); - - writeReg(0xFF, 0x00); - writeReg(0x09, 0x00); - writeReg(0x10, 0x00); - writeReg(0x11, 0x00); - - writeReg(0x24, 0x01); - writeReg(0x25, 0xFF); - writeReg(0x75, 0x00); - - writeReg(0xFF, 0x01); - writeReg(0x4E, 0x2C); - writeReg(0x48, 0x00); - writeReg(0x30, 0x20); - - writeReg(0xFF, 0x00); - writeReg(0x30, 0x09); - writeReg(0x54, 0x00); - writeReg(0x31, 0x04); - writeReg(0x32, 0x03); - writeReg(0x40, 0x83); - writeReg(0x46, 0x25); - writeReg(0x60, 0x00); - writeReg(0x27, 0x00); - writeReg(0x50, 0x06); - writeReg(0x51, 0x00); - writeReg(0x52, 0x96); - writeReg(0x56, 0x08); - writeReg(0x57, 0x30); - writeReg(0x61, 0x00); - writeReg(0x62, 0x00); - writeReg(0x64, 0x00); - writeReg(0x65, 0x00); - writeReg(0x66, 0xA0); - - writeReg(0xFF, 0x01); - writeReg(0x22, 0x32); - writeReg(0x47, 0x14); - writeReg(0x49, 0xFF); - writeReg(0x4A, 0x00); - - writeReg(0xFF, 0x00); - writeReg(0x7A, 0x0A); - writeReg(0x7B, 0x00); - writeReg(0x78, 0x21); - - writeReg(0xFF, 0x01); - writeReg(0x23, 0x34); - writeReg(0x42, 0x00); - writeReg(0x44, 0xFF); - writeReg(0x45, 0x26); - writeReg(0x46, 0x05); - writeReg(0x40, 0x40); - writeReg(0x0E, 0x06); - writeReg(0x20, 0x1A); - writeReg(0x43, 0x40); - - writeReg(0xFF, 0x00); - writeReg(0x34, 0x03); - writeReg(0x35, 0x44); - - writeReg(0xFF, 0x01); - writeReg(0x31, 0x04); - writeReg(0x4B, 0x09); - writeReg(0x4C, 0x05); - writeReg(0x4D, 0x04); - - writeReg(0xFF, 0x00); - writeReg(0x44, 0x00); - writeReg(0x45, 0x20); - writeReg(0x47, 0x08); - writeReg(0x48, 0x28); - writeReg(0x67, 0x00); - writeReg(0x70, 0x04); - writeReg(0x71, 0x01); - writeReg(0x72, 0xFE); - writeReg(0x76, 0x00); - writeReg(0x77, 0x00); - - writeReg(0xFF, 0x01); - writeReg(0x0D, 0x01); - - writeReg(0xFF, 0x00); - writeReg(0x80, 0x01); - writeReg(0x01, 0xF8); - - writeReg(0xFF, 0x01); - writeReg(0x8E, 0x01); - writeReg(0x00, 0x01); - writeReg(0xFF, 0x00); - writeReg(0x80, 0x00); - - // -- VL53L0X_load_tuning_settings() end - - // "Set interrupt config to new sample ready" - // -- VL53L0X_SetGpioConfig() begin - - writeReg(SYSTEM_INTERRUPT_CONFIG_GPIO, 0x04); - writeReg(GPIO_HV_MUX_ACTIVE_HIGH, readReg(GPIO_HV_MUX_ACTIVE_HIGH) & ~0x10); // active low - writeReg(SYSTEM_INTERRUPT_CLEAR, 0x01); - - // -- VL53L0X_SetGpioConfig() end - - measurement_timing_budget_us = getMeasurementTimingBudget(); - - // "Disable MSRC and TCC by default" - // MSRC = Minimum Signal Rate Check - // TCC = Target CentreCheck - // -- VL53L0X_SetSequenceStepEnable() begin - - writeReg(SYSTEM_SEQUENCE_CONFIG, 0xE8); - - // -- VL53L0X_SetSequenceStepEnable() end - - // "Recalculate timing budget" - setMeasurementTimingBudget(measurement_timing_budget_us); - - // VL53L0X_StaticInit() end - - // VL53L0X_PerformRefCalibration() begin (VL53L0X_perform_ref_calibration()) - - // -- VL53L0X_perform_vhv_calibration() begin - - writeReg(SYSTEM_SEQUENCE_CONFIG, 0x01); - if (!performSingleRefCalibration(0x40)) { return false; } - - // -- VL53L0X_perform_vhv_calibration() end - - // -- VL53L0X_perform_phase_calibration() begin - - writeReg(SYSTEM_SEQUENCE_CONFIG, 0x02); - if (!performSingleRefCalibration(0x00)) { return false; } - - // -- VL53L0X_perform_phase_calibration() end - - // "restore the previous Sequence Config" - writeReg(SYSTEM_SEQUENCE_CONFIG, 0xE8); - - // VL53L0X_PerformRefCalibration() end - - return true; -} - -// Write an 8-bit register -void VL53L0X::writeReg(uint8_t reg, uint8_t value) -{ - bus->beginTransmission(address); - bus->write(reg); - bus->write(value); - last_status = bus->endTransmission(); -} - -// Write a 16-bit register -void VL53L0X::writeReg16Bit(uint8_t reg, uint16_t value) -{ - bus->beginTransmission(address); - bus->write(reg); - bus->write((uint8_t)(value >> 8)); // value high byte - bus->write((uint8_t)(value)); // value low byte - last_status = bus->endTransmission(); -} - -// Write a 32-bit register -void VL53L0X::writeReg32Bit(uint8_t reg, uint32_t value) -{ - bus->beginTransmission(address); - bus->write(reg); - bus->write((uint8_t)(value >> 24)); // value highest byte - bus->write((uint8_t)(value >> 16)); - bus->write((uint8_t)(value >> 8)); - bus->write((uint8_t)(value)); // value lowest byte - last_status = bus->endTransmission(); -} - -// Read an 8-bit register -uint8_t VL53L0X::readReg(uint8_t reg) -{ - uint8_t value; - - bus->beginTransmission(address); - bus->write(reg); - last_status = bus->endTransmission(); - - bus->requestFrom(address, (uint8_t)1); - value = bus->read(); - - return value; -} - -// Read a 16-bit register -uint16_t VL53L0X::readReg16Bit(uint8_t reg) -{ - uint16_t value; - - bus->beginTransmission(address); - bus->write(reg); - last_status = bus->endTransmission(); - - bus->requestFrom(address, (uint8_t)2); - value = (uint16_t)bus->read() << 8; // value high byte - value |= bus->read(); // value low byte - - return value; -} - -// Read a 32-bit register -uint32_t VL53L0X::readReg32Bit(uint8_t reg) -{ - uint32_t value; - - bus->beginTransmission(address); - bus->write(reg); - last_status = bus->endTransmission(); - - bus->requestFrom(address, (uint8_t)4); - value = (uint32_t)bus->read() << 24; // value highest byte - value |= (uint32_t)bus->read() << 16; - value |= (uint16_t)bus->read() << 8; - value |= bus->read(); // value lowest byte - - return value; -} - -// Write an arbitrary number of bytes from the given array to the sensor, -// starting at the given register -void VL53L0X::writeMulti(uint8_t reg, uint8_t const * src, uint8_t count) -{ - bus->beginTransmission(address); - bus->write(reg); - - while (count-- > 0) - { - bus->write(*(src++)); - } - - last_status = bus->endTransmission(); -} - -// Read an arbitrary number of bytes from the sensor, starting at the given -// register, into the given array -void VL53L0X::readMulti(uint8_t reg, uint8_t * dst, uint8_t count) -{ - bus->beginTransmission(address); - bus->write(reg); - last_status = bus->endTransmission(); - - bus->requestFrom(address, count); - - while (count-- > 0) - { - *(dst++) = bus->read(); - } -} - -// Set the return signal rate limit check value in units of MCPS (mega counts -// per second). "This represents the amplitude of the signal reflected from the -// target and detected by the device"; setting this limit presumably determines -// the minimum measurement necessary for the sensor to report a valid reading. -// Setting a lower limit increases the potential range of the sensor but also -// seems to increase the likelihood of getting an inaccurate reading because of -// unwanted reflections from objects other than the intended target. -// Defaults to 0.25 MCPS as initialized by the ST API and this library. -bool VL53L0X::setSignalRateLimit(float limit_Mcps) -{ - if (limit_Mcps < 0 || limit_Mcps > 511.99) { return false; } - - // Q9.7 fixed point format (9 integer bits, 7 fractional bits) - writeReg16Bit(FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, limit_Mcps * (1 << 7)); - return true; -} - -// Get the return signal rate limit check value in MCPS -float VL53L0X::getSignalRateLimit() -{ - return (float)readReg16Bit(FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT) / (1 << 7); -} - -// Set the measurement timing budget in microseconds, which is the time allowed -// for one measurement; the ST API and this library take care of splitting the -// timing budget among the sub-steps in the ranging sequence. A longer timing -// budget allows for more accurate measurements. Increasing the budget by a -// factor of N decreases the range measurement standard deviation by a factor of -// sqrt(N). Defaults to about 33 milliseconds; the minimum is 20 ms. -// based on VL53L0X_set_measurement_timing_budget_micro_seconds() -bool VL53L0X::setMeasurementTimingBudget(uint32_t budget_us) -{ - SequenceStepEnables enables; - SequenceStepTimeouts timeouts; - - uint16_t const StartOverhead = 1910; - uint16_t const EndOverhead = 960; - uint16_t const MsrcOverhead = 660; - uint16_t const TccOverhead = 590; - uint16_t const DssOverhead = 690; - uint16_t const PreRangeOverhead = 660; - uint16_t const FinalRangeOverhead = 550; - - uint32_t used_budget_us = StartOverhead + EndOverhead; - - getSequenceStepEnables(&enables); - getSequenceStepTimeouts(&enables, &timeouts); - - if (enables.tcc) - { - used_budget_us += (timeouts.msrc_dss_tcc_us + TccOverhead); - } - - if (enables.dss) - { - used_budget_us += 2 * (timeouts.msrc_dss_tcc_us + DssOverhead); - } - else if (enables.msrc) - { - used_budget_us += (timeouts.msrc_dss_tcc_us + MsrcOverhead); - } - - if (enables.pre_range) - { - used_budget_us += (timeouts.pre_range_us + PreRangeOverhead); - } - - if (enables.final_range) - { - used_budget_us += FinalRangeOverhead; - - // "Note that the final range timeout is determined by the timing - // budget and the sum of all other timeouts within the sequence. - // If there is no room for the final range timeout, then an error - // will be set. Otherwise the remaining time will be applied to - // the final range." - - if (used_budget_us > budget_us) - { - // "Requested timeout too big." - return false; - } - - uint32_t final_range_timeout_us = budget_us - used_budget_us; - - // set_sequence_step_timeout() begin - // (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE) - - // "For the final range timeout, the pre-range timeout - // must be added. To do this both final and pre-range - // timeouts must be expressed in macro periods MClks - // because they have different vcsel periods." - - uint32_t final_range_timeout_mclks = - timeoutMicrosecondsToMclks(final_range_timeout_us, - timeouts.final_range_vcsel_period_pclks); - - if (enables.pre_range) - { - final_range_timeout_mclks += timeouts.pre_range_mclks; - } - - writeReg16Bit(FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, - encodeTimeout(final_range_timeout_mclks)); - - // set_sequence_step_timeout() end - - measurement_timing_budget_us = budget_us; // store for internal reuse - } - return true; -} - -// Get the measurement timing budget in microseconds -// based on VL53L0X_get_measurement_timing_budget_micro_seconds() -// in us -uint32_t VL53L0X::getMeasurementTimingBudget() -{ - SequenceStepEnables enables; - SequenceStepTimeouts timeouts; - - uint16_t const StartOverhead = 1910; - uint16_t const EndOverhead = 960; - uint16_t const MsrcOverhead = 660; - uint16_t const TccOverhead = 590; - uint16_t const DssOverhead = 690; - uint16_t const PreRangeOverhead = 660; - uint16_t const FinalRangeOverhead = 550; - - // "Start and end overhead times always present" - uint32_t budget_us = StartOverhead + EndOverhead; - - getSequenceStepEnables(&enables); - getSequenceStepTimeouts(&enables, &timeouts); - - if (enables.tcc) - { - budget_us += (timeouts.msrc_dss_tcc_us + TccOverhead); - } - - if (enables.dss) - { - budget_us += 2 * (timeouts.msrc_dss_tcc_us + DssOverhead); - } - else if (enables.msrc) - { - budget_us += (timeouts.msrc_dss_tcc_us + MsrcOverhead); - } - - if (enables.pre_range) - { - budget_us += (timeouts.pre_range_us + PreRangeOverhead); - } - - if (enables.final_range) - { - budget_us += (timeouts.final_range_us + FinalRangeOverhead); - } - - measurement_timing_budget_us = budget_us; // store for internal reuse - return budget_us; -} - -// Set the VCSEL (vertical cavity surface emitting laser) pulse period for the -// given period type (pre-range or final range) to the given value in PCLKs. -// Longer periods seem to increase the potential range of the sensor. -// Valid values are (even numbers only): -// pre: 12 to 18 (initialized default: 14) -// final: 8 to 14 (initialized default: 10) -// based on VL53L0X_set_vcsel_pulse_period() -bool VL53L0X::setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks) -{ - uint8_t vcsel_period_reg = encodeVcselPeriod(period_pclks); - - SequenceStepEnables enables; - SequenceStepTimeouts timeouts; - - getSequenceStepEnables(&enables); - getSequenceStepTimeouts(&enables, &timeouts); - - // "Apply specific settings for the requested clock period" - // "Re-calculate and apply timeouts, in macro periods" - - // "When the VCSEL period for the pre or final range is changed, - // the corresponding timeout must be read from the device using - // the current VCSEL period, then the new VCSEL period can be - // applied. The timeout then must be written back to the device - // using the new VCSEL period. - // - // For the MSRC timeout, the same applies - this timeout being - // dependant on the pre-range vcsel period." - - - if (type == VcselPeriodPreRange) - { - // "Set phase check limits" - switch (period_pclks) - { - case 12: - writeReg(PRE_RANGE_CONFIG_VALID_PHASE_HIGH, 0x18); - break; - - case 14: - writeReg(PRE_RANGE_CONFIG_VALID_PHASE_HIGH, 0x30); - break; - - case 16: - writeReg(PRE_RANGE_CONFIG_VALID_PHASE_HIGH, 0x40); - break; - - case 18: - writeReg(PRE_RANGE_CONFIG_VALID_PHASE_HIGH, 0x50); - break; - - default: - // invalid period - return false; - } - writeReg(PRE_RANGE_CONFIG_VALID_PHASE_LOW, 0x08); - - // apply new VCSEL period - writeReg(PRE_RANGE_CONFIG_VCSEL_PERIOD, vcsel_period_reg); - - // update timeouts - - // set_sequence_step_timeout() begin - // (SequenceStepId == VL53L0X_SEQUENCESTEP_PRE_RANGE) - - uint16_t new_pre_range_timeout_mclks = - timeoutMicrosecondsToMclks(timeouts.pre_range_us, period_pclks); - - writeReg16Bit(PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, - encodeTimeout(new_pre_range_timeout_mclks)); - - // set_sequence_step_timeout() end - - // set_sequence_step_timeout() begin - // (SequenceStepId == VL53L0X_SEQUENCESTEP_MSRC) - - uint16_t new_msrc_timeout_mclks = - timeoutMicrosecondsToMclks(timeouts.msrc_dss_tcc_us, period_pclks); - - writeReg(MSRC_CONFIG_TIMEOUT_MACROP, - (new_msrc_timeout_mclks > 256) ? 255 : (new_msrc_timeout_mclks - 1)); - - // set_sequence_step_timeout() end - } - else if (type == VcselPeriodFinalRange) - { - switch (period_pclks) - { - case 8: - writeReg(FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x10); - writeReg(FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08); - writeReg(GLOBAL_CONFIG_VCSEL_WIDTH, 0x02); - writeReg(ALGO_PHASECAL_CONFIG_TIMEOUT, 0x0C); - writeReg(0xFF, 0x01); - writeReg(ALGO_PHASECAL_LIM, 0x30); - writeReg(0xFF, 0x00); - break; - - case 10: - writeReg(FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x28); - writeReg(FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08); - writeReg(GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); - writeReg(ALGO_PHASECAL_CONFIG_TIMEOUT, 0x09); - writeReg(0xFF, 0x01); - writeReg(ALGO_PHASECAL_LIM, 0x20); - writeReg(0xFF, 0x00); - break; - - case 12: - writeReg(FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x38); - writeReg(FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08); - writeReg(GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); - writeReg(ALGO_PHASECAL_CONFIG_TIMEOUT, 0x08); - writeReg(0xFF, 0x01); - writeReg(ALGO_PHASECAL_LIM, 0x20); - writeReg(0xFF, 0x00); - break; - - case 14: - writeReg(FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x48); - writeReg(FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08); - writeReg(GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); - writeReg(ALGO_PHASECAL_CONFIG_TIMEOUT, 0x07); - writeReg(0xFF, 0x01); - writeReg(ALGO_PHASECAL_LIM, 0x20); - writeReg(0xFF, 0x00); - break; - - default: - // invalid period - return false; - } - - // apply new VCSEL period - writeReg(FINAL_RANGE_CONFIG_VCSEL_PERIOD, vcsel_period_reg); - - // update timeouts - - // set_sequence_step_timeout() begin - // (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE) - - // "For the final range timeout, the pre-range timeout - // must be added. To do this both final and pre-range - // timeouts must be expressed in macro periods MClks - // because they have different vcsel periods." - - uint16_t new_final_range_timeout_mclks = - timeoutMicrosecondsToMclks(timeouts.final_range_us, period_pclks); - - if (enables.pre_range) - { - new_final_range_timeout_mclks += timeouts.pre_range_mclks; - } - - writeReg16Bit(FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, - encodeTimeout(new_final_range_timeout_mclks)); - - // set_sequence_step_timeout end - } - else - { - // invalid type - return false; - } - - // "Finally, the timing budget must be re-applied" - - setMeasurementTimingBudget(measurement_timing_budget_us); - - // "Perform the phase calibration. This is needed after changing on vcsel period." - // VL53L0X_perform_phase_calibration() begin - - uint8_t sequence_config = readReg(SYSTEM_SEQUENCE_CONFIG); - writeReg(SYSTEM_SEQUENCE_CONFIG, 0x02); - performSingleRefCalibration(0x0); - writeReg(SYSTEM_SEQUENCE_CONFIG, sequence_config); - - // VL53L0X_perform_phase_calibration() end - - return true; -} - -// Get the VCSEL pulse period in PCLKs for the given period type. -// based on VL53L0X_get_vcsel_pulse_period() -uint8_t VL53L0X::getVcselPulsePeriod(vcselPeriodType type) -{ - if (type == VcselPeriodPreRange) - { - return decodeVcselPeriod(readReg(PRE_RANGE_CONFIG_VCSEL_PERIOD)); - } - else if (type == VcselPeriodFinalRange) - { - return decodeVcselPeriod(readReg(FINAL_RANGE_CONFIG_VCSEL_PERIOD)); - } - else { return 255; } -} - -// Start continuous ranging measurements. If period_ms (optional) is 0 or not -// given, continuous back-to-back mode is used (the sensor takes measurements as -// often as possible); otherwise, continuous timed mode is used, with the given -// inter-measurement period in milliseconds determining how often the sensor -// takes a measurement. -// based on VL53L0X_StartMeasurement() -void VL53L0X::startContinuous(uint32_t period_ms) -{ - writeReg(0x80, 0x01); - writeReg(0xFF, 0x01); - writeReg(0x00, 0x00); - writeReg(0x91, stop_variable); - writeReg(0x00, 0x01); - writeReg(0xFF, 0x00); - writeReg(0x80, 0x00); - - if (period_ms != 0) - { - // continuous timed mode - - // VL53L0X_SetInterMeasurementPeriodMilliSeconds() begin - - uint16_t osc_calibrate_val = readReg16Bit(OSC_CALIBRATE_VAL); - - if (osc_calibrate_val != 0) - { - period_ms *= osc_calibrate_val; - } - - writeReg32Bit(SYSTEM_INTERMEASUREMENT_PERIOD, period_ms); - - // VL53L0X_SetInterMeasurementPeriodMilliSeconds() end - - writeReg(SYSRANGE_START, 0x04); // VL53L0X_REG_SYSRANGE_MODE_TIMED - } - else - { - // continuous back-to-back mode - writeReg(SYSRANGE_START, 0x02); // VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK - } -} - -// Stop continuous measurements -// based on VL53L0X_StopMeasurement() -void VL53L0X::stopContinuous() -{ - writeReg(SYSRANGE_START, 0x01); // VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT - - writeReg(0xFF, 0x01); - writeReg(0x00, 0x00); - writeReg(0x91, 0x00); - writeReg(0x00, 0x01); - writeReg(0xFF, 0x00); -} - -// Returns a range reading in millimeters when continuous mode is active -// (readRangeSingleMillimeters() also calls this function after starting a -// single-shot range measurement) -uint16_t VL53L0X::readRangeContinuousMillimeters() -{ - startTimeout(); - while ((readReg(RESULT_INTERRUPT_STATUS) & 0x07) == 0) - { - if (checkTimeoutExpired()) - { - did_timeout = true; - return 65535; - } - } - - // assumptions: Linearity Corrective Gain is 1000 (default); - // fractional ranging is not enabled - uint16_t range = readReg16Bit(RESULT_RANGE_STATUS + 10); - - writeReg(SYSTEM_INTERRUPT_CLEAR, 0x01); - - return range; -} - -// Performs a single-shot range measurement and returns the reading in -// millimeters -// based on VL53L0X_PerformSingleRangingMeasurement() -uint16_t VL53L0X::readRangeSingleMillimeters() -{ - writeReg(0x80, 0x01); - writeReg(0xFF, 0x01); - writeReg(0x00, 0x00); - writeReg(0x91, stop_variable); - writeReg(0x00, 0x01); - writeReg(0xFF, 0x00); - writeReg(0x80, 0x00); - - writeReg(SYSRANGE_START, 0x01); - - // "Wait until start bit has been cleared" - startTimeout(); - while (readReg(SYSRANGE_START) & 0x01) - { - if (checkTimeoutExpired()) - { - did_timeout = true; - return 65535; - } - } - - return readRangeContinuousMillimeters(); -} - -// Did a timeout occur in one of the read functions since the last call to -// timeoutOccurred()? -bool VL53L0X::timeoutOccurred() -{ - bool tmp = did_timeout; - did_timeout = false; - return tmp; -} - -// Private Methods ///////////////////////////////////////////////////////////// - -// Get reference SPAD (single photon avalanche diode) count and type -// based on VL53L0X_get_info_from_device(), -// but only gets reference SPAD count and type -bool VL53L0X::getSpadInfo(uint8_t * count, bool * type_is_aperture) -{ - uint8_t tmp; - - writeReg(0x80, 0x01); - writeReg(0xFF, 0x01); - writeReg(0x00, 0x00); - - writeReg(0xFF, 0x06); - writeReg(0x83, readReg(0x83) | 0x04); - writeReg(0xFF, 0x07); - writeReg(0x81, 0x01); - - writeReg(0x80, 0x01); - - writeReg(0x94, 0x6b); - writeReg(0x83, 0x00); - startTimeout(); - while (readReg(0x83) == 0x00) - { - if (checkTimeoutExpired()) { return false; } - } - writeReg(0x83, 0x01); - tmp = readReg(0x92); - - *count = tmp & 0x7f; - *type_is_aperture = (tmp >> 7) & 0x01; - - writeReg(0x81, 0x00); - writeReg(0xFF, 0x06); - writeReg(0x83, readReg(0x83) & ~0x04); - writeReg(0xFF, 0x01); - writeReg(0x00, 0x01); - - writeReg(0xFF, 0x00); - writeReg(0x80, 0x00); - - return true; -} - -// Get sequence step enables -// based on VL53L0X_GetSequenceStepEnables() -void VL53L0X::getSequenceStepEnables(SequenceStepEnables * enables) -{ - uint8_t sequence_config = readReg(SYSTEM_SEQUENCE_CONFIG); - - enables->tcc = (sequence_config >> 4) & 0x1; - enables->dss = (sequence_config >> 3) & 0x1; - enables->msrc = (sequence_config >> 2) & 0x1; - enables->pre_range = (sequence_config >> 6) & 0x1; - enables->final_range = (sequence_config >> 7) & 0x1; -} - -// Get sequence step timeouts -// based on get_sequence_step_timeout(), -// but gets all timeouts instead of just the requested one, and also stores -// intermediate values -void VL53L0X::getSequenceStepTimeouts(SequenceStepEnables const * enables, SequenceStepTimeouts * timeouts) -{ - timeouts->pre_range_vcsel_period_pclks = getVcselPulsePeriod(VcselPeriodPreRange); - - timeouts->msrc_dss_tcc_mclks = readReg(MSRC_CONFIG_TIMEOUT_MACROP) + 1; - timeouts->msrc_dss_tcc_us = - timeoutMclksToMicroseconds(timeouts->msrc_dss_tcc_mclks, - timeouts->pre_range_vcsel_period_pclks); - - timeouts->pre_range_mclks = - decodeTimeout(readReg16Bit(PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI)); - timeouts->pre_range_us = - timeoutMclksToMicroseconds(timeouts->pre_range_mclks, - timeouts->pre_range_vcsel_period_pclks); - - timeouts->final_range_vcsel_period_pclks = getVcselPulsePeriod(VcselPeriodFinalRange); - - timeouts->final_range_mclks = - decodeTimeout(readReg16Bit(FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI)); - - if (enables->pre_range) - { - timeouts->final_range_mclks -= timeouts->pre_range_mclks; - } - - timeouts->final_range_us = - timeoutMclksToMicroseconds(timeouts->final_range_mclks, - timeouts->final_range_vcsel_period_pclks); -} - -// Decode sequence step timeout in MCLKs from register value -// based on VL53L0X_decode_timeout() -// Note: the original function returned a uint32_t, but the return value is -// always stored in a uint16_t. -uint16_t VL53L0X::decodeTimeout(uint16_t reg_val) -{ - // format: "(LSByte * 2^MSByte) + 1" - return (uint16_t)((reg_val & 0x00FF) << - (uint16_t)((reg_val & 0xFF00) >> 8)) + 1; -} - -// Encode sequence step timeout register value from timeout in MCLKs -// based on VL53L0X_encode_timeout() -uint16_t VL53L0X::encodeTimeout(uint32_t timeout_mclks) -{ - // format: "(LSByte * 2^MSByte) + 1" - - uint32_t ls_byte = 0; - uint16_t ms_byte = 0; - - if (timeout_mclks > 0) - { - ls_byte = timeout_mclks - 1; - - while ((ls_byte & 0xFFFFFF00) > 0) - { - ls_byte >>= 1; - ms_byte++; - } - - return (ms_byte << 8) | (ls_byte & 0xFF); - } - else { return 0; } -} - -// Convert sequence step timeout from MCLKs to microseconds with given VCSEL period in PCLKs -// based on VL53L0X_calc_timeout_us() -uint32_t VL53L0X::timeoutMclksToMicroseconds(uint16_t timeout_period_mclks, uint8_t vcsel_period_pclks) -{ - uint32_t macro_period_ns = calcMacroPeriod(vcsel_period_pclks); - - return ((timeout_period_mclks * macro_period_ns) + 500) / 1000; -} - -// Convert sequence step timeout from microseconds to MCLKs with given VCSEL period in PCLKs -// based on VL53L0X_calc_timeout_mclks() -uint32_t VL53L0X::timeoutMicrosecondsToMclks(uint32_t timeout_period_us, uint8_t vcsel_period_pclks) -{ - uint32_t macro_period_ns = calcMacroPeriod(vcsel_period_pclks); - - return (((timeout_period_us * 1000) + (macro_period_ns / 2)) / macro_period_ns); -} - - -// based on VL53L0X_perform_single_ref_calibration() -bool VL53L0X::performSingleRefCalibration(uint8_t vhv_init_byte) -{ - writeReg(SYSRANGE_START, 0x01 | vhv_init_byte); // VL53L0X_REG_SYSRANGE_MODE_START_STOP - - startTimeout(); - while ((readReg(RESULT_INTERRUPT_STATUS) & 0x07) == 0) - { - if (checkTimeoutExpired()) { return false; } - } - - writeReg(SYSTEM_INTERRUPT_CLEAR, 0x01); - - writeReg(SYSRANGE_START, 0x00); - - return true; -} diff --git a/VL53L0X/VL53L0X.h b/VL53L0X/VL53L0X.h deleted file mode 100644 index 0e861d6ddec0be90ef77d99415edcb0250682d73..0000000000000000000000000000000000000000 --- a/VL53L0X/VL53L0X.h +++ /dev/null @@ -1,181 +0,0 @@ -#ifndef VL53L0X_h -#define VL53L0X_h - -#include <Arduino.h> -#include <Wire.h> - -class VL53L0X -{ - public: - // register addresses from API vl53l0x_device.h (ordered as listed there) - enum regAddr - { - SYSRANGE_START = 0x00, - - SYSTEM_THRESH_HIGH = 0x0C, - SYSTEM_THRESH_LOW = 0x0E, - - SYSTEM_SEQUENCE_CONFIG = 0x01, - SYSTEM_RANGE_CONFIG = 0x09, - SYSTEM_INTERMEASUREMENT_PERIOD = 0x04, - - SYSTEM_INTERRUPT_CONFIG_GPIO = 0x0A, - - GPIO_HV_MUX_ACTIVE_HIGH = 0x84, - - SYSTEM_INTERRUPT_CLEAR = 0x0B, - - RESULT_INTERRUPT_STATUS = 0x13, - RESULT_RANGE_STATUS = 0x14, - - RESULT_CORE_AMBIENT_WINDOW_EVENTS_RTN = 0xBC, - RESULT_CORE_RANGING_TOTAL_EVENTS_RTN = 0xC0, - RESULT_CORE_AMBIENT_WINDOW_EVENTS_REF = 0xD0, - RESULT_CORE_RANGING_TOTAL_EVENTS_REF = 0xD4, - RESULT_PEAK_SIGNAL_RATE_REF = 0xB6, - - ALGO_PART_TO_PART_RANGE_OFFSET_MM = 0x28, - - I2C_SLAVE_DEVICE_ADDRESS = 0x8A, - - MSRC_CONFIG_CONTROL = 0x60, - - PRE_RANGE_CONFIG_MIN_SNR = 0x27, - PRE_RANGE_CONFIG_VALID_PHASE_LOW = 0x56, - PRE_RANGE_CONFIG_VALID_PHASE_HIGH = 0x57, - PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT = 0x64, - - FINAL_RANGE_CONFIG_MIN_SNR = 0x67, - FINAL_RANGE_CONFIG_VALID_PHASE_LOW = 0x47, - FINAL_RANGE_CONFIG_VALID_PHASE_HIGH = 0x48, - FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT = 0x44, - - PRE_RANGE_CONFIG_SIGMA_THRESH_HI = 0x61, - PRE_RANGE_CONFIG_SIGMA_THRESH_LO = 0x62, - - PRE_RANGE_CONFIG_VCSEL_PERIOD = 0x50, - PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI = 0x51, - PRE_RANGE_CONFIG_TIMEOUT_MACROP_LO = 0x52, - - SYSTEM_HISTOGRAM_BIN = 0x81, - HISTOGRAM_CONFIG_INITIAL_PHASE_SELECT = 0x33, - HISTOGRAM_CONFIG_READOUT_CTRL = 0x55, - - FINAL_RANGE_CONFIG_VCSEL_PERIOD = 0x70, - FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI = 0x71, - FINAL_RANGE_CONFIG_TIMEOUT_MACROP_LO = 0x72, - CROSSTALK_COMPENSATION_PEAK_RATE_MCPS = 0x20, - - MSRC_CONFIG_TIMEOUT_MACROP = 0x46, - - SOFT_RESET_GO2_SOFT_RESET_N = 0xBF, - IDENTIFICATION_MODEL_ID = 0xC0, - IDENTIFICATION_REVISION_ID = 0xC2, - - OSC_CALIBRATE_VAL = 0xF8, - - GLOBAL_CONFIG_VCSEL_WIDTH = 0x32, - GLOBAL_CONFIG_SPAD_ENABLES_REF_0 = 0xB0, - GLOBAL_CONFIG_SPAD_ENABLES_REF_1 = 0xB1, - GLOBAL_CONFIG_SPAD_ENABLES_REF_2 = 0xB2, - GLOBAL_CONFIG_SPAD_ENABLES_REF_3 = 0xB3, - GLOBAL_CONFIG_SPAD_ENABLES_REF_4 = 0xB4, - GLOBAL_CONFIG_SPAD_ENABLES_REF_5 = 0xB5, - - GLOBAL_CONFIG_REF_EN_START_SELECT = 0xB6, - DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD = 0x4E, - DYNAMIC_SPAD_REF_EN_START_OFFSET = 0x4F, - POWER_MANAGEMENT_GO1_POWER_FORCE = 0x80, - - VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV = 0x89, - - ALGO_PHASECAL_LIM = 0x30, - ALGO_PHASECAL_CONFIG_TIMEOUT = 0x30, - }; - - enum vcselPeriodType { VcselPeriodPreRange, VcselPeriodFinalRange }; - - uint8_t last_status; // status of last I2C transmission - - VL53L0X(); - - void setBus(TwoWire * bus) { this->bus = bus; } - TwoWire * getBus() { return bus; } - - void setAddress(uint8_t new_addr); - inline uint8_t getAddress() { return address; } - - bool init(bool io_2v8 = true); - - void writeReg(uint8_t reg, uint8_t value); - void writeReg16Bit(uint8_t reg, uint16_t value); - void writeReg32Bit(uint8_t reg, uint32_t value); - uint8_t readReg(uint8_t reg); - uint16_t readReg16Bit(uint8_t reg); - uint32_t readReg32Bit(uint8_t reg); - - void writeMulti(uint8_t reg, uint8_t const * src, uint8_t count); - void readMulti(uint8_t reg, uint8_t * dst, uint8_t count); - - bool setSignalRateLimit(float limit_Mcps); - float getSignalRateLimit(); - - bool setMeasurementTimingBudget(uint32_t budget_us); - uint32_t getMeasurementTimingBudget(); - - bool setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks); - uint8_t getVcselPulsePeriod(vcselPeriodType type); - - void startContinuous(uint32_t period_ms = 0); - void stopContinuous(); - uint16_t readRangeContinuousMillimeters(); - uint16_t readRangeSingleMillimeters(); - - inline void setTimeout(uint16_t timeout) { io_timeout = timeout; } - inline uint16_t getTimeout() { return io_timeout; } - bool timeoutOccurred(); - - private: - // TCC: Target CentreCheck - // MSRC: Minimum Signal Rate Check - // DSS: Dynamic Spad Selection - - struct SequenceStepEnables - { - boolean tcc, msrc, dss, pre_range, final_range; - }; - - struct SequenceStepTimeouts - { - uint16_t pre_range_vcsel_period_pclks, final_range_vcsel_period_pclks; - - uint16_t msrc_dss_tcc_mclks, pre_range_mclks, final_range_mclks; - uint32_t msrc_dss_tcc_us, pre_range_us, final_range_us; - }; - - TwoWire * bus; - uint8_t address; - uint16_t io_timeout; - bool did_timeout; - uint16_t timeout_start_ms; - - uint8_t stop_variable; // read by init and used when starting measurement; is StopVariable field of VL53L0X_DevData_t structure in API - uint32_t measurement_timing_budget_us; - - bool getSpadInfo(uint8_t * count, bool * type_is_aperture); - - void getSequenceStepEnables(SequenceStepEnables * enables); - void getSequenceStepTimeouts(SequenceStepEnables const * enables, SequenceStepTimeouts * timeouts); - - bool performSingleRefCalibration(uint8_t vhv_init_byte); - - static uint16_t decodeTimeout(uint16_t value); - static uint16_t encodeTimeout(uint32_t timeout_mclks); - static uint32_t timeoutMclksToMicroseconds(uint16_t timeout_period_mclks, uint8_t vcsel_period_pclks); - static uint32_t timeoutMicrosecondsToMclks(uint32_t timeout_period_us, uint8_t vcsel_period_pclks); -}; - -#endif - - - diff --git a/VL53L0X/examples/Continuous/Continuous.ino b/VL53L0X/examples/Continuous/Continuous.ino deleted file mode 100644 index 9f33216179d6c24045c8e4291d508507a2d9408a..0000000000000000000000000000000000000000 --- a/VL53L0X/examples/Continuous/Continuous.ino +++ /dev/null @@ -1,37 +0,0 @@ -/* This example shows how to use continuous mode to take -range measurements with the VL53L0X. It is based on -vl53l0x_ContinuousRanging_Example.c from the VL53L0X API. - -The range readings are in units of mm. */ - -#include <Wire.h> -#include <VL53L0X.h> - -VL53L0X sensor; - -void setup() -{ - Serial.begin(9600); - Wire.begin(); - - sensor.setTimeout(500); - if (!sensor.init()) - { - Serial.println("Failed to detect and initialize sensor!"); - while (1) {} - } - - // Start continuous back-to-back mode (take readings as - // fast as possible). To use continuous timed mode - // instead, provide a desired inter-measurement period in - // ms (e.g. sensor.startContinuous(100)). - sensor.startContinuous(); -} - -void loop() -{ - Serial.print(sensor.readRangeContinuousMillimeters()); - if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); } - - Serial.println(); -} diff --git a/VL53L0X/examples/Single/Single.ino b/VL53L0X/examples/Single/Single.ino deleted file mode 100644 index 3291ba9a59856e6eaff5a447dc7a682c65a969bd..0000000000000000000000000000000000000000 --- a/VL53L0X/examples/Single/Single.ino +++ /dev/null @@ -1,69 +0,0 @@ -/* This example shows how to get single-shot range - measurements from the VL53L0X. The sensor can optionally be - configured with different ranging profiles, as described in - the VL53L0X API user manual, to get better performance for - a certain application. This code is based on the four - "SingleRanging" examples in the VL53L0X API. - - The range readings are in units of mm. */ - -#include <Wire.h> -#include <VL53L0X.h> - -VL53L0X sensor; - - -// Uncomment this line to use long range mode. This -// increases the sensitivity of the sensor and extends its -// potential range, but increases the likelihood of getting -// an inaccurate reading because of reflections from objects -// other than the intended target. It works best in dark -// conditions. - -//#define LONG_RANGE - - -// Uncomment ONE of these two lines to get -// - higher speed at the cost of lower accuracy OR -// - higher accuracy at the cost of lower speed - -//#define HIGH_SPEED -//#define HIGH_ACCURACY - - -void setup() -{ - Serial.begin(9600); - Wire.begin(); - - sensor.setTimeout(500); - if (!sensor.init()) - { - Serial.println("Failed to detect and initialize sensor!"); - while (1) {} - } - -#if defined LONG_RANGE - // lower the return signal rate limit (default is 0.25 MCPS) - sensor.setSignalRateLimit(0.1); - // increase laser pulse periods (defaults are 14 and 10 PCLKs) - sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18); - sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14); -#endif - -#if defined HIGH_SPEED - // reduce timing budget to 20 ms (default is about 33 ms) - sensor.setMeasurementTimingBudget(20000); -#elif defined HIGH_ACCURACY - // increase timing budget to 200 ms - sensor.setMeasurementTimingBudget(200000); -#endif -} - -void loop() -{ - Serial.print(sensor.readRangeSingleMillimeters()); - if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); } - - Serial.println(); -} diff --git a/VL53L0X/keywords.txt b/VL53L0X/keywords.txt deleted file mode 100644 index 437add908642118593bc55887e63571f921fd0fd..0000000000000000000000000000000000000000 --- a/VL53L0X/keywords.txt +++ /dev/null @@ -1,90 +0,0 @@ -VL53L0X KEYWORD1 - -setAddress KEYWORD2 -getAddress KEYWORD2 -init KEYWORD2 -writeReg KEYWORD2 -writeReg16Bit KEYWORD2 -writeReg32Bit KEYWORD2 -readReg KEYWORD2 -readReg16Bit KEYWORD2 -readReg32Bit KEYWORD2 -writeMulti KEYWORD2 -readMulti KEYWORD2 -setSignalRateLimit KEYWORD2 -getSignalRateLimit KEYWORD2 -setMeasurementTimingBudget KEYWORD2 -getMeasurementTimingBudget KEYWORD2 -setVcselPulsePeriod KEYWORD2 -getVcselPulsePeriod KEYWORD2 -startContinuous KEYWORD2 -stopContinuous KEYWORD2 -readRangeContinuousMillimeters KEYWORD2 -readRangeSingleMillimeters KEYWORD2 -setTimeout KEYWORD2 -getTimeout KEYWORD2 -timeoutOccurred KEYWORD2 - -SYSRANGE_START LITERAL1 -SYSTEM_THRESH_HIGH LITERAL1 -SYSTEM_THRESH_LOW LITERAL1 -SYSTEM_SEQUENCE_CONFIG LITERAL1 -SYSTEM_RANGE_CONFIG LITERAL1 -SYSTEM_INTERMEASUREMENT_PERIOD LITERAL1 -SYSTEM_INTERRUPT_CONFIG_GPIO LITERAL1 -GPIO_HV_MUX_ACTIVE_HIGH LITERAL1 -SYSTEM_INTERRUPT_CLEAR LITERAL1 -RESULT_INTERRUPT_STATUS LITERAL1 -RESULT_RANGE_STATUS LITERAL1 -RESULT_CORE_AMBIENT_WINDOW_EVENTS_RTN LITERAL1 -RESULT_CORE_RANGING_TOTAL_EVENTS_RTN LITERAL1 -RESULT_CORE_AMBIENT_WINDOW_EVENTS_REF LITERAL1 -RESULT_CORE_RANGING_TOTAL_EVENTS_REF LITERAL1 -RESULT_PEAK_SIGNAL_RATE_REF LITERAL1 -ALGO_PART_TO_PART_RANGE_OFFSET_MM LITERAL1 -I2C_SLAVE_DEVICE_ADDRESS LITERAL1 -MSRC_CONFIG_CONTROL LITERAL1 -PRE_RANGE_CONFIG_MIN_SNR LITERAL1 -PRE_RANGE_CONFIG_VALID_PHASE_LOW LITERAL1 -PRE_RANGE_CONFIG_VALID_PHASE_HIGH LITERAL1 -PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT LITERAL1 -FINAL_RANGE_CONFIG_MIN_SNR LITERAL1 -FINAL_RANGE_CONFIG_VALID_PHASE_LOW LITERAL1 -FINAL_RANGE_CONFIG_VALID_PHASE_HIGH LITERAL1 -FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT LITERAL1 -PRE_RANGE_CONFIG_SIGMA_THRESH_HI LITERAL1 -PRE_RANGE_CONFIG_SIGMA_THRESH_LO LITERAL1 -PRE_RANGE_CONFIG_VCSEL_PERIOD LITERAL1 -PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI LITERAL1 -PRE_RANGE_CONFIG_TIMEOUT_MACROP_LO LITERAL1 -SYSTEM_HISTOGRAM_BIN LITERAL1 -HISTOGRAM_CONFIG_INITIAL_PHASE_SELECT LITERAL1 -HISTOGRAM_CONFIG_READOUT_CTRL LITERAL1 -FINAL_RANGE_CONFIG_VCSEL_PERIOD LITERAL1 -FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI LITERAL1 -FINAL_RANGE_CONFIG_TIMEOUT_MACROP_LO LITERAL1 -CROSSTALK_COMPENSATION_PEAK_RATE_MCPS LITERAL1 -MSRC_CONFIG_TIMEOUT_MACROP LITERAL1 -SOFT_RESET_GO2_SOFT_RESET_N LITERAL1 -IDENTIFICATION_MODEL_ID LITERAL1 -IDENTIFICATION_REVISION_ID LITERAL1 -OSC_CALIBRATE_VAL LITERAL1 -GLOBAL_CONFIG_VCSEL_WIDTH LITERAL1 -GLOBAL_CONFIG_SPAD_ENABLES_REF_0 LITERAL1 -GLOBAL_CONFIG_SPAD_ENABLES_REF_1 LITERAL1 -GLOBAL_CONFIG_SPAD_ENABLES_REF_2 LITERAL1 -GLOBAL_CONFIG_SPAD_ENABLES_REF_3 LITERAL1 -GLOBAL_CONFIG_SPAD_ENABLES_REF_4 LITERAL1 -GLOBAL_CONFIG_SPAD_ENABLES_REF_5 LITERAL1 -GLOBAL_CONFIG_REF_EN_START_SELECT LITERAL1 -DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD LITERAL1 -DYNAMIC_SPAD_REF_EN_START_OFFSET LITERAL1 -POWER_MANAGEMENT_GO1_POWER_FORCE LITERAL1 -VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV LITERAL1 -ALGO_PHASECAL_LIM LITERAL1 -ALGO_PHASECAL_CONFIG_TIMEOUT LITERAL1 - -VcselPeriodPreRange LITERAL1 -VcselPeriodFinalRange LITERAL1 - - diff --git a/VL53L0X/library.properties b/VL53L0X/library.properties deleted file mode 100644 index ab4a22d9f02799221bf2e04a310ded99b9a7afbf..0000000000000000000000000000000000000000 --- a/VL53L0X/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=VL53L0X -version=1.3.1 -author=Pololu -maintainer=Pololu <inbox@pololu.com> -sentence=VL53L0X distance sensor library -paragraph=This is a library for the Arduino IDE that helps interface with ST's VL53L0X distance sensor. -category=Sensors -url=https://github.com/pololu/vl53l0x-arduino -architectures=* diff --git a/bits_motor_driver b/bits_motor_driver deleted file mode 160000 index 4a41ce64869b02cd7860077d9641f6b5ca2aa310..0000000000000000000000000000000000000000 --- a/bits_motor_driver +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4a41ce64869b02cd7860077d9641f6b5ca2aa310 diff --git a/bits_time_of_flight_controller b/bits_time_of_flight_controller deleted file mode 160000 index 018017f255c3b9f22f1affed13426ef626c92bb6..0000000000000000000000000000000000000000 --- a/bits_time_of_flight_controller +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 018017f255c3b9f22f1affed13426ef626c92bb6 diff --git a/mpu6050 b/mpu6050 deleted file mode 160000 index 0281cd4532b36922f4d68a4cae70eca7aebe9988..0000000000000000000000000000000000000000 --- a/mpu6050 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0281cd4532b36922f4d68a4cae70eca7aebe9988 diff --git a/mpu6050-master/.github/FUNDING.yml b/mpu6050-master/.github/FUNDING.yml deleted file mode 100644 index ccea6b625aa9d4cc7c74ca16b6ce7345885cc2db..0000000000000000000000000000000000000000 --- a/mpu6050-master/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=TSVUYKBK29H52&source=url diff --git a/mpu6050-master/.github/ISSUE_TEMPLATE/BUG_REPORT_EC.md b/mpu6050-master/.github/ISSUE_TEMPLATE/BUG_REPORT_EC.md deleted file mode 100644 index 80922aeda754f56d8c6c8ea342592cba0063a3e8..0000000000000000000000000000000000000000 --- a/mpu6050-master/.github/ISSUE_TEMPLATE/BUG_REPORT_EC.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -name: "\U0001F640 Bug report " -about: Report a bug or unexpected behavior while using the MPU6050 library -title: 'ElectronicCats' -labels: bug ---- - -**Please, before reporting any issue** -- Make sure your board it's in good condition. -- Make sure your MPU6050 it's in good condition. -- Verify that it really is a library problem and not a hardware problem. -- **Avoid** to submit a GitHub issue for project troubleshooting. - -Any feedback/suggestions should be discussed on the [feedback section](https://github.com/ElectronicCats/mpu6050/issues): - * Just click on New Issue and select the correct category. - -When reporting any issue, please try to provide all relevant information to help on its resolution. - - -**Describe the bug** -A clear and concise description of what the bug is. -The more detailed this is, the easier we can come up with a solution. - - -**To Reproduce** -Complete source code which can be used to reproduce the issue. Please try to be as generic as possible. -No extra code, extra hardware, etc. -If you think it is absolutely necessary to add this, mention in detail the connections in case it is necessary hardware and also indicate the part of code that was added and how it was added. - - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**To help us to understand your situation, we would like to ask you for the following additional information::** - - Which board are you using? - - What Operating System and version are you using (e.g. Windows 11, macOS 12.0, Linux)? - - In case you are using the Arduino IDE, What version of the Arduino IDE? - - Did it work before?, If it worked before, what were the parameters that you modify? - - -**Additional context** -Add any other context about the problem here that you think will help us to solve your problem. \ No newline at end of file diff --git a/mpu6050-master/.github/ISSUE_TEMPLATE/Feedback-request.md b/mpu6050-master/.github/ISSUE_TEMPLATE/Feedback-request.md deleted file mode 100644 index 5b57a7aa16afa63eed6fc03028e46fe11b9b4e12..0000000000000000000000000000000000000000 --- a/mpu6050-master/.github/ISSUE_TEMPLATE/Feedback-request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: "\U0001F408 Feddback or requests" -about: Suggest an idea or improvement for this project -title: 'ElectronicCats' -labels: 'enhancement' ---- - -**What idea or improvement for the library has occurred to you?** - -**If you found an error:** - -Please describe clearly and concisely the problem you are aware of. - - -**Have you already found a solution?** - -If you found a way to fix the problem please let us know. -It would be very helpful if you put the part of the code that needs to be corrected and how it needs to be corrected. - -***Thanks a lot*** \ No newline at end of file diff --git a/mpu6050-master/.github/ISSUE_TEMPLATE/config.yml b/mpu6050-master/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index fbf87f78b165446dd1a8e723db14a0aa19e9c63f..0000000000000000000000000000000000000000 --- a/mpu6050-master/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: See if your issue is solved before creating a new one. - about: Try to see if ther is an answer for yoru questions before you create a new issue. - url: https://github.com/ElectronicCats/mpu6050/issues?q=is%3Aissue+is%3Aclosed - - name: ElectronicCats - about: Contact us through our website - url: https://electroniccats.com/contact/ \ No newline at end of file diff --git a/mpu6050-master/.github/stale.yml b/mpu6050-master/.github/stale.yml deleted file mode 100644 index 9eb36fbf32765b4e9e77ee1313ad87048ef989a8..0000000000000000000000000000000000000000 --- a/mpu6050-master/.github/stale.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 5 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 3 -# Issues with these labels will never be considered stale -exemptLabels: -- Bug -- Quality -- Feedback -- Libraries -- Feature request -# Label to use when marking an issue as stale -staleLabel: First warning -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This is a message to remind you that your request has been pending for 5 days and awaits your comments. - - Our agent would like to hear from you about your previous request to see if the difficulty - you were facing has been resolved or if we can provide further assistance. - Otherwise, if we do not hear back from you within the next three days, the issue will be closed. - - Kind regards, - Electronic Cats Support Team -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false -# Limit to only `issues` or `pulls` -only: issues diff --git a/mpu6050-master/.github/workflows/LibraryBuild.yml b/mpu6050-master/.github/workflows/LibraryBuild.yml deleted file mode 100644 index adce56c1f34822cd277b51def330056ae7a8968c..0000000000000000000000000000000000000000 --- a/mpu6050-master/.github/workflows/LibraryBuild.yml +++ /dev/null @@ -1,79 +0,0 @@ -# LibraryBuild.yml -# Github workflow script to test compile all examples of an Arduino library repository. -# -# Copyright (C) 2020 Armin Joachimsmeyer -# https://github.com/ArminJo/Github-Actions -# - -# This is the name of the workflow, visible on GitHub UI. -name: LibraryBuild -on: [push, pull_request] # see: https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-event-pull_request - -jobs: - build: - name: ${{ matrix.arduino-boards-fqbn }} - test compiling examples - - runs-on: ubuntu-latest # I picked Ubuntu to use shell scripts. - - env: - # Comma separated list without double quotes around the list. - REQUIRED_LIBRARIES: OSC,WiFiManager - - strategy: - matrix: - # The matrix will produce one job for each configuration parameter of type `arduino-boards-fqbn` - # In the Arduino IDE, the fqbn is printed in the first line of the verbose output for compilation as parameter -fqbn=... for the "arduino-builder -dump-prefs" command - # - # Examples: arduino:avr:uno, arduino:avr:leonardo, arduino:avr:nano, arduino:avr:mega - # arduino:sam:arduino_due_x, arduino:samd:arduino_zero_native" - # ATTinyCore:avr:attinyx5:chip=85,clock=1internal, digistump:avr:digispark-tiny, digistump:avr:digispark-pro - # STM32:stm32:GenF1:pnum=BLUEPILL_F103C8 - # esp8266:esp8266:huzzah:eesz=4M3M,xtal=80, esp32:esp32:featheresp32:FlashFreq=80 - # You may add a suffix behind the fqbn with "|" to specify one board for e.g. different compile options like arduino:avr:uno|trace - ############################################################################################################# - arduino-boards-fqbn: - - arduino:avr:uno - - arduino:avr:leonardo - - arduino:samd:nano_33_iot - - esp8266:esp8266:huzzah:eesz=4M3M,xtal=80 - - esp32:esp32:featheresp32:FlashFreq=80 - - # Specify parameters for each board. - # Parameters can be: platform-url, sketches-exclude and examples-build-properties - # With sketches-exclude you may exclude specific examples for a board. Use a space separated list. - ############################################################################################################# - include: - - arduino-boards-fqbn: arduino:avr:uno - sketches-exclude: MPU6050_DMP6_ESPWiFi,MPU6050_DMP6_Ethernet - - - arduino-boards-fqbn: arduino:avr:leonardo - sketches-exclude: MPU6050_DMP6_ESPWiFi,MPU6050_DMP6_Ethernet - - - arduino-boards-fqbn: arduino:samd:nano_33_iot - sketches-exclude: MPU6050_DMP6_ESPWiFi,MPU6050_DMP6_Ethernet - - - arduino-boards-fqbn: esp8266:esp8266:huzzah:eesz=4M3M,xtal=80 - platform-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json - sketches-exclude: MPU6050_DMP6_Ethernet - - - arduino-boards-fqbn: esp32:esp32:featheresp32:FlashFreq=80 - platform-url: https://dl.espressif.com/dl/package_esp32_index.json - sketches-exclude: MPU6050_DMP6_Ethernet - - # Do not cancel all jobs / architectures if one job fails - fail-fast: false - - # This is the list of steps this job will run. - steps: - - # First of all, we clone the repo using the `checkout` action. - - name: Checkout - uses: actions/checkout@master - - - name: Compile all examples - uses: ArminJo/arduino-test-compile@v3 - with: - arduino-board-fqbn: ${{ matrix.arduino-boards-fqbn }} - required-libraries: ${{ env.REQUIRED_LIBRARIES }} - platform-url: ${{ matrix.platform-url }} - sketches-exclude: ${{ matrix.sketches-exclude }} diff --git a/mpu6050-master/.github/workflows/arduino-lint.yml b/mpu6050-master/.github/workflows/arduino-lint.yml deleted file mode 100644 index 5c3ac0183c24b58ce842e01fab9c276ca45c3465..0000000000000000000000000000000000000000 --- a/mpu6050-master/.github/workflows/arduino-lint.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: arduino-lint -on: [push, pull_request] -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: arduino/arduino-lint-action@v1 - with: - # path: ./ - version: 1.x - compliance: strict - library-manager: update - project-type: library - recursive: true - # report-file: - verbose: false \ No newline at end of file diff --git a/mpu6050-master/.gitignore b/mpu6050-master/.gitignore deleted file mode 100644 index 0485ba8f6b07aff0aaa8ae8d20e6723bcb365a36..0000000000000000000000000000000000000000 --- a/mpu6050-master/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ - -\.DS_Store diff --git a/mpu6050-master/LICENSE b/mpu6050-master/LICENSE deleted file mode 100644 index 669a814cca1e57ecd8bde04e9a19521c8136a2ec..0000000000000000000000000000000000000000 --- a/mpu6050-master/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 ElectronicCats - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/mpu6050-master/README.md b/mpu6050-master/README.md deleted file mode 100644 index ac38993b130735ac68d06fb8cbddadacca809884..0000000000000000000000000000000000000000 --- a/mpu6050-master/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# MPU6050 by Electronic Cats - Library for Arduino -[](https://github.com/ElectronicCats/mpu6050/actions/workflows/LibraryBuild.yml) - -Arduino library for controlling MPU6050 module. - -MPU6050 Combines a 3-axis gyroscope and a 3-axis accelerometer on the same silicon die together with -an onboard Digital Motion Processor(DMP) which processes complex 6-axis MotionFusion algorithms. - -## Features of this version - -- ### Supported Chipsets - - AVR - - SAM - - SAMD21 - - ARM - - ESP32 - - ESP8266 - - RENESAS - - -#### Original Library - -Based in the work of [jrowberg/i2cdevlib](https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050) - -## Quick Installing - -To install, use the [Arduino Library Manager](https://support.arduino.cc/hc/en-us/articles/5145457742236-Add-libraries-to-Arduino-IDE) and search for "MPU6050" and install the MPU6050 by Electronic Cats library. - -## Wiki and Getting Started -For more information please visit: [**Getting Started in our Wiki**](https://github.com/ElectronicCats/mpu6050/wiki) - -<a href="https://github.com/ElectronicCats/mpu6050/wiki"> - <img src="https://user-images.githubusercontent.com/107638696/241324971-43b8fe88-447d-4c2d-9296-4b3aaa50f4ce.png" height="400" /> -</a> - - -## Maintainer - -<a href="https://github.com/sponsors/ElectronicCats"> - <p align="center"> - <img src="https://electroniccats.com/wp-content/uploads/2020/07/Badge_GHS.png" height="104" /> - </p> -</a> - -Electronic Cats invests time and resources providing this open source design, please support Electronic Cats and open-source hardware by purchasing products from Electronic Cats! \ No newline at end of file diff --git a/mpu6050-master/examples/IMU_Zero/IMU_Zero.ino b/mpu6050-master/examples/IMU_Zero/IMU_Zero.ino deleted file mode 100644 index 8e50b991b47aabfea54b1a291f875d39f3af4f1e..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/IMU_Zero/IMU_Zero.ino +++ /dev/null @@ -1,358 +0,0 @@ -// MPU6050 offset-finder, based on Jeff Rowberg's MPU6050_RAW -// 2016-10-19 by Robert R. Fenichel (bob@fenichel.net) - -// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class -// 10/7/2011 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2019-07-11 - added PID offset generation at begninning Generates first offsets -// - in @ 6 seconds and completes with 4 more sets @ 10 seconds -// - then continues with origional 2016 calibration code. -// 2016-11-25 - added delays to reduce sampling rate to ~200 Hz -// added temporizing printing during long computations -// 2016-10-25 - requires inequality (Low < Target, High > Target) during expansion -// dynamic speed change when closing in -// 2016-10-22 - cosmetic changes -// 2016-10-19 - initial release of IMU_Zero -// 2013-05-08 - added multiple output formats -// - added seamless Fastwire support -// 2011-10-07 - initial release of MPU6050_RAW - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2011 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - If an MPU6050 - * is an ideal member of its tribe, - * is properly warmed up, - * is at rest in a neutral position, - * is in a location where the pull of gravity is exactly 1g, and - * has been loaded with the best possible offsets, -then it will report 0 for all accelerations and displacements, except for -Z acceleration, for which it will report 16384 (that is, 2^14). Your device -probably won't do quite this well, but good offsets will all get the baseline -outputs close to these target values. - - Put the MPU6050 on a flat and horizontal surface, and leave it operating for -5-10 minutes so its temperature gets stabilized. - - Run this program. A "----- done -----" line will indicate that it has done its best. -With the current accuracy-related constants (NFast = 1000, NSlow = 10000), it will take -a few minutes to get there. - - Along the way, it will generate a dozen or so lines of output, showing that for each -of the 6 desired offsets, it is - * first, trying to find two estimates, one too low and one too high, and - * then, closing in until the bracket can't be made smaller. - - The line just above the "done" line will look something like - [567,567] --> [-1,2] [-2223,-2223] --> [0,1] [1131,1132] --> [16374,16404] [155,156] --> [-1,1] [-25,-24] --> [0,3] [5,6] --> [0,4] -As will have been shown in interspersed header lines, the six groups making up this -line describe the optimum offsets for the X acceleration, Y acceleration, Z acceleration, -X gyro, Y gyro, and Z gyro, respectively. In the sample shown just above, the trial showed -that +567 was the best offset for the X acceleration, -2223 was best for Y acceleration, -and so on. - - The need for the delay between readings (usDelay) was brought to my attention by Nikolaus Doppelhammer. -=============================================== -*/ - -// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files -// for both classes must be in the include path of your project -#include "I2Cdev.h" -#include "MPU6050.h" - -// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation -// is used in I2Cdev.h -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - #include "Wire.h" -#endif - -// class default I2C address is 0x68 -// specific I2C addresses may be passed as a parameter here -// AD0 low = 0x68 (default for InvenSense evaluation board) -// AD0 high = 0x69 -MPU6050 accelgyro; -//MPU6050 accelgyro(0x69); // <-- use for AD0 high - - -const char LBRACKET = '['; -const char RBRACKET = ']'; -const char COMMA = ','; -const char BLANK = ' '; -const char PERIOD = '.'; - -const int iAx = 0; -const int iAy = 1; -const int iAz = 2; -const int iGx = 3; -const int iGy = 4; -const int iGz = 5; - -const int usDelay = 3150; // empirical, to hold sampling to 200 Hz -const int NFast = 1000; // the bigger, the better (but slower) -const int NSlow = 10000; // .. -const int LinesBetweenHeaders = 5; - int LowValue[6]; - int HighValue[6]; - int Smoothed[6]; - int LowOffset[6]; - int HighOffset[6]; - int Target[6]; - int LinesOut; - int N; - -void ForceHeader() - { LinesOut = 99; } - -void GetSmoothed() - { int16_t RawValue[6]; - int i; - long Sums[6]; - for (i = iAx; i <= iGz; i++) - { Sums[i] = 0; } -// unsigned long Start = micros(); - - for (i = 1; i <= N; i++) - { // get sums - accelgyro.getMotion6(&RawValue[iAx], &RawValue[iAy], &RawValue[iAz], - &RawValue[iGx], &RawValue[iGy], &RawValue[iGz]); - if ((i % 500) == 0) - Serial.print(PERIOD); - delayMicroseconds(usDelay); - for (int j = iAx; j <= iGz; j++) - Sums[j] = Sums[j] + RawValue[j]; - } // get sums -// unsigned long usForN = micros() - Start; -// Serial.print(" reading at "); -// Serial.print(1000000/((usForN+N/2)/N)); -// Serial.println(" Hz"); - for (i = iAx; i <= iGz; i++) - { Smoothed[i] = (Sums[i] + N/2) / N ; } - } // GetSmoothed - -void Initialize() - { - // join I2C bus (I2Cdev library doesn't do this automatically) - #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - Wire.begin(); - #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE - Fastwire::setup(400, true); - #endif - - Serial.begin(9600); - - // initialize device - Serial.println("Initializing I2C devices..."); - accelgyro.initialize(); - - // verify connection - Serial.println("Testing device connections..."); - Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); - Serial.println("PID tuning Each Dot = 100 readings"); - /*A tidbit on how PID (PI actually) tuning works. - When we change the offset in the MPU6050 we can get instant results. This allows us to use Proportional and - integral of the PID to discover the ideal offsets. Integral is the key to discovering these offsets, Integral - uses the error from set-point (set-point is zero), it takes a fraction of this error (error * ki) and adds it - to the integral value. Each reading narrows the error down to the desired offset. The greater the error from - set-point, the more we adjust the integral value. The proportional does its part by hiding the noise from the - integral math. The Derivative is not used because of the noise and because the sensor is stationary. With the - noise removed the integral value lands on a solid offset after just 600 readings. At the end of each set of 100 - readings, the integral value is used for the actual offsets and the last proportional reading is ignored due to - the fact it reacts to any noise. - */ - accelgyro.CalibrateAccel(6); - accelgyro.CalibrateGyro(6); - Serial.println("\nat 600 Readings"); - accelgyro.PrintActiveOffsets(); - Serial.println(); - accelgyro.CalibrateAccel(1); - accelgyro.CalibrateGyro(1); - Serial.println("700 Total Readings"); - accelgyro.PrintActiveOffsets(); - Serial.println(); - accelgyro.CalibrateAccel(1); - accelgyro.CalibrateGyro(1); - Serial.println("800 Total Readings"); - accelgyro.PrintActiveOffsets(); - Serial.println(); - accelgyro.CalibrateAccel(1); - accelgyro.CalibrateGyro(1); - Serial.println("900 Total Readings"); - accelgyro.PrintActiveOffsets(); - Serial.println(); - accelgyro.CalibrateAccel(1); - accelgyro.CalibrateGyro(1); - Serial.println("1000 Total Readings"); - accelgyro.PrintActiveOffsets(); - Serial.println("\n\n Any of the above offsets will work nice \n\n Lets proof the PID tuning using another method:"); - } // Initialize - -void SetOffsets(int TheOffsets[6]) - { accelgyro.setXAccelOffset(TheOffsets [iAx]); - accelgyro.setYAccelOffset(TheOffsets [iAy]); - accelgyro.setZAccelOffset(TheOffsets [iAz]); - accelgyro.setXGyroOffset (TheOffsets [iGx]); - accelgyro.setYGyroOffset (TheOffsets [iGy]); - accelgyro.setZGyroOffset (TheOffsets [iGz]); - } // SetOffsets - -void ShowProgress() - { if (LinesOut >= LinesBetweenHeaders) - { // show header - Serial.println("\tXAccel\t\t\tYAccel\t\t\t\tZAccel\t\t\tXGyro\t\t\tYGyro\t\t\tZGyro"); - LinesOut = 0; - } // show header - Serial.print(BLANK); - for (int i = iAx; i <= iGz; i++) - { Serial.print(LBRACKET); - Serial.print(LowOffset[i]), - Serial.print(COMMA); - Serial.print(HighOffset[i]); - Serial.print("] --> ["); - Serial.print(LowValue[i]); - Serial.print(COMMA); - Serial.print(HighValue[i]); - if (i == iGz) - { Serial.println(RBRACKET); } - else - { Serial.print("]\t"); } - } - LinesOut++; - } // ShowProgress - -void PullBracketsIn() - { boolean AllBracketsNarrow; - boolean StillWorking; - int NewOffset[6]; - - Serial.println("\nclosing in:"); - AllBracketsNarrow = false; - ForceHeader(); - StillWorking = true; - while (StillWorking) - { StillWorking = false; - if (AllBracketsNarrow && (N == NFast)) - { SetAveraging(NSlow); } - else - { AllBracketsNarrow = true; }// tentative - for (int i = iAx; i <= iGz; i++) - { if (HighOffset[i] <= (LowOffset[i]+1)) - { NewOffset[i] = LowOffset[i]; } - else - { // binary search - StillWorking = true; - NewOffset[i] = (LowOffset[i] + HighOffset[i]) / 2; - if (HighOffset[i] > (LowOffset[i] + 10)) - { AllBracketsNarrow = false; } - } // binary search - } - SetOffsets(NewOffset); - GetSmoothed(); - for (int i = iAx; i <= iGz; i++) - { // closing in - if (Smoothed[i] > Target[i]) - { // use lower half - HighOffset[i] = NewOffset[i]; - HighValue[i] = Smoothed[i]; - } // use lower half - else - { // use upper half - LowOffset[i] = NewOffset[i]; - LowValue[i] = Smoothed[i]; - } // use upper half - } // closing in - ShowProgress(); - } // still working - - } // PullBracketsIn - -void PullBracketsOut() - { boolean Done = false; - int NextLowOffset[6]; - int NextHighOffset[6]; - - Serial.println("expanding:"); - ForceHeader(); - - while (!Done) - { Done = true; - SetOffsets(LowOffset); - GetSmoothed(); - for (int i = iAx; i <= iGz; i++) - { // got low values - LowValue[i] = Smoothed[i]; - if (LowValue[i] >= Target[i]) - { Done = false; - NextLowOffset[i] = LowOffset[i] - 1000; - } - else - { NextLowOffset[i] = LowOffset[i]; } - } // got low values - - SetOffsets(HighOffset); - GetSmoothed(); - for (int i = iAx; i <= iGz; i++) - { // got high values - HighValue[i] = Smoothed[i]; - if (HighValue[i] <= Target[i]) - { Done = false; - NextHighOffset[i] = HighOffset[i] + 1000; - } - else - { NextHighOffset[i] = HighOffset[i]; } - } // got high values - ShowProgress(); - for (int i = iAx; i <= iGz; i++) - { LowOffset[i] = NextLowOffset[i]; // had to wait until ShowProgress done - HighOffset[i] = NextHighOffset[i]; // .. - } - } // keep going - } // PullBracketsOut - -void SetAveraging(int NewN) - { N = NewN; - Serial.print("averaging "); - Serial.print(N); - Serial.println(" readings each time"); - } // SetAveraging - -void setup() - { Initialize(); - for (int i = iAx; i <= iGz; i++) - { // set targets and initial guesses - Target[i] = 0; // must fix for ZAccel - HighOffset[i] = 0; - LowOffset[i] = 0; - } // set targets and initial guesses - Target[iAz] = 16384; - SetAveraging(NFast); - - PullBracketsOut(); - PullBracketsIn(); - - Serial.println("-------------- done --------------"); - } // setup - -void loop() - { - } // loop diff --git a/mpu6050-master/examples/MPU6050_DMP6/MPU6050_DMP6.ino b/mpu6050-master/examples/MPU6050_DMP6/MPU6050_DMP6.ino deleted file mode 100644 index 3ebe2ee6382abef67e9168dd4ca73a47e4793db6..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_DMP6/MPU6050_DMP6.ino +++ /dev/null @@ -1,345 +0,0 @@ -// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0) -// 6/21/2012 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2019-07-08 - Added Auto Calibration and offset generator -// - and altered FIFO retrieval sequence to avoid using blocking code -// 2016-04-18 - Eliminated a potential infinite loop -// 2013-05-08 - added seamless Fastwire support -// - added note about gyro calibration -// 2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error -// 2012-06-20 - improved FIFO overflow handling and simplified read process -// 2012-06-19 - completely rearranged DMP initialization code and simplification -// 2012-06-13 - pull gyro and accel data from FIFO packet instead of reading directly -// 2012-06-09 - fix broken FIFO read sequence and change interrupt detection to RISING -// 2012-06-05 - add gravity-compensated initial reference frame acceleration output -// - add 3D math helper file to DMP6 example sketch -// - add Euler output and Yaw/Pitch/Roll output formats -// 2012-06-04 - remove accel offset clearing for better results (thanks Sungon Lee) -// 2012-06-01 - fixed gyro sensitivity to be 2000 deg/sec instead of 250 -// 2012-05-30 - basic DMP initialization working - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files -// for both classes must be in the include path of your project -#include "I2Cdev.h" - -#include "MPU6050_6Axis_MotionApps20.h" -//#include "MPU6050.h" // not necessary if using MotionApps include file - -// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation -// is used in I2Cdev.h -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - #include "Wire.h" -#endif - -// class default I2C address is 0x68 -// specific I2C addresses may be passed as a parameter here -// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) -// AD0 high = 0x69 -MPU6050 mpu; -//MPU6050 mpu(0x69); // <-- use for AD0 high - -/* ========================================================================= - NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch - depends on the MPU-6050's INT pin being connected to the Arduino's - external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is - digital I/O pin 2. - * ========================================================================= */ - -/* ========================================================================= - NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error - when using Serial.write(buf, len). The Teapot output uses this method. - The solution requires a modification to the Arduino USBAPI.h file, which - is fortunately simple, but annoying. This will be fixed in the next IDE - release. For more info, see these links: - - http://arduino.cc/forum/index.php/topic,109987.0.html - http://code.google.com/p/arduino/issues/detail?id=958 - * ========================================================================= */ - - - -// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual -// quaternion components in a [w, x, y, z] format (not best for parsing -// on a remote host such as Processing or something though) -//#define OUTPUT_READABLE_QUATERNION - -// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles -// (in degrees) calculated from the quaternions coming from the FIFO. -// Note that Euler angles suffer from gimbal lock (for more info, see -// http://en.wikipedia.org/wiki/Gimbal_lock) -//#define OUTPUT_READABLE_EULER - -// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/ -// pitch/roll angles (in degrees) calculated from the quaternions coming -// from the FIFO. Note this also requires gravity vector calculations. -// Also note that yaw/pitch/roll angles suffer from gimbal lock (for -// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock) -#define OUTPUT_READABLE_YAWPITCHROLL - -// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration -// components with gravity removed. This acceleration reference frame is -// not compensated for orientation, so +X is always +X according to the -// sensor, just without the effects of gravity. If you want acceleration -// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead. -//#define OUTPUT_READABLE_REALACCEL - -// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration -// components with gravity removed and adjusted for the world frame of -// reference (yaw is relative to initial orientation, since no magnetometer -// is present in this case). Could be quite handy in some cases. -//#define OUTPUT_READABLE_WORLDACCEL - -// uncomment "OUTPUT_TEAPOT" if you want output that matches the -// format used for the InvenSense teapot demo -//#define OUTPUT_TEAPOT - - - -#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards -#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) -bool blinkState = false; - -// MPU control/status vars -bool dmpReady = false; // set true if DMP init was successful -uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU -uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) -uint16_t packetSize; // expected DMP packet size (default is 42 bytes) -uint16_t fifoCount; // count of all bytes currently in FIFO -uint8_t fifoBuffer[64]; // FIFO storage buffer - -// orientation/motion vars -Quaternion q; // [w, x, y, z] quaternion container -VectorInt16 aa; // [x, y, z] accel sensor measurements -VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements -VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements -VectorFloat gravity; // [x, y, z] gravity vector -float euler[3]; // [psi, theta, phi] Euler angle container -float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector - -// packet structure for InvenSense teapot demo -uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' }; - - - -// ================================================================ -// === INTERRUPT DETECTION ROUTINE === -// ================================================================ - -volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high -void dmpDataReady() { - mpuInterrupt = true; -} - - - -// ================================================================ -// === INITIAL SETUP === -// ================================================================ - -void setup() { - // join I2C bus (I2Cdev library doesn't do this automatically) - #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - Wire.begin(); - Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties - #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE - Fastwire::setup(400, true); - #endif - - // initialize serial communication - // (115200 chosen because it is required for Teapot Demo output, but it's - // really up to you depending on your project) - Serial.begin(115200); - while (!Serial); // wait for Leonardo enumeration, others continue immediately - - // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3V or Arduino - // Pro Mini running at 3.3V, cannot handle this baud rate reliably due to - // the baud timing being too misaligned with processor ticks. You must use - // 38400 or slower in these cases, or use some kind of external separate - // crystal solution for the UART timer. - - // initialize device - Serial.println(F("Initializing I2C devices...")); - mpu.initialize(); - pinMode(INTERRUPT_PIN, INPUT); - - // verify connection - Serial.println(F("Testing device connections...")); - Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); - - // wait for ready - Serial.println(F("\nSend any character to begin DMP programming and demo: ")); - while (Serial.available() && Serial.read()); // empty buffer - while (!Serial.available()); // wait for data - while (Serial.available() && Serial.read()); // empty buffer again - - // load and configure the DMP - Serial.println(F("Initializing DMP...")); - devStatus = mpu.dmpInitialize(); - - // supply your own gyro offsets here, scaled for min sensitivity - mpu.setXGyroOffset(220); - mpu.setYGyroOffset(76); - mpu.setZGyroOffset(-85); - mpu.setZAccelOffset(1788); // 1688 factory default for my test chip - - // make sure it worked (returns 0 if so) - if (devStatus == 0) { - // Calibration Time: generate offsets and calibrate our MPU6050 - mpu.CalibrateAccel(6); - mpu.CalibrateGyro(6); - mpu.PrintActiveOffsets(); - // turn on the DMP, now that it's ready - Serial.println(F("Enabling DMP...")); - mpu.setDMPEnabled(true); - - // enable Arduino interrupt detection - Serial.print(F("Enabling interrupt detection (Arduino external interrupt ")); - Serial.print(digitalPinToInterrupt(INTERRUPT_PIN)); - Serial.println(F(")...")); - attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); - mpuIntStatus = mpu.getIntStatus(); - - // set our DMP Ready flag so the main loop() function knows it's okay to use it - Serial.println(F("DMP ready! Waiting for first interrupt...")); - dmpReady = true; - - // get expected DMP packet size for later comparison - packetSize = mpu.dmpGetFIFOPacketSize(); - } else { - // ERROR! - // 1 = initial memory load failed - // 2 = DMP configuration updates failed - // (if it's going to break, usually the code will be 1) - Serial.print(F("DMP Initialization failed (code ")); - Serial.print(devStatus); - Serial.println(F(")")); - } - - // configure LED for output - pinMode(LED_PIN, OUTPUT); -} - - - -// ================================================================ -// === MAIN PROGRAM LOOP === -// ================================================================ - -void loop() { - // if programming failed, don't try to do anything - if (!dmpReady) return; - // read a packet from FIFO - if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet - #ifdef OUTPUT_READABLE_QUATERNION - // display quaternion values in easy matrix form: w x y z - mpu.dmpGetQuaternion(&q, fifoBuffer); - Serial.print("quat\t"); - Serial.print(q.w); - Serial.print("\t"); - Serial.print(q.x); - Serial.print("\t"); - Serial.print(q.y); - Serial.print("\t"); - Serial.println(q.z); - #endif - - #ifdef OUTPUT_READABLE_EULER - // display Euler angles in degrees - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetEuler(euler, &q); - Serial.print("euler\t"); - Serial.print(euler[0] * 180/M_PI); - Serial.print("\t"); - Serial.print(euler[1] * 180/M_PI); - Serial.print("\t"); - Serial.println(euler[2] * 180/M_PI); - #endif - - #ifdef OUTPUT_READABLE_YAWPITCHROLL - // display Euler angles in degrees - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); - Serial.print("ypr\t"); - Serial.print(ypr[0] * 180/M_PI); - Serial.print("\t"); - Serial.print(ypr[1] * 180/M_PI); - Serial.print("\t"); - Serial.println(ypr[2] * 180/M_PI); - #endif - - #ifdef OUTPUT_READABLE_REALACCEL - // display real acceleration, adjusted to remove gravity - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetAccel(&aa, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); - Serial.print("areal\t"); - Serial.print(aaReal.x); - Serial.print("\t"); - Serial.print(aaReal.y); - Serial.print("\t"); - Serial.println(aaReal.z); - #endif - - #ifdef OUTPUT_READABLE_WORLDACCEL - // display initial world-frame acceleration, adjusted to remove gravity - // and rotated based on known orientation from quaternion - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetAccel(&aa, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); - mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); - Serial.print("aworld\t"); - Serial.print(aaWorld.x); - Serial.print("\t"); - Serial.print(aaWorld.y); - Serial.print("\t"); - Serial.println(aaWorld.z); - #endif - - #ifdef OUTPUT_TEAPOT - // display quaternion values in InvenSense Teapot demo format: - teapotPacket[2] = fifoBuffer[0]; - teapotPacket[3] = fifoBuffer[1]; - teapotPacket[4] = fifoBuffer[4]; - teapotPacket[5] = fifoBuffer[5]; - teapotPacket[6] = fifoBuffer[8]; - teapotPacket[7] = fifoBuffer[9]; - teapotPacket[8] = fifoBuffer[12]; - teapotPacket[9] = fifoBuffer[13]; - Serial.write(teapotPacket, 14); - teapotPacket[11]++; // packetCount, loops at 0xFF on purpose - #endif - - // blink LED to indicate activity - blinkState = !blinkState; - digitalWrite(LED_PIN, blinkState); - } -} diff --git a/mpu6050-master/examples/MPU6050_DMP6/Processing/MPUTeapot/MPUTeapot.pde b/mpu6050-master/examples/MPU6050_DMP6/Processing/MPUTeapot/MPUTeapot.pde deleted file mode 100644 index 881132d43f865a79bef7316cfd6155025c904bf6..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_DMP6/Processing/MPUTeapot/MPUTeapot.pde +++ /dev/null @@ -1,242 +0,0 @@ -// I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output -// 6/20/2012 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2012-06-20 - initial release - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -import processing.serial.*; -import processing.opengl.*; -import toxi.geom.*; -import toxi.processing.*; - -// NOTE: requires ToxicLibs to be installed in order to run properly. -// 1. Download from https://github.com/postspectacular/toxiclibs/releases -// 2. Extract into [userdir]/Processing/libraries -// (location may be different on Mac/Linux) -// 3. Run and bask in awesomeness - -ToxiclibsSupport gfx; - -Serial port; // The serial port -char[] teapotPacket = new char[14]; // InvenSense Teapot packet -int serialCount = 0; // current packet byte position -int synced = 0; -int interval = 0; - -float[] q = new float[4]; -Quaternion quat = new Quaternion(1, 0, 0, 0); - -float[] gravity = new float[3]; -float[] euler = new float[3]; -float[] ypr = new float[3]; - -void setup() { - // 300px square viewport using OpenGL rendering - size(300, 300, OPENGL); - gfx = new ToxiclibsSupport(this); - - // setup lights and antialiasing - lights(); - smooth(); - - // display serial port list for debugging/clarity - println(Serial.list()); - - // get the first available port (use EITHER this OR the specific port code below) - String portName = Serial.list()[0]; - - // get a specific serial port (use EITHER this OR the first-available code above) - //String portName = "COM4"; - - // open the serial port - port = new Serial(this, portName, 115200); - - // send single character to trigger DMP init/start - // (expected by MPU6050_DMP6 example Arduino sketch) - port.write('r'); -} - -void draw() { - if (millis() - interval > 1000) { - // resend single character to trigger DMP init/start - // in case the MPU is halted/reset while applet is running - port.write('r'); - interval = millis(); - } - - // black background - background(0); - - // translate everything to the middle of the viewport - pushMatrix(); - translate(width / 2, height / 2); - - // 3-step rotation from yaw/pitch/roll angles (gimbal lock!) - // ...and other weirdness I haven't figured out yet - //rotateY(-ypr[0]); - //rotateZ(-ypr[1]); - //rotateX(-ypr[2]); - - // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!) - // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of - // different coordinate system orientation assumptions between Processing - // and InvenSense DMP) - float[] axis = quat.toAxisAngle(); - rotate(axis[0], -axis[1], axis[3], axis[2]); - - // draw main body in red - fill(255, 0, 0, 200); - box(10, 10, 200); - - // draw front-facing tip in blue - fill(0, 0, 255, 200); - pushMatrix(); - translate(0, 0, -120); - rotateX(PI/2); - drawCylinder(0, 20, 20, 8); - popMatrix(); - - // draw wings and tail fin in green - fill(0, 255, 0, 200); - beginShape(TRIANGLES); - vertex(-100, 2, 30); vertex(0, 2, -80); vertex(100, 2, 30); // wing top layer - vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30); // wing bottom layer - vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70); // tail left layer - vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70); // tail right layer - endShape(); - beginShape(QUADS); - vertex(-100, 2, 30); vertex(-100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80); - vertex( 100, 2, 30); vertex( 100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80); - vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2, 30); vertex(100, 2, 30); - vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, -30, 98); vertex(-2, -30, 98); - vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, 0, 70); vertex(-2, 0, 70); - vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2, 0, 70); vertex(-2, 0, 70); - endShape(); - - popMatrix(); -} - -void serialEvent(Serial port) { - interval = millis(); - while (port.available() > 0) { - int ch = port.read(); - - if (synced == 0 && ch != '$') return; // initial synchronization - also used to resync/realign if needed - synced = 1; - print ((char)ch); - - if ((serialCount == 1 && ch != 2) - || (serialCount == 12 && ch != '\r') - || (serialCount == 13 && ch != '\n')) { - serialCount = 0; - synced = 0; - return; - } - - if (serialCount > 0 || ch == '$') { - teapotPacket[serialCount++] = (char)ch; - if (serialCount == 14) { - serialCount = 0; // restart packet byte position - - // get quaternion from data packet - q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f; - q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f; - q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f; - q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f; - for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i]; - - // set our toxilibs quaternion to new data - quat.set(q[0], q[1], q[2], q[3]); - - /* - // below calculations unnecessary for orientation only using toxilibs - - // calculate gravity vector - gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]); - gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]); - gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3]; - - // calculate Euler angles - euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1); - euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]); - euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1); - - // calculate yaw/pitch/roll angles - ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1); - ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2])); - ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2])); - - // output various components for debugging - //println("q:\t" + round(q[0]*100.0f)/100.0f + "\t" + round(q[1]*100.0f)/100.0f + "\t" + round(q[2]*100.0f)/100.0f + "\t" + round(q[3]*100.0f)/100.0f); - //println("euler:\t" + euler[0]*180.0f/PI + "\t" + euler[1]*180.0f/PI + "\t" + euler[2]*180.0f/PI); - //println("ypr:\t" + ypr[0]*180.0f/PI + "\t" + ypr[1]*180.0f/PI + "\t" + ypr[2]*180.0f/PI); - */ - } - } - } -} - -void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) { - float angle = 0; - float angleIncrement = TWO_PI / sides; - beginShape(QUAD_STRIP); - for (int i = 0; i < sides + 1; ++i) { - vertex(topRadius*cos(angle), 0, topRadius*sin(angle)); - vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle)); - angle += angleIncrement; - } - endShape(); - - // If it is not a cone, draw the circular top cap - if (topRadius != 0) { - angle = 0; - beginShape(TRIANGLE_FAN); - - // Center point - vertex(0, 0, 0); - for (int i = 0; i < sides + 1; i++) { - vertex(topRadius * cos(angle), 0, topRadius * sin(angle)); - angle += angleIncrement; - } - endShape(); - } - - // If it is not a cone, draw the circular bottom cap - if (bottomRadius != 0) { - angle = 0; - beginShape(TRIANGLE_FAN); - - // Center point - vertex(0, tall, 0); - for (int i = 0; i < sides + 1; i++) { - vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle)); - angle += angleIncrement; - } - endShape(); - } -} diff --git a/mpu6050-master/examples/MPU6050_DMP6_ESPWiFi/MPU6050_DMP6_ESPWiFi.ino b/mpu6050-master/examples/MPU6050_DMP6_ESPWiFi/MPU6050_DMP6_ESPWiFi.ino deleted file mode 100644 index 6e1fea66f7c2e21806234761825a1b74a0c5763d..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_DMP6_ESPWiFi/MPU6050_DMP6_ESPWiFi.ino +++ /dev/null @@ -1,377 +0,0 @@ -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -/* This driver reads quaternion data from the MPU6060 and sends - Open Sound Control messages. - - GY-521 NodeMCU - MPU6050 devkit 1.0 - board Lolin Description - ======= ========== ==================================================== - VCC VU (5V USB) Not available on all boards so use 3.3V if needed. - GND G Ground - SCL D1 (GPIO05) I2C clock - SDA D2 (GPIO04) I2C data - XDA not connected - XCL not connected - AD0 not connected - INT D8 (GPIO15) Interrupt pin - -*/ - -#if defined(ESP8266) -#include <ESP8266WiFi.h> -#else -#include <WiFi.h> -#endif -#include <DNSServer.h> -#include <WiFiClient.h> -#include <WiFiUdp.h> -#include <OSCMessage.h> -#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager - -// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files -// for both classes must be in the include path of your project -#include "I2Cdev.h" - -#include "MPU6050_6Axis_MotionApps20.h" -//#include "MPU6050.h" // not necessary if using MotionApps include file - -// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation -// is used in I2Cdev.h -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - #include "Wire.h" -#endif - -// class default I2C address is 0x68 -// specific I2C addresses may be passed as a parameter here -// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) -// AD0 high = 0x69 -MPU6050 mpu; -//MPU6050 mpu(0x69); // <-- use for AD0 high - -/* ========================================================================= - NOTE: In addition to connection 5/3.3v, GND, SDA, and SCL, this sketch - depends on the MPU-6050's INT pin being connected to the ESP8266 GPIO15 - pin. - * ========================================================================= */ - -// MPU control/status vars -bool dmpReady = false; // set true if DMP init was successful -uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU -uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) -uint16_t packetSize; // expected DMP packet size (default is 42 bytes) -uint16_t fifoCount; // count of all bytes currently in FIFO -uint8_t fifoBuffer[64]; // FIFO storage buffer - -// orientation/motion vars -Quaternion q; // [w, x, y, z] quaternion container -VectorInt16 aa; // [x, y, z] accel sensor measurements -VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements -VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements -VectorFloat gravity; // [x, y, z] gravity vector - - -// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual -// quaternion components in a [w, x, y, z] format (not best for parsing -// on a remote host such as Processing or something though) -//#define OUTPUT_READABLE_QUATERNION - -// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles -// (in degrees) calculated from the quaternions coming from the FIFO. -// Note that Euler angles suffer from gimbal lock (for more info, see -// http://en.wikipedia.org/wiki/Gimbal_lock) -//#define OUTPUT_READABLE_EULER - -// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/ -// pitch/roll angles (in degrees) calculated from the quaternions coming -// from the FIFO. Note this also requires gravity vector calculations. -// Also note that yaw/pitch/roll angles suffer from gimbal lock (for -// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock) -//#define OUTPUT_READABLE_YAWPITCHROLL - -// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration -// components with gravity removed. This acceleration reference frame is -// not compensated for orientation, so +X is always +X according to the -// sensor, just without the effects of gravity. If you want acceleration -// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead. -//#define OUTPUT_READABLE_REALACCEL - -// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration -// components with gravity removed and adjusted for the world frame of -// reference (yaw is relative to initial orientation, since no magnetometer -// is present in this case). Could be quite handy in some cases. -//#define OUTPUT_READABLE_WORLDACCEL - -// uncomment "OUTPUT_TEAPOT_OSC" if you want output that matches the -// format used for the InvenSense teapot demo -#define OUTPUT_TEAPOT_OSC - - -#ifdef OUTPUT_READABLE_EULER -float euler[3]; // [psi, theta, phi] Euler angle container -#endif -#ifdef OUTPUT_READABLE_YAWPITCHROLL -float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector -#endif - -#define INTERRUPT_PIN 15 // use pin 15 on ESP8266 - -const char DEVICE_NAME[] = "mpu6050"; - -WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP -const IPAddress outIp(192, 168, 1, 11); // remote IP to receive OSC -const unsigned int outPort = 9999; // remote port to receive OSC - -// ================================================================ -// === INTERRUPT DETECTION ROUTINE === -// ================================================================ - -volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high -void ICACHE_RAM_ATTR dmpDataReady() { - mpuInterrupt = true; -} - -void mpu_setup() -{ - // join I2C bus (I2Cdev library doesn't do this automatically) -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - Wire.begin(); - Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties -#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE - Fastwire::setup(400, true); -#endif - - // initialize device - Serial.println(F("Initializing I2C devices...")); - mpu.initialize(); - pinMode(INTERRUPT_PIN, INPUT); - - // verify connection - Serial.println(F("Testing device connections...")); - Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); - - // load and configure the DMP - Serial.println(F("Initializing DMP...")); - devStatus = mpu.dmpInitialize(); - - // supply your own gyro offsets here, scaled for min sensitivity - mpu.setXGyroOffset(220); - mpu.setYGyroOffset(76); - mpu.setZGyroOffset(-85); - mpu.setZAccelOffset(1788); // 1688 factory default for my test chip - - // make sure it worked (returns 0 if so) - if (devStatus == 0) { - // turn on the DMP, now that it's ready - Serial.println(F("Enabling DMP...")); - mpu.setDMPEnabled(true); - - // enable Arduino interrupt detection - Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); - attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); - mpuIntStatus = mpu.getIntStatus(); - - // set our DMP Ready flag so the main loop() function knows it's okay to use it - Serial.println(F("DMP ready! Waiting for first interrupt...")); - dmpReady = true; - - // get expected DMP packet size for later comparison - packetSize = mpu.dmpGetFIFOPacketSize(); - } else { - // ERROR! - // 1 = initial memory load failed - // 2 = DMP configuration updates failed - // (if it's going to break, usually the code will be 1) - Serial.print(F("DMP Initialization failed (code ")); - Serial.print(devStatus); - Serial.println(F(")")); - } -} - -void setup(void) -{ - Serial.begin(115200); - Serial.println(F("\nOrientation Sensor OSC output")); Serial.println(); - - //WiFiManager - //Local intialization. Once its business is done, there is no need to keep it around - WiFiManager wifiManager; - //reset saved settings - //wifiManager.resetSettings(); - - //fetches ssid and pass from eeprom and tries to connect - //if it does not connect it starts an access point with the specified name - //and goes into a blocking loop awaiting configuration - wifiManager.autoConnect(DEVICE_NAME); - - Serial.print(F("WiFi connected! IP address: ")); - Serial.println(WiFi.localIP()); - - mpu_setup(); -} - -void mpu_loop() -{ - // if programming failed, don't try to do anything - if (!dmpReady) return; - - // wait for MPU interrupt or extra packet(s) available - if (!mpuInterrupt && fifoCount < packetSize) return; - - // reset interrupt flag and get INT_STATUS byte - mpuInterrupt = false; - mpuIntStatus = mpu.getIntStatus(); - - // get current FIFO count - fifoCount = mpu.getFIFOCount(); - - // check for overflow (this should never happen unless our code is too inefficient) - if ((mpuIntStatus & 0x10) || fifoCount == 1024) { - // reset so we can continue cleanly - mpu.resetFIFO(); - Serial.println(F("FIFO overflow!")); - - // otherwise, check for DMP data ready interrupt (this should happen frequently) - } else if (mpuIntStatus & 0x02) { - // wait for correct available data length, should be a VERY short wait - while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); - - // read a packet from FIFO - mpu.getFIFOBytes(fifoBuffer, packetSize); - - // track FIFO count here in case there is > 1 packet available - // (this lets us immediately read more without waiting for an interrupt) - fifoCount -= packetSize; - -#ifdef OUTPUT_READABLE_QUATERNION - // display quaternion values in easy matrix form: w x y z - mpu.dmpGetQuaternion(&q, fifoBuffer); - Serial.print("quat\t"); - Serial.print(q.w); - Serial.print("\t"); - Serial.print(q.x); - Serial.print("\t"); - Serial.print(q.y); - Serial.print("\t"); - Serial.println(q.z); -#endif - -#ifdef OUTPUT_TEAPOT_OSC -#ifndef OUTPUT_READABLE_QUATERNION - // display quaternion values in easy matrix form: w x y z - mpu.dmpGetQuaternion(&q, fifoBuffer); -#endif - // Send OSC message - OSCMessage msg("/imuquat"); - msg.add((float)q.w); - msg.add((float)q.x); - msg.add((float)q.y); - msg.add((float)q.z); - - Udp.beginPacket(outIp, outPort); - msg.send(Udp); - Udp.endPacket(); - - msg.empty(); -#endif - -#ifdef OUTPUT_READABLE_EULER - // display Euler angles in degrees - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetEuler(euler, &q); - Serial.print("euler\t"); - Serial.print(euler[0] * 180/M_PI); - Serial.print("\t"); - Serial.print(euler[1] * 180/M_PI); - Serial.print("\t"); - Serial.println(euler[2] * 180/M_PI); -#endif - -#ifdef OUTPUT_READABLE_YAWPITCHROLL - // display Euler angles in degrees - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); - Serial.print("ypr\t"); - Serial.print(ypr[0] * 180/M_PI); - Serial.print("\t"); - Serial.print(ypr[1] * 180/M_PI); - Serial.print("\t"); - Serial.println(ypr[2] * 180/M_PI); -#endif - -#ifdef OUTPUT_READABLE_REALACCEL - // display real acceleration, adjusted to remove gravity - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetAccel(&aa, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); - Serial.print("areal\t"); - Serial.print(aaReal.x); - Serial.print("\t"); - Serial.print(aaReal.y); - Serial.print("\t"); - Serial.println(aaReal.z); -#endif - -#ifdef OUTPUT_READABLE_WORLDACCEL - // display initial world-frame acceleration, adjusted to remove gravity - // and rotated based on known orientation from quaternion - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetAccel(&aa, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); - mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); - Serial.print("aworld\t"); - Serial.print(aaWorld.x); - Serial.print("\t"); - Serial.print(aaWorld.y); - Serial.print("\t"); - Serial.println(aaWorld.z); -#endif - } -} - -/**************************************************************************/ -/* - Arduino loop function, called once 'setup' is complete (your own code - should go here) -*/ -/**************************************************************************/ -void loop(void) -{ - if (WiFi.status() != WL_CONNECTED) { - Serial.println(); - Serial.println("*** Disconnected from AP so rebooting ***"); - Serial.println(); - #if defined(ESP8266) - ESP.reset(); - #else - ESP.restart(); - #endif - } - - mpu_loop(); -} diff --git a/mpu6050-master/examples/MPU6050_DMP6_ESPWiFi/Processing/MPUOSCTeapot/MPUOSCTeapot.pde b/mpu6050-master/examples/MPU6050_DMP6_ESPWiFi/Processing/MPUOSCTeapot/MPUOSCTeapot.pde deleted file mode 100644 index d7dd7f13a78e142c027579cce8f5f106b07c0682..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_DMP6_ESPWiFi/Processing/MPUOSCTeapot/MPUOSCTeapot.pde +++ /dev/null @@ -1,187 +0,0 @@ -// I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output -// 6/20/2012 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2012-06-20 - initial release - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -/** - * MPUOSCTeapot Processing demo for MPU6050 DMP modified for OSC - * https://gitub.com/jrowberg/i2cdevlib - * The original demo uses serial port I/O which has been replaced with - * OSC UDP messages in this sketch. - * - * The MPU6050 is connected to an ESP8266 with battery so it is completely - * wire free. - * - * Tested on Processing 3.3.5 running on Ubuntu Linux 14.04 - * - * Dependencies installed using Library Manager - * - * Open Sound Control library - * oscP5 website at http://www.sojamo.de/oscP5 - * ToxicLibs - * quaternion functions https://github.com/postspectacular/toxiclibs/ - */ - -// Install oscP5 using the IDE library manager. -// From the IDE menu bar, Sketch | Import Library | Add library. -// In the search box type "osc". -import oscP5.*; -import netP5.*; -// 1. Download from https://github.com/postspectacular/toxiclibs/releases -// 2. Extract into [userdir]/Processing/libraries -// (location may be different on Mac/Linux) -import toxi.geom.*; -import toxi.processing.*; - -ToxiclibsSupport gfx; - -Quaternion quat = new Quaternion(1, 0, 0, 0); - -OscP5 oscP5; - -void setup() { - // 300px square viewport using OpenGL rendering - size(300, 300, P3D); - gfx = new ToxiclibsSupport(this); - - // setup lights and antialiasing - lights(); - smooth(); - - /* start oscP5, listening for incoming messages at port 9999 */ - oscP5 = new OscP5(this, 9999); - - oscP5.plug(this, "imu", "/imuquat"); -} - -/* incoming osc message are forwarded to the oscEvent method. */ -void oscEvent(OscMessage theOscMessage) { - /* print the address pattern and the typetag of the received OscMessage */ - //print("### received an osc message."); - //print(" addrpattern: "+theOscMessage.addrPattern()); - //println(" typetag: "+theOscMessage.typetag()); -} - -public void imu(float quant_w, float quant_x, float quant_y, float quant_z) { - //println(quant_w, quant_x, quant_y, quant_z); - quat.set(quant_w, quant_x, quant_y, quant_z); -} - -void draw() { - // black background - background(0); - - // translate everything to the middle of the viewport - pushMatrix(); - translate(width / 2, height / 2); - - // 3-step rotation from yaw/pitch/roll angles (gimbal lock!) - // ...and other weirdness I haven't figured out yet - //rotateY(-ypr[0]); - //rotateZ(-ypr[1]); - //rotateX(-ypr[2]); - - // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!) - // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of - // different coordinate system orientation assumptions between Processing - // and InvenSense DMP) - float[] axis = quat.toAxisAngle(); - rotate(axis[0], -axis[1], axis[3], axis[2]); - - // draw main body in red - fill(255, 0, 0, 200); - box(10, 10, 200); - - // draw front-facing tip in blue - fill(0, 0, 255, 200); - pushMatrix(); - translate(0, 0, -120); - rotateX(PI/2); - drawCylinder(0, 20, 20, 8); - popMatrix(); - - // draw wings and tail fin in green - fill(0, 255, 0, 200); - beginShape(TRIANGLES); - vertex(-100, 2, 30); vertex(0, 2, -80); vertex(100, 2, 30); // wing top layer - vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30); // wing bottom layer - vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70); // tail left layer - vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70); // tail right layer - endShape(); - beginShape(QUADS); - vertex(-100, 2, 30); vertex(-100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80); - vertex( 100, 2, 30); vertex( 100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80); - vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2, 30); vertex(100, 2, 30); - vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, -30, 98); vertex(-2, -30, 98); - vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, 0, 70); vertex(-2, 0, 70); - vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2, 0, 70); vertex(-2, 0, 70); - endShape(); - - popMatrix(); -} - -void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) { - float angle = 0; - float angleIncrement = TWO_PI / sides; - beginShape(QUAD_STRIP); - for (int i = 0; i < sides + 1; ++i) { - vertex(topRadius*cos(angle), 0, topRadius*sin(angle)); - vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle)); - angle += angleIncrement; - } - endShape(); - - // If it is not a cone, draw the circular top cap - if (topRadius != 0) { - angle = 0; - beginShape(TRIANGLE_FAN); - - // Center point - vertex(0, 0, 0); - for (int i = 0; i < sides + 1; i++) { - vertex(topRadius * cos(angle), 0, topRadius * sin(angle)); - angle += angleIncrement; - } - endShape(); - } - - // If it is not a cone, draw the circular bottom cap - if (bottomRadius != 0) { - angle = 0; - beginShape(TRIANGLE_FAN); - - // Center point - vertex(0, tall, 0); - for (int i = 0; i < sides + 1; i++) { - vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle)); - angle += angleIncrement; - } - endShape(); - } -} diff --git a/mpu6050-master/examples/MPU6050_DMP6_Ethernet/MPU6050_DMP6_Ethernet.ino b/mpu6050-master/examples/MPU6050_DMP6_Ethernet/MPU6050_DMP6_Ethernet.ino deleted file mode 100644 index c6891f789169a78a23afce80218387afc4979794..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_DMP6_Ethernet/MPU6050_DMP6_Ethernet.ino +++ /dev/null @@ -1,545 +0,0 @@ -// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0) over Ethernet -// 2/27/2016 by hellphoenix -// Based on I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0) (6/21/2012 by Jeff Rowberg <jeff@rowberg.net>) -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2016-04-18 - Eliminated a potential infinite loop -// 2016-02-28 - Cleaned up code to be in line with other example codes -// - Added Ethernet outputs for Quaternion, Euler, RealAccel, WorldAccel -// 2016-02-27 - Initial working code compiled -// Bugs: -// - There is still a hangup after some time, though it only occurs when you are reading data from the website. -// If you only read the data from the serial port, there are no hangups. -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ -#include <Ethernet.h> -// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files -// for both classes must be in the include path of your project -#include "I2Cdev.h" - -#include "MPU6050_6Axis_MotionApps20.h" -//#include "MPU6050.h" // not necessary if using MotionApps include file - -// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation -// is used in I2Cdev.h -#include "Wire.h" -#include "avr/wdt.h"// Watchdog library - -// class default I2C address is 0x68 -// specific I2C addresses may be passed as a parameter here -// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) -// AD0 high = 0x69 -MPU6050 mpu; -//MPU6050 mpu(0x69); // <-- use for AD0 high - -// MAC address from Ethernet shield sticker under board -byte mac[] = { - 0x90, 0xA2, 0xDA, 0x10, 0x26, 0x82 -}; -// assign an IP address for the controller: -IPAddress ip(192,168,1,50); -// the router's gateway address: -byte gateway[] = { 192, 168, 1, 1 }; -// the subnet: -byte subnet[] = { 255, 255, 0, 0 }; - -// Initialize the Ethernet server library -// with the IP address and port you want to use -// (port 80 is default for HTTP): -EthernetServer server(80); - -String HTTP_req; // stores the HTTP request - -/* ========================================================================= - NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch - depends on the MPU-6050's INT pin being connected to the Arduino's - external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is - digital I/O pin 2. - * ========================================================================= */ - -/* ========================================================================= - NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error - when using Serial.write(buf, len). The Teapot output uses this method. - The solution requires a modification to the Arduino USBAPI.h file, which - is fortunately simple, but annoying. This will be fixed in the next IDE - release. For more info, see these links: - - http://arduino.cc/forum/index.php/topic,109987.0.html - http://code.google.com/p/arduino/issues/detail?id=958 - * ========================================================================= */ - - -// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual -// quaternion components in a [w, x, y, z] format (not best for parsing -// on a remote host such as Processing or something though) -//#define OUTPUT_READABLE_QUATERNION - -// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles -// (in degrees) calculated from the quaternions coming from the FIFO. -// Note that Euler angles suffer from gimbal lock (for more info, see -// http://en.wikipedia.org/wiki/Gimbal_lock) -//#define OUTPUT_READABLE_EULER - -// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/ -// pitch/roll angles (in degrees) calculated from the quaternions coming -// from the FIFO. Note this also requires gravity vector calculations. -// Also note that yaw/pitch/roll angles suffer from gimbal lock (for -// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock) -#define OUTPUT_READABLE_YAWPITCHROLL - -// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration -// components with gravity removed. This acceleration reference frame is -// not compensated for orientation, so +X is always +X according to the -// sensor, just without the effects of gravity. If you want acceleration -// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead. -//#define OUTPUT_READABLE_REALACCEL - -// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration -// components with gravity removed and adjusted for the world frame of -// reference (yaw is relative to initial orientation, since no magnetometer -// is present in this case). Could be quite handy in some cases. -//#define OUTPUT_READABLE_WORLDACCEL - -// uncomment "OUTPUT_TEAPOT" if you want output that matches the -// format used for the InvenSense teapot demo -//#define OUTPUT_TEAPOT - -#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards -#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) -bool blinkState = false; - -// MPU control/status vars -bool dmpReady = false; // set true if DMP init was successful -uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU -uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) -uint16_t packetSize; // expected DMP packet size (default is 42 bytes) -uint16_t fifoCount; // count of all bytes currently in FIFO -uint8_t fifoBuffer[64]; // FIFO storage buffer - -// orientation/motion vars -Quaternion q; // [w, x, y, z] quaternion container -VectorInt16 aa; // [x, y, z] accel sensor measurements -VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements -VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements -VectorFloat gravity; // [x, y, z] gravity vector -float euler[3]; // [psi, theta, phi] Euler angle container -float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector - -// packet structure for InvenSense teapot demo -uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' }; - - - -// ================================================================ -// === INTERRUPT DETECTION ROUTINE === -// ================================================================ - -volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high -void dmpDataReady() { - mpuInterrupt = true; -} -// ================================================================ -// === INITIAL SETUP === -// ================================================================ - -void setup() { - wdt_enable(WDTO_1S); //Watchdog enable. - //WDTO_1S sets the watchdog timer to 1 second. The time set here is approximate. - // You can find more time settings at http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html . - - // join I2C bus (I2Cdev library doesn't do this automatically) - #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - Wire.begin(); - Wire.setClock(400000); // 400kHz I2C clock (200kHz if CPU is 8MHz). Comment this line if having compilation difficulties - #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE - Fastwire::setup(400, true); - #endif - - // initialize serial communication - // (115200 chosen because it is required for Teapot Demo output, but it's - // really up to you depending on your project) - Serial.begin(115200); - // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3V or Arduino - // Pro Mini running at 3.3V, cannot handle this baud rate reliably due to - // the baud timing being too misaligned with processor ticks. You must use - // 38400 or slower in these cases, or use some kind of external separate - // crystal solution for the UART timer. - - Ethernet.begin(mac, ip, gateway, subnet); - server.begin(); - Serial.print("server is at "); - Serial.println(Ethernet.localIP()); - while (!Serial); // wait for Leonardo enumeration, others continue immediately - - // initialize device - Serial.println(F("Initializing I2C devices...")); - mpu.initialize(); - pinMode(INTERRUPT_PIN, INPUT); - - // verify connection - Serial.println(F("Testing device connections...")); - Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); - - // load and configure the DMP - Serial.println(F("Initializing DMP...")); - devStatus = mpu.dmpInitialize(); - - // supply your own gyro offsets here, scaled for min sensitivity - mpu.setXGyroOffset(220); - mpu.setYGyroOffset(76); - mpu.setZGyroOffset(-85); - mpu.setZAccelOffset(1788); // 1688 factory default for my test chip - - // make sure it worked (returns 0 if so) - if (devStatus == 0) { - // turn on the DMP, now that it's ready - Serial.println(F("Enabling DMP...")); - mpu.setDMPEnabled(true); - - // enable Arduino interrupt detection - Serial.print(F("Enabling interrupt detection (Arduino external interrupt ")); - Serial.print(digitalPinToInterrupt(INTERRUPT_PIN)); - Serial.println(F(")...")); - attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); - mpuIntStatus = mpu.getIntStatus(); - - // set our DMP Ready flag so the main loop() function knows it's okay to use it - Serial.println(F("DMP ready! Waiting for first interrupt...")); - dmpReady = true; - - // get expected DMP packet size for later comparison - packetSize = mpu.dmpGetFIFOPacketSize(); - } else { - // ERROR! - // 1 = initial memory load failed - // 2 = DMP configuration updates failed - // (if it's going to break, usually the code will be 1) - Serial.print(F("DMP Initialization failed (code ")); - Serial.print(devStatus); - Serial.println(F(")")); - } - - // configure LED for output - pinMode(LED_PIN, OUTPUT); -} - - - -// ================================================================ -// === MAIN PROGRAM LOOP === -// ================================================================ - -void loop() { - // if programming failed, don't try to do anything - if (!dmpReady) return; - - wdt_reset();//Resets the watchdog timer. If the timer is not reset, and the timer expires, a watchdog-initiated device reset will occur. - // wait for MPU interrupt or extra packet(s) available - while (!mpuInterrupt && fifoCount < packetSize) { - if (mpuInterrupt && fifoCount < packetSize) { - // try to get out of the infinite loop - fifoCount = mpu.getFIFOCount(); - } - // other program behavior stuff here - // . - // . - // if you are really paranoid you can frequently test in between other - // stuff to see if mpuInterrupt is true, and if so, "break;" from the - // while() loop to immediately process the MPU data - // . - // . - // . - } - - // reset interrupt flag and get INT_STATUS byte - mpuInterrupt = false; - mpuIntStatus = mpu.getIntStatus(); - - // get current FIFO count - fifoCount = mpu.getFIFOCount(); - - // check for overflow (this should never happen unless our code is too inefficient) - if ((mpuIntStatus & _BV(MPU6050_IMU::MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) { - // reset so we can continue cleanly - mpu.resetFIFO(); - fifoCount = mpu.getFIFOCount(); - Serial.println(F("FIFO overflow!")); - - // otherwise, check for DMP data ready interrupt (this should happen frequently) - } else if (mpuIntStatus & _BV(MPU6050_IMU::MPU6050_INTERRUPT_DMP_INT_BIT)) { - // wait for correct available data length, should be a VERY short wait - while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); - - // read a packet from FIFO, then clear the buffer - mpu.getFIFOBytes(fifoBuffer, packetSize); - //mpu.resetFIFO(); - - // track FIFO count here in case there is > 1 packet available - // (this lets us immediately read more without waiting for an interrupt) - fifoCount -= packetSize; - - #ifdef OUTPUT_READABLE_QUATERNION - // display quaternion values in easy matrix form: w x y z - mpu.dmpGetQuaternion(&q, fifoBuffer); - Serial.print("quat\t"); - Serial.print(q.w); - Serial.print("\t"); - Serial.print(q.x); - Serial.print("\t"); - Serial.print(q.y); - Serial.print("\t"); - Serial.println(q.z); - #endif - #ifdef OUTPUT_READABLE_EULER - // display Euler angles in degrees - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetEuler(euler, &q); - Serial.print("euler\t"); - Serial.print(euler[0] * 180/M_PI); - Serial.print("\t"); - Serial.print(euler[1] * 180/M_PI); - Serial.print("\t"); - Serial.println(euler[2] * 180/M_PI); - #endif - #ifdef OUTPUT_READABLE_YAWPITCHROLL - // display Euler angles in degrees - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); - Serial.print("ypr\t"); - Serial.print(ypr[0] * 180/M_PI); - Serial.print("\t"); - Serial.print(ypr[1] * 180/M_PI); - Serial.print("\t"); - Serial.println(ypr[2] * 180/M_PI); - #endif - #ifdef OUTPUT_READABLE_REALACCEL - // display real acceleration, adjusted to remove gravity - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetAccel(&aa, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); - Serial.print("areal\t"); - Serial.print(aaReal.x); - Serial.print("\t"); - Serial.print(aaReal.y); - Serial.print("\t"); - Serial.println(aaReal.z); - #endif - #ifdef OUTPUT_READABLE_WORLDACCEL - // display initial world-frame acceleration, adjusted to remove gravity - // and rotated based on known orientation from quaternion - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetAccel(&aa, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); - mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); - Serial.print("aworld\t"); - Serial.print(aaWorld.x); - Serial.print("\t"); - Serial.print(aaWorld.y); - Serial.print("\t"); - Serial.println(aaWorld.z); - #endif - #ifdef OUTPUT_TEAPOT - // display quaternion values in InvenSense Teapot demo format: - teapotPacket[2] = fifoBuffer[0]; - teapotPacket[3] = fifoBuffer[1]; - teapotPacket[4] = fifoBuffer[4]; - teapotPacket[5] = fifoBuffer[5]; - teapotPacket[6] = fifoBuffer[8]; - teapotPacket[7] = fifoBuffer[9]; - teapotPacket[8] = fifoBuffer[12]; - teapotPacket[9] = fifoBuffer[13]; - Serial.write(teapotPacket, 14); - teapotPacket[11]++; // packetCount, loops at 0xFF on purpose - #endif - serversend(); - // blink LED to indicate activity - blinkState = !blinkState; - digitalWrite(LED_PIN, blinkState); - } -} - -void serversend(){ - - EthernetClient client = server.available(); // try to get client - - if (client) { // got client? - //boolean currentLineIsBlank = true; - while (client.connected()) { - if (client.available()) { // client data available to read - char c = client.read(); // read 1 byte (character) from client - HTTP_req += c; // save the HTTP request 1 char at a time - // last line of client request is blank and ends with \n - // respond to client only after last line received - if (c == '\n') { - // send a standard http response header - client.println("HTTP/1.1 200 OK"); - client.println("Content-Type: text/html"); - //client.println("Connection: keep-alive"); - client.println(); - // AJAX request for switch state - if (HTTP_req.indexOf("ajax_switch") > -1) { - // read switch state and analog input - GetAjaxData(client); - } - else { // HTTP request for web page - // send web page - contains JavaScript with AJAX calls - client.println("<!DOCTYPE html>"); - client.println("<html>"); - client.println("<head>"); - client.println("<title>Arduino Web Page</title>"); - client.println("<script>"); - client.println("function GetAjaxData() {"); - client.println( - "nocache = \"&nocache=\" + Math.random() * 1000000;"); - client.println("var request = new XMLHttpRequest();"); - client.println("request.onreadystatechange = function() {"); - client.println("if (this.readyState == 4) {"); - client.println("if (this.status == 200) {"); - client.println("if (this.responseText != null) {"); - client.println("document.getElementById(\"sw_an_data\")\ -.innerHTML = this.responseText;"); - client.println("}}}}"); - client.println( - "request.open(\"GET\", \"ajax_switch\" + nocache, true);"); - client.println("request.send(null);"); - client.println("setTimeout('GetAjaxData()', 10);"); - client.println("}"); - client.println("</script>"); - client.println("</head>"); - client.println("<body onload=\"GetAjaxData()\">"); - client.println("<h1>MPU6050 Output</h1>"); - client.println("<div id=\"sw_an_data\">"); - client.println("</div>"); - client.println("</body>"); - client.println("</html>"); - } - // display received HTTP request on serial port - Serial.print(HTTP_req); - HTTP_req = ""; // finished with request, empty string - client.stop(); // close the connection - break; - } - } - } - } -} - -void GetAjaxData(EthernetClient cl) -{ - #ifdef OUTPUT_READABLE_QUATERNION - // display quaternion values in easy matrix form: w x y z - cl.print("Quaternion Values:\t"); - cl.print("<p>w:"); - cl.print(q.w); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>x:"); - cl.print(q.x); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>y:"); - cl.print(q.y); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>z:"); - cl.print(q.z); - cl.print("\t"); - cl.println("</p>"); - #endif - #ifdef OUTPUT_READABLE_EULER - // display Euler angles in degrees - cl.print("Euler Angles:\t"); - cl.print("<p>Yaw:"); - cl.print(euler[0] * 180/M_PI); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>Pitch:"); - cl.print(euler[2] * 180/M_PI); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>Roll:"); - cl.print(euler[1] * 180/M_PI); - cl.print("\t"); - cl.println("</p>"); - #endif - #ifdef OUTPUT_READABLE_YAWPITCHROLL - // display Yaw/Pitch/Roll values in degrees - cl.print("Yaw, Pitch, and Roll:\t"); - cl.print("<p>Yaw:"); - cl.print(ypr[0] * 180/M_PI); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>Pitch:"); - cl.print(ypr[2] * 180/M_PI); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>Roll:"); - cl.print(ypr[1] * 180/M_PI); - cl.print("\t"); - cl.println("</p>"); - #endif - #ifdef OUTPUT_READABLE_REALACCEL - // display real acceleration, adjusted to remove gravity - cl.print("Real Accel:\t"); - cl.print("<p>Yaw:"); - cl.print(aaReal.x); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>Pitch:"); - cl.print(aaReal.z); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>Roll:"); - cl.print(aaReal.y); - cl.print("\t"); - cl.println("</p>"); - #endif - #ifdef OUTPUT_READABLE_WORLDACCEL - // display initial world-frame acceleration, adjusted to remove gravity - // and rotated based on known orientation from quaternion - cl.print("World Accel:\t"); - cl.print("<p>Yaw:"); - cl.print(aaWorld.x); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>Pitch:"); - cl.print(aaWorld.z); - cl.print("\t"); - cl.println("</p>"); - cl.print("<p>Roll:"); - cl.print(aaWorld.y); - cl.print("\t"); - cl.println("</p>"); - #endif - #ifdef OUTPUT_TEAPOT - cl.print("<p>teapotpacket:"); - cl.write(teapotPacket, 14); - cl.print("\t"); - cl.println("</p>"); - #endif -} diff --git a/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPU6050_DMP6_using_DMP_V6v12.ino b/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPU6050_DMP6_using_DMP_V6v12.ino deleted file mode 100644 index 9a87db5ca11f0732ff4d24a3f088ea8d57a9de90..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPU6050_DMP6_using_DMP_V6v12.ino +++ /dev/null @@ -1,368 +0,0 @@ -// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v6.12) -// 6/21/2012 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2019-07-10 - Uses the new version of the DMP Firmware V6.12 -// - Note: I believe the Teapot demo is broken with this versin as -// - the fifo buffer structure has changed -// 2016-04-18 - Eliminated a potential infinite loop -// 2013-05-08 - added seamless Fastwire support -// - added note about gyro calibration -// 2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error -// 2012-06-20 - improved FIFO overflow handling and simplified read process -// 2012-06-19 - completely rearranged DMP initialization code and simplification -// 2012-06-13 - pull gyro and accel data from FIFO packet instead of reading directly -// 2012-06-09 - fix broken FIFO read sequence and change interrupt detection to RISING -// 2012-06-05 - add gravity-compensated initial reference frame acceleration output -// - add 3D math helper file to DMP6 example sketch -// - add Euler output and Yaw/Pitch/Roll output formats -// 2012-06-04 - remove accel offset clearing for better results (thanks Sungon Lee) -// 2012-06-01 - fixed gyro sensitivity to be 2000 deg/sec instead of 250 -// 2012-05-30 - basic DMP initialization working - -/* ============================================ - I2Cdev device library code is placed under the MIT license - Copyright (c) 2012 Jeff Rowberg - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - =============================================== -*/ - -// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files -// for both classes must be in the include path of your project -#include "I2Cdev.h" - -#include "MPU6050_6Axis_MotionApps_V6_12.h" -//#include "MPU6050.h" // not necessary if using MotionApps include file - -// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation -// is used in I2Cdev.h -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE -#include "Wire.h" -#endif - -// class default I2C address is 0x68 -// specific I2C addresses may be passed as a parameter here -// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) -// AD0 high = 0x69 -MPU6050 mpu; -//MPU6050 mpu(0x69); // <-- use for AD0 high - -/* ========================================================================= - NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch - depends on the MPU-6050's INT pin being connected to the Arduino's - external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is - digital I/O pin 2. - ========================================================================= */ - -/* ========================================================================= - NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error - when using Serial.write(buf, len). The Teapot output uses this method. - The solution requires a modification to the Arduino USBAPI.h file, which - is fortunately simple, but annoying. This will be fixed in the next IDE - release. For more info, see these links: - - http://arduino.cc/forum/index.php/topic,109987.0.html - http://code.google.com/p/arduino/issues/detail?id=958 - ========================================================================= */ - - - -// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual -// quaternion components in a [w, x, y, z] format (not best for parsing -// on a remote host such as Processing or something though) -//#define OUTPUT_READABLE_QUATERNION - -// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles -// (in degrees) calculated from the quaternions coming from the FIFO. -// Note that Euler angles suffer from gimbal lock (for more info, see -// http://en.wikipedia.org/wiki/Gimbal_lock) -//#define OUTPUT_READABLE_EULER - -// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/ -// pitch/roll angles (in degrees) calculated from the quaternions coming -// from the FIFO. Note this also requires gravity vector calculations. -// Also note that yaw/pitch/roll angles suffer from gimbal lock (for -// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock) -#define OUTPUT_READABLE_YAWPITCHROLL - -// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration -// components with gravity removed. This acceleration reference frame is -// not compensated for orientation, so +X is always +X according to the -// sensor, just without the effects of gravity. If you want acceleration -// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead. -//#define OUTPUT_READABLE_REALACCEL - -// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration -// components with gravity removed and adjusted for the world frame of -// reference (yaw is relative to initial orientation, since no magnetometer -// is present in this case). Could be quite handy in some cases. -//#define OUTPUT_READABLE_WORLDACCEL - -// uncomment "OUTPUT_TEAPOT" if you want output that matches the -// format used for the InvenSense teapot demo -//#define OUTPUT_TEAPOT - - - -#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards -#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) -bool blinkState = false; - -// MPU control/status vars -bool dmpReady = false; // set true if DMP init was successful -uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU -uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) -uint16_t packetSize; // expected DMP packet size (default is 42 bytes) -uint16_t fifoCount; // count of all bytes currently in FIFO -uint8_t fifoBuffer[64]; // FIFO storage buffer - -// orientation/motion vars -Quaternion q; // [w, x, y, z] quaternion container -VectorInt16 aa; // [x, y, z] accel sensor measurements -VectorInt16 gy; // [x, y, z] gyro sensor measurements -VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements -VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements -VectorFloat gravity; // [x, y, z] gravity vector -float euler[3]; // [psi, theta, phi] Euler angle container -float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector - -// packet structure for InvenSense teapot demo -uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' }; - - - -// ================================================================ -// === INTERRUPT DETECTION ROUTINE === -// ================================================================ - -volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high -void dmpDataReady() { - mpuInterrupt = true; -} - - - -// ================================================================ -// === INITIAL SETUP === -// ================================================================ - -void setup() { - // join I2C bus (I2Cdev library doesn't do this automatically) -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - Wire.begin(); - Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties -#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE - Fastwire::setup(400, true); -#endif - - // initialize serial communication - // (115200 chosen because it is required for Teapot Demo output, but it's - // really up to you depending on your project) - Serial.begin(115200); - while (!Serial); // wait for Leonardo enumeration, others continue immediately - - // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3V or Arduino - // Pro Mini running at 3.3V, cannot handle this baud rate reliably due to - // the baud timing being too misaligned with processor ticks. You must use - // 38400 or slower in these cases, or use some kind of external separate - // crystal solution for the UART timer. - - // initialize device - Serial.println(F("Initializing I2C devices...")); - mpu.initialize(); - pinMode(INTERRUPT_PIN, INPUT); - - // verify connection - Serial.println(F("Testing device connections...")); - Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); - - // wait for ready - Serial.println(F("\nSend any character to begin DMP programming and demo: ")); - while (Serial.available() && Serial.read()); // empty buffer - while (!Serial.available()); // wait for data - while (Serial.available() && Serial.read()); // empty buffer again - - // load and configure the DMP - Serial.println(F("Initializing DMP...")); - devStatus = mpu.dmpInitialize(); - - // supply your own gyro offsets here, scaled for min sensitivity - mpu.setXGyroOffset(51); - mpu.setYGyroOffset(8); - mpu.setZGyroOffset(21); - mpu.setXAccelOffset(1150); - mpu.setYAccelOffset(-50); - mpu.setZAccelOffset(1060); - // make sure it worked (returns 0 if so) - if (devStatus == 0) { - // Calibration Time: generate offsets and calibrate our MPU6050 - mpu.CalibrateAccel(6); - mpu.CalibrateGyro(6); - Serial.println(); - mpu.PrintActiveOffsets(); - // turn on the DMP, now that it's ready - Serial.println(F("Enabling DMP...")); - mpu.setDMPEnabled(true); - - // enable Arduino interrupt detection - Serial.print(F("Enabling interrupt detection (Arduino external interrupt ")); - Serial.print(digitalPinToInterrupt(INTERRUPT_PIN)); - Serial.println(F(")...")); - attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); - mpuIntStatus = mpu.getIntStatus(); - - // set our DMP Ready flag so the main loop() function knows it's okay to use it - Serial.println(F("DMP ready! Waiting for first interrupt...")); - dmpReady = true; - - // get expected DMP packet size for later comparison - packetSize = mpu.dmpGetFIFOPacketSize(); - } else { - // ERROR! - // 1 = initial memory load failed - // 2 = DMP configuration updates failed - // (if it's going to break, usually the code will be 1) - Serial.print(F("DMP Initialization failed (code ")); - Serial.print(devStatus); - Serial.println(F(")")); - } - - // configure LED for output - pinMode(LED_PIN, OUTPUT); -} - - - -// ================================================================ -// === MAIN PROGRAM LOOP === -// ================================================================ - -void loop() { - // if programming failed, don't try to do anything - if (!dmpReady) return; - // read a packet from FIFO - if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet - -#ifdef OUTPUT_READABLE_QUATERNION - // display quaternion values in easy matrix form: w x y z - mpu.dmpGetQuaternion(&q, fifoBuffer); - Serial.print("quat\t"); - Serial.print(q.w); - Serial.print("\t"); - Serial.print(q.x); - Serial.print("\t"); - Serial.print(q.y); - Serial.print("\t"); - Serial.println(q.z); -#endif - -#ifdef OUTPUT_READABLE_EULER - // display Euler angles in degrees - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetEuler(euler, &q); - Serial.print("euler\t"); - Serial.print(euler[0] * 180 / M_PI); - Serial.print("\t"); - Serial.print(euler[1] * 180 / M_PI); - Serial.print("\t"); - Serial.println(euler[2] * 180 / M_PI); -#endif - -#ifdef OUTPUT_READABLE_YAWPITCHROLL - // display Euler angles in degrees - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); - Serial.print("ypr\t"); - Serial.print(ypr[0] * 180 / M_PI); - Serial.print("\t"); - Serial.print(ypr[1] * 180 / M_PI); - Serial.print("\t"); - Serial.print(ypr[2] * 180 / M_PI); - /* - mpu.dmpGetAccel(&aa, fifoBuffer); - Serial.print("\tRaw Accl XYZ\t"); - Serial.print(aa.x); - Serial.print("\t"); - Serial.print(aa.y); - Serial.print("\t"); - Serial.print(aa.z); - mpu.dmpGetGyro(&gy, fifoBuffer); - Serial.print("\tRaw Gyro XYZ\t"); - Serial.print(gy.x); - Serial.print("\t"); - Serial.print(gy.y); - Serial.print("\t"); - Serial.print(gy.z); - */ - Serial.println(); - -#endif - -#ifdef OUTPUT_READABLE_REALACCEL - // display real acceleration, adjusted to remove gravity - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetAccel(&aa, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); - Serial.print("areal\t"); - Serial.print(aaReal.x); - Serial.print("\t"); - Serial.print(aaReal.y); - Serial.print("\t"); - Serial.println(aaReal.z); -#endif - -#ifdef OUTPUT_READABLE_WORLDACCEL - // display initial world-frame acceleration, adjusted to remove gravity - // and rotated based on known orientation from quaternion - mpu.dmpGetQuaternion(&q, fifoBuffer); - mpu.dmpGetAccel(&aa, fifoBuffer); - mpu.dmpGetGravity(&gravity, &q); - mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); - mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); - Serial.print("aworld\t"); - Serial.print(aaWorld.x); - Serial.print("\t"); - Serial.print(aaWorld.y); - Serial.print("\t"); - Serial.println(aaWorld.z); -#endif - -#ifdef OUTPUT_TEAPOT - // display quaternion values in InvenSense Teapot demo format: - teapotPacket[2] = fifoBuffer[0]; - teapotPacket[3] = fifoBuffer[1]; - teapotPacket[4] = fifoBuffer[4]; - teapotPacket[5] = fifoBuffer[5]; - teapotPacket[6] = fifoBuffer[8]; - teapotPacket[7] = fifoBuffer[9]; - teapotPacket[8] = fifoBuffer[12]; - teapotPacket[9] = fifoBuffer[13]; - Serial.write(teapotPacket, 14); - teapotPacket[11]++; // packetCount, loops at 0xFF on purpose -#endif - - // blink LED to indicate activity - blinkState = !blinkState; - digitalWrite(LED_PIN, blinkState); - } -} diff --git a/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/MPUplane.pde b/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/MPUplane.pde deleted file mode 100644 index 7aded8f131a38c38a6fac6a3a215665be2945dfb..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/MPUplane.pde +++ /dev/null @@ -1,189 +0,0 @@ -// I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output -// 6/20/2012 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2012-06-20 - initial release -// 2016-10-28 - Changed to bi-plane 3d model based on tutorial at -// https://forum.processing.org/two/discussion/24350/display-obj-file-in-3d -// https://opengameart.org/content/low-poly-biplane - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -import processing.serial.*; -//import processing.opengl.*; -import toxi.geom.*; -import toxi.processing.*; - -// NOTE: requires ToxicLibs to be installed in order to run properly. -// 1. Download from https://github.com/postspectacular/toxiclibs/releases -// 2. Extract into [userdir]/Processing/libraries -// (location may be different on Mac/Linux) -// 3. Run and bask in awesomeness - -ToxiclibsSupport gfx; - -Serial port; // The serial port -char[] teapotPacket = new char[14]; // InvenSense Teapot packet -int serialCount = 0; // current packet byte position -int synced = 0; -int interval = 0; - -float[] q = new float[4]; -Quaternion quat = new Quaternion(1, 0, 0, 0); - -float[] gravity = new float[3]; -float[] euler = new float[3]; -float[] ypr = new float[3]; - - -PShape plane; // 3d model - -void setup() { - // 640x480 px square viewport - size(640, 480, P3D); - gfx = new ToxiclibsSupport(this); - - // setup lights and antialiasing - lights(); - smooth(); - - // display serial port list for debugging/clarity - println(Serial.list()); - - // get a specific serial port - String portName = "COM12"; - - // open the serial port - port = new Serial(this, portName, 115200); - - // send single character to trigger DMP init/start - // (expected by MPU6050_DMP6 example Arduino sketch) - port.write('r'); - - // Load Plane object - // The file must be in the \data folder - // of the current sketch to load successfully - plane = loadShape("biplane.obj"); - - - // apply its texture and set orientation - PImage img1=loadImage("diffuse_512.png"); - plane.setTexture(img1); - plane.scale(30); - plane.rotateX(PI); - plane.rotateY(PI+HALF_PI); - - -} - -void draw() { - if (millis() - interval > 1000) { - // resend single character to trigger DMP init/start - // in case the MPU is halted/reset while applet is running - port.write('r'); - interval = millis(); - } - - // black background - background(0); - - - // translate everything to the middle of the viewport - pushMatrix(); - translate(width / 2, height / 2); - - // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!) - // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of - // different coordinate system orientation assumptions between Processing - // and InvenSense DMP) - float[] axis = quat.toAxisAngle(); - rotate(axis[0], -axis[1], axis[3], axis[2]); - - // draw plane - shape(plane, 0, 0); - - popMatrix(); -} - -void serialEvent(Serial port) { - interval = millis(); - while (port.available() > 0) { - int ch = port.read(); - - if (synced == 0 && ch != '$') return; // initial synchronization - also used to resync/realign if needed - synced = 1; - print ((char)ch); - - if ((serialCount == 1 && ch != 2) - || (serialCount == 12 && ch != '\r') - || (serialCount == 13 && ch != '\n')) { - serialCount = 0; - synced = 0; - return; - } - - if (serialCount > 0 || ch == '$') { - teapotPacket[serialCount++] = (char)ch; - if (serialCount == 14) { - serialCount = 0; // restart packet byte position - - // get quaternion from data packet - q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f; - q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f; - q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f; - q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f; - for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i]; - - // set our toxilibs quaternion to new data - quat.set(q[0], q[1], q[2], q[3]); - - - // below calculations unnecessary for orientation only using toxilibs - - // calculate gravity vector - gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]); - gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]); - gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3]; - - // calculate Euler angles - euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1); - euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]); - euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1); - - // calculate yaw/pitch/roll angles - ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1); - ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2])); - ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2])); - - // output various components for debugging - println("q:\t" + round(q[0]*100.0f)/100.0f + "\t" + round(q[1]*100.0f)/100.0f + "\t" + round(q[2]*100.0f)/100.0f + "\t" + round(q[3]*100.0f)/100.0f); - println("euler:\t" + euler[0]*180.0f/PI + "\t" + euler[1]*180.0f/PI + "\t" + euler[2]*180.0f/PI); - println("ypr:\t" + ypr[0]*180.0f/PI + "\t" + ypr[1]*180.0f/PI + "\t" + ypr[2]*180.0f/PI); - - } - } - } -} diff --git a/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/biplane.obj b/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/biplane.obj deleted file mode 100644 index 6867928e7d89915fe07658b08d435db7c3ccdd39..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/biplane.obj +++ /dev/null @@ -1,2239 +0,0 @@ -v 4.500000 0.176989 0.367522 -v 4.500000 0.318923 0.254332 -v 4.500000 0.397690 0.090770 -v 4.500000 0.397690 -0.090770 -v 4.500000 0.318923 -0.254333 -v 4.500000 0.176989 -0.367521 -v 4.500000 0.000000 -0.407918 -v 4.500000 -0.176989 -0.367521 -v 4.500000 -0.318923 -0.254332 -v 4.500000 -0.397691 -0.090770 -v 4.500000 -0.397691 0.090770 -v 4.500000 -0.318923 0.254333 -v 4.500001 -0.176989 0.367522 -v 4.500000 0.000000 0.407918 -v 2.700000 0.259478 0.538812 -v 2.700000 0.467563 0.372869 -v 2.700000 0.583042 0.133076 -v 2.700000 0.583042 -0.133076 -v 2.700000 0.467563 -0.372869 -v 2.700000 0.259478 -0.538812 -v 2.700000 0.000000 -0.598036 -v 2.700000 -0.259478 -0.538812 -v 2.700000 -0.467563 -0.372869 -v 2.700000 -0.583042 -0.133075 -v 2.700000 -0.583042 0.133075 -v 2.700000 -0.467563 0.372870 -v 2.700000 -0.259478 0.538812 -v 2.700000 0.000000 0.598036 -v 0.900000 0.323112 0.670950 -v 0.900000 0.582229 0.464312 -v 0.900000 0.726027 0.165711 -v 0.900000 0.726027 -0.165711 -v 0.900000 0.582229 -0.464312 -v 0.900000 0.323113 -0.670950 -v 0.900000 0.000000 -0.744698 -v 0.900000 -0.323112 -0.670950 -v 0.900000 -0.582229 -0.464312 -v 0.900000 -0.726027 -0.165711 -v 0.900000 -0.726027 0.165711 -v 0.900000 -0.582229 0.464312 -v 0.900000 -0.323113 0.670950 -v 0.900000 0.000000 0.744699 -v -0.900000 0.384390 0.798195 -v -0.900000 0.692647 0.552368 -v -0.475444 0.863717 0.197138 -v -0.475445 0.863717 -0.197138 -v -0.900000 0.692647 -0.552368 -v -0.900000 0.384390 -0.798194 -v -0.900000 0.000000 -0.885929 -v -0.900000 -0.384390 -0.798195 -v -0.900000 -0.692647 -0.552368 -v -0.900000 -0.863717 -0.197138 -v -0.900000 -0.863717 0.197138 -v -0.900000 -0.692647 0.552368 -v -0.900000 -0.384390 0.798195 -v -0.900000 0.000000 0.885929 -v -2.700000 0.433883 0.900969 -v -2.700000 0.781831 0.623490 -v -2.885778 0.974928 0.222521 -v -2.885778 0.974928 -0.222521 -v -2.700000 0.781832 -0.623490 -v -2.699999 0.433884 -0.900969 -v -2.699999 0.000000 -1.000000 -v -2.700000 -0.433883 -0.900969 -v -2.700000 -0.781831 -0.623490 -v -2.700000 -0.974928 -0.222521 -v -2.700000 -0.974928 0.222521 -v -2.700000 -0.781832 0.623489 -v -2.700000 -0.433884 0.900969 -v -2.700000 0.000000 1.000000 -v 4.500000 0.000000 -0.000000 -v -5.181942 0.000000 -0.000000 -v 5.269916 1.092397 0.090771 -v 5.269916 1.092397 -0.090770 -v 3.399458 1.972455 0.000001 -v 5.551387 0.000000 -0.000000 -v 4.141554 0.176989 1.784806 -v 4.500000 0.318923 1.235124 -v 2.700000 0.467563 1.342699 -v 3.058446 0.259478 1.802116 -v 4.500000 0.318923 -1.235123 -v 4.141554 0.176989 -1.784806 -v 3.058446 0.259478 -1.802116 -v 2.700000 0.467563 -1.342699 -v -1.300000 1.103771 0.487962 -v -1.125000 1.252653 0.195352 -v -2.475000 1.333997 0.213918 -v -2.300000 1.156989 0.519851 -v -1.125000 1.252653 -0.195351 -v -2.475000 1.333997 -0.213917 -v -1.300000 1.103772 -0.487962 -v -2.300000 1.156989 -0.519851 -v -1.799999 1.281724 0.398879 -v -1.125000 1.187470 0.380784 -v -1.800000 1.350005 0.204635 -v -2.475000 1.262618 0.416974 -v -1.800000 1.156763 0.540666 -v -1.800000 1.372766 0.000000 -v -1.125000 1.274381 0.000000 -v -1.800000 1.350006 -0.204634 -v -2.475000 1.357790 0.000000 -v -1.800000 1.281724 -0.398879 -v -1.125000 1.187470 -0.380784 -v -1.800000 1.156763 -0.540666 -v -2.475000 1.262618 -0.416974 -v -0.825593 1.004904 0.374753 -v -0.475445 0.778182 0.374753 -v -0.825593 1.069055 0.192257 -v -1.125000 0.951901 0.516854 -v -2.700000 1.105101 0.423005 -v -2.885779 0.878380 0.423006 -v -2.475000 1.021542 0.564478 -v -2.700000 1.177512 0.217012 -v -1.800000 0.963961 0.587929 -v -1.800000 0.737239 0.587929 -v -0.825593 1.090439 0.000000 -v -0.475445 0.863717 0.000000 -v -0.825593 1.069055 -0.192257 -v -2.700000 1.201650 0.000000 -v -2.885779 0.974928 0.000000 -v -2.700000 1.177513 -0.217012 -v -0.825592 1.004904 -0.374753 -v -0.475444 0.778182 -0.374753 -v -1.125000 0.951901 -0.516854 -v -1.800000 0.963961 -0.587929 -v -1.800000 0.737239 -0.587929 -v -2.475000 1.021542 -0.564478 -v -2.700000 1.105101 -0.423005 -v -2.885778 0.878380 -0.423005 -v 2.700000 0.583042 0.000000 -v 0.900000 0.726027 0.005801 -v -5.181943 -0.629401 -0.501931 -v -4.986976 -0.781831 -0.623490 -v -5.181942 -0.784850 -0.179137 -v -4.986976 -0.974928 -0.222521 -v -5.181942 -0.784850 0.179137 -v -4.986976 -0.974928 0.222521 -v -5.181942 -0.629401 0.501930 -v -4.986977 -0.781831 0.623490 -v -5.181942 -0.349291 0.725311 -v -4.986976 -0.433884 0.900969 -v -4.986976 0.000000 1.000000 -v -5.181942 0.000000 0.805034 -v -5.181942 0.629401 -0.501930 -v -4.987885 0.789991 -0.606546 -v -4.986976 0.781832 -0.623490 -v -5.181942 0.349291 -0.725310 -v -4.986977 0.433884 -0.900968 -v -4.986976 0.433884 0.900969 -v -5.181942 0.349291 0.725311 -v -4.986976 0.781831 0.623490 -v -4.987885 0.789991 0.606546 -v -5.181942 0.629401 0.501931 -v -4.986976 0.974928 0.222521 -v -5.181942 0.784301 0.179012 -v -5.181942 0.000000 -0.805034 -v -4.986976 0.000000 -1.000000 -v -5.181942 -0.349291 -0.725310 -v -4.986976 -0.433884 -0.900969 -v -5.181942 0.784301 -0.179011 -v -4.986976 0.974928 -0.222521 -v -5.181942 0.779962 0.000001 -v -4.986976 0.974928 0.000000 -vt 0.455704 0.153054 -vt 0.419776 0.128644 -vt 0.383319 0.143119 -vt 0.328896 0.143119 -vt 0.292439 0.128644 -vt 0.256511 0.153054 -vt 0.245563 0.201018 -vt 0.256511 0.248981 -vt 0.287184 0.287445 -vt 0.331509 0.308790 -vt 0.380706 0.308790 -vt 0.425031 0.287445 -vt 0.455704 0.248981 -vt 0.466652 0.201018 -vt 0.005173 0.359445 -vt 0.016095 0.354912 -vt 0.061664 0.354281 -vt 0.166522 0.327467 -vt 0.186034 0.323730 -vt 0.219371 0.310411 -vt 0.248725 0.289652 -vt 0.263886 0.273262 -vt 0.275993 0.321494 -vt 0.305445 0.321494 -vt 0.334898 0.321494 -vt 0.364351 0.321494 -vt 0.393803 0.321494 -vt 0.423256 0.321494 -vt 0.452709 0.321494 -vt 0.019054 0.449768 -vt 0.082140 0.442189 -vt 0.099276 0.445505 -vt 0.128729 0.445505 -vt 0.158182 0.445505 -vt 0.187634 0.445505 -vt 0.217087 0.445505 -vt 0.246540 0.445505 -vt 0.275993 0.445505 -vt 0.305445 0.445505 -vt 0.334898 0.445505 -vt 0.364351 0.445505 -vt 0.393803 0.445505 -vt 0.423256 0.445505 -vt 0.452709 0.445505 -vt 0.040371 0.569517 -vt 0.069824 0.569517 -vt 0.099276 0.569517 -vt 0.128729 0.569517 -vt 0.158182 0.569517 -vt 0.187634 0.569517 -vt 0.217087 0.569517 -vt 0.246540 0.569517 -vt 0.275993 0.569517 -vt 0.305445 0.569517 -vt 0.334898 0.569517 -vt 0.364351 0.569517 -vt 0.393803 0.569517 -vt 0.423256 0.569517 -vt 0.452709 0.569517 -vt 0.040371 0.693528 -vt 0.073505 0.709029 -vt 0.099276 0.685777 -vt 0.128729 0.685777 -vt 0.154500 0.709029 -vt 0.187634 0.693528 -vt 0.217087 0.693528 -vt 0.246540 0.693528 -vt 0.275993 0.693528 -vt 0.305445 0.693528 -vt 0.334898 0.693528 -vt 0.364351 0.693528 -vt 0.393803 0.693528 -vt 0.423256 0.693528 -vt 0.452709 0.693528 -vt 0.040371 0.817539 -vt 0.073505 0.802038 -vt 0.154500 0.802038 -vt 0.356107 0.180046 -vt 0.098756 0.319100 -vt 0.114003 0.445505 -vt 0.087917 0.323202 -vt 0.360587 0.109025 -vt 0.356108 0.136215 -vt 0.351628 0.109025 -vt 0.023534 0.441375 -vt 0.044323 0.425256 -vt 0.082140 0.442189 -vt 0.019054 0.449768 -vt 0.204695 0.353513 -vt 0.203181 0.378966 -vt 0.187634 0.445505 -vt 0.158182 0.445505 -vt 0.076369 0.721086 -vt 0.099276 0.709029 -vt 0.099276 0.802038 -vt 0.076369 0.789982 -vt 0.128729 0.709029 -vt 0.128729 0.802038 -vt 0.151637 0.721086 -vt 0.151637 0.789982 -vt 0.084550 0.755534 -vt 0.084550 0.709029 -vt 0.099276 0.755534 -vt 0.084550 0.802038 -vt 0.073505 0.755534 -vt 0.114003 0.755534 -vt 0.114003 0.709029 -vt 0.128729 0.755534 -vt 0.114003 0.802038 -vt 0.143455 0.755534 -vt 0.143455 0.709029 -vt 0.154500 0.755534 -vt 0.143455 0.802038 -vt 0.084550 0.693528 -vt 0.084550 0.693528 -vt 0.099276 0.693528 -vt 0.073505 0.709029 -vt 0.084550 0.817539 -vt 0.073505 0.802038 -vt 0.099276 0.817539 -vt 0.069824 0.755534 -vt 0.069824 0.755534 -vt 0.114003 0.693528 -vt 0.114003 0.693528 -vt 0.128729 0.693528 -vt 0.114003 0.817539 -vt 0.128729 0.817539 -vt 0.143455 0.693528 -vt 0.143455 0.693528 -vt 0.154500 0.709029 -vt 0.158182 0.755534 -vt 0.158182 0.755534 -vt 0.154500 0.802038 -vt 0.143455 0.817539 -vt 0.114003 0.445505 -vt 0.113487 0.569517 -vt 0.084550 0.817539 -vt 0.063450 0.938935 -vt 0.275993 0.817539 -vt 0.060733 0.120401 -vt 0.305445 0.817539 -vt 0.104650 0.099252 -vt 0.334898 0.817539 -vt 0.153395 0.099252 -vt 0.364351 0.817539 -vt 0.197313 0.120401 -vt 0.423256 0.925429 -vt 0.393803 0.817539 -vt 0.423256 0.817539 -vt 0.143455 0.817539 -vt 0.060733 0.291667 -vt 0.030341 0.253557 -vt 0.449688 0.935863 -vt 0.452709 0.817539 -vt 0.053984 0.934786 -vt 0.017895 0.932919 -vt 0.100219 0.950069 -vt 0.102123 0.931740 -vt 0.099276 0.825290 -vt 0.217087 0.817539 -vt 0.187634 0.817539 -vt 0.019494 0.206034 -vt 0.030341 0.158511 -vt 0.246540 0.817539 -vt 0.104667 0.312738 -vt 0.129023 0.201653 -vt 0.128729 0.825290 -vt 0.114003 0.817539 -vt 0.129023 0.312124 -vt 0.275993 0.931809 -vt 0.273121 0.941551 -vt 0.249411 0.941551 -vt 0.278864 0.941551 -vt 0.305445 0.931809 -vt 0.302574 0.941551 -vt 0.308316 0.941551 -vt 0.334898 0.931809 -vt 0.332027 0.941551 -vt 0.337769 0.941551 -vt 0.364351 0.931809 -vt 0.361480 0.941551 -vt 0.367222 0.941551 -vt 0.396310 0.932910 -vt 0.390932 0.941551 -vt 0.227704 0.158511 -vt 0.153378 0.312738 -vt 0.066951 0.949302 -vt 0.411698 0.969294 -vt 0.007495 0.983733 -vt 0.156937 0.931070 -vt 0.155311 0.941551 -vt 0.131609 0.941551 -vt 0.161053 0.941551 -vt 0.187634 0.931809 -vt 0.184763 0.941551 -vt 0.190506 0.941551 -vt 0.217087 0.931809 -vt 0.214216 0.941551 -vt 0.437979 0.994491 -vt 0.197313 0.291667 -vt 0.050289 0.993403 -vt 0.393883 0.992961 -vt 0.238551 0.206034 -vt 0.102156 0.941551 -vt 0.114003 0.931021 -vt 0.219958 0.941551 -vt 0.246540 0.931809 -vt 0.243669 0.941551 -vt 0.128729 0.931680 -vt 0.125850 0.941551 -vt 0.114003 0.941551 -vt 0.158299 0.939937 -vt 0.157893 0.930592 -vt 0.227704 0.253557 -vt 0.046355 0.992034 -vt 0.421247 0.969294 -vn 0.089573 0.940981 0.326392 -vn 0.089573 0.940981 0.326392 -vn 0.089573 0.940981 0.326392 -vn 0.089573 0.940981 0.326392 -vn 0.089574 0.940981 -0.326392 -vn 0.089574 0.940981 -0.326392 -vn 0.089574 0.940981 -0.326392 -vn 0.089574 0.940981 -0.326392 -vn 0.150361 -0.955640 -0.253265 -vn 0.180233 0.000001 -0.983624 -vn 0.091281 0.000000 -0.995825 -vn -0.150994 -0.690915 -0.706992 -vn 0.180233 -0.426779 -0.886214 -vn 0.091281 -0.432073 -0.897208 -vn 0.180233 -0.769028 -0.613280 -vn 0.091281 -0.778567 -0.620887 -vn 0.180233 -0.958962 -0.218877 -vn 0.091281 -0.970858 -0.221593 -vn 0.180233 -0.958962 0.218877 -vn 0.091281 -0.970858 0.221592 -vn 0.180233 -0.769028 0.613280 -vn 0.091281 -0.778567 0.620887 -vn 0.180234 -0.426778 0.886214 -vn 0.091281 -0.432072 0.897208 -vn 0.180233 -0.000000 0.983624 -vn 0.091281 0.000000 0.995825 -vn 0.150361 -0.955640 0.253265 -vn 0.016625 -0.653805 0.756481 -vn 0.079554 0.000000 -0.996831 -vn 0.079554 0.432509 -0.898113 -vn 0.079554 -0.432508 -0.898113 -vn 0.079554 -0.779353 -0.621514 -vn 0.079554 -0.971838 -0.221816 -vn 0.079554 -0.971838 0.221816 -vn 0.079554 -0.779354 0.621514 -vn 0.079554 -0.432509 0.898113 -vn 0.079554 0.000000 0.996831 -vn 0.070121 -0.432816 -0.898751 -vn 0.070121 0.000000 -0.997539 -vn 0.070121 -0.779907 -0.621955 -vn 0.070121 -0.972528 -0.221973 -vn 0.070121 -0.972528 0.221973 -vn 0.070121 -0.779907 0.621955 -vn 0.070121 -0.432816 0.898751 -vn 0.130833 0.712633 0.689229 -vn 0.130833 0.712633 0.689229 -vn 0.130833 0.712633 0.689229 -vn 0.130833 0.712633 0.689229 -vn 0.143365 0.983605 0.109401 -vn 0.143365 0.983605 0.109401 -vn 0.143365 0.983605 0.109401 -vn 0.143365 0.983605 0.109401 -vn 0.139254 0.934218 -0.328397 -vn 0.139254 0.934218 -0.328397 -vn 0.139254 0.934218 -0.328397 -vn 0.139254 0.934218 -0.328397 -vn 0.026848 -0.433727 -0.900644 -vn 0.026848 0.000000 -0.999640 -vn 0.026848 -0.781550 -0.623265 -vn 0.026848 -0.974576 -0.222441 -vn 0.026848 -0.974577 0.222441 -vn 0.026848 -0.781550 0.623265 -vn 0.026848 -0.433728 0.900644 -vn -0.064587 -0.972892 -0.222057 -vn -0.064587 -0.780199 -0.622188 -vn -0.064587 -0.972892 0.222056 -vn -0.064587 -0.780199 0.622188 -vn -0.064587 -0.432978 0.899088 -vn 0.870350 -0.485974 0.079502 -vn 1.000000 -0.000000 -0.000000 -vn 1.000000 0.000002 -0.000003 -vn 0.870349 -0.485975 -0.079503 -vn 1.000000 -0.000003 0.000000 -vn 0.733799 -0.670454 0.109683 -vn 0.733799 -0.670454 0.109683 -vn 0.082297 0.996608 0.000000 -vn 0.082297 0.996608 0.000000 -vn 0.082297 0.996608 0.000000 -vn 0.082297 0.996608 0.000000 -vn -0.842065 -0.522167 0.135162 -vn -0.842065 -0.522167 0.135162 -vn -0.842065 -0.522167 0.135162 -vn -0.842065 -0.522167 0.135162 -vn -0.057129 -0.998367 0.000000 -vn -0.057129 -0.998367 0.000000 -vn 0.733799 -0.670455 -0.109683 -vn 0.733799 -0.670455 -0.109683 -vn -0.057129 -0.998367 -0.000000 -vn -0.057129 -0.998367 -0.000000 -vn -0.045744 0.737399 -0.673906 -vn -0.842065 -0.522167 -0.135162 -vn -0.842065 -0.522167 -0.135162 -vn 0.082297 0.996608 0.000000 -vn 0.082297 0.996608 0.000000 -vn 0.082297 0.996608 0.000000 -vn 0.082297 0.996608 0.000000 -vn 0.139254 0.934218 0.328398 -vn 0.139254 0.934218 0.328398 -vn 0.139254 0.934218 0.328398 -vn 0.139254 0.934218 0.328398 -vn -0.017811 0.943260 0.331576 -vn -0.017811 0.943260 0.331576 -vn -0.017811 0.943260 0.331576 -vn -0.017811 0.943260 0.331576 -vn -0.013215 0.722929 0.690796 -vn -0.013215 0.722929 0.690796 -vn -0.013215 0.722929 0.690796 -vn -0.013215 0.722929 0.690796 -vn 0.143365 0.983605 -0.109401 -vn 0.143365 0.983605 -0.109401 -vn 0.143365 0.983605 -0.109401 -vn 0.143365 0.983605 -0.109401 -vn -0.022046 0.993630 -0.110516 -vn -0.022046 0.993630 -0.110516 -vn -0.022046 0.993630 -0.110516 -vn -0.022046 0.993630 -0.110516 -vn -0.022046 0.993630 0.110516 -vn -0.022046 0.993630 0.110516 -vn -0.022046 0.993630 0.110516 -vn -0.022046 0.993630 0.110516 -vn 0.130833 0.712634 -0.689229 -vn 0.130833 0.712634 -0.689229 -vn 0.130833 0.712634 -0.689229 -vn 0.130833 0.712634 -0.689229 -vn -0.013215 0.722930 -0.690795 -vn -0.013215 0.722930 -0.690795 -vn -0.013215 0.722930 -0.690795 -vn -0.013215 0.722930 -0.690795 -vn -0.017811 0.943260 -0.331576 -vn -0.017811 0.943260 -0.331576 -vn -0.017811 0.943260 -0.331576 -vn -0.017811 0.943260 -0.331576 -vn -0.545911 0.790429 -0.277854 -vn -0.545911 0.790429 -0.277854 -vn -0.545911 0.790429 -0.277854 -vn -0.545911 0.790429 -0.277854 -vn -0.264463 0.503333 -0.822627 -vn -0.264463 0.503333 -0.822627 -vn -0.264463 0.503333 -0.822627 -vn -0.264463 0.503333 -0.822627 -vn 0.071428 0.391121 -0.917563 -vn -0.022348 0.280539 -0.959582 -vn -0.022348 0.280539 -0.959582 -vn -0.022348 0.280539 -0.959582 -vn -0.022348 0.280539 -0.959582 -vn -0.727792 0.633269 -0.263228 -vn -0.727792 0.633269 -0.263228 -vn -0.727792 0.633269 -0.263228 -vn -0.727792 0.633270 -0.263228 -vn 0.024936 0.422951 -0.905809 -vn 0.020457 0.652869 -0.757194 -vn 0.064463 0.552835 -0.830794 -vn -0.064587 0.432978 -0.899088 -vn -0.051952 0.691351 -0.720648 -vn -0.430065 0.475818 -0.767230 -vn -0.430065 0.475818 -0.767230 -vn -0.430065 0.475818 -0.767230 -vn -0.430065 0.475818 -0.767230 -vn 0.015304 0.118231 -0.992868 -vn 0.015304 0.118231 -0.992868 -vn 0.015304 0.118231 -0.992868 -vn 0.015304 0.118231 -0.992868 -vn -0.064587 -0.432978 -0.899088 -vn -0.064587 0.000000 -0.997912 -vn -0.567759 0.818150 -0.090998 -vn -0.567759 0.818150 -0.090998 -vn -0.567759 0.818150 -0.090998 -vn -0.567759 0.818150 -0.090998 -vn -0.755415 0.654260 -0.035929 -vn -0.755415 0.654260 -0.035929 -vn -0.755415 0.654260 -0.035929 -vn -0.755415 0.654260 -0.035929 -vn 0.000000 0.900969 -0.433884 -vn -0.072505 0.898614 -0.432707 -vn -0.082933 0.960669 -0.265023 -vn 0.000000 0.964593 -0.263742 -vn -0.924988 0.164874 0.342364 -vn -0.927519 0.290707 0.234942 -vn -1.000000 -0.000000 0.000000 -vn -0.925651 0.362381 0.108856 -vn -0.924989 -0.000000 -0.379995 -vn -0.924988 -0.164873 -0.342365 -vn -0.924989 -0.297092 -0.236923 -vn -0.924989 -0.370468 -0.084556 -vn -0.924989 -0.370467 0.084557 -vn -0.924989 -0.297092 0.236923 -vn -0.924989 -0.164874 0.342363 -vn -0.924989 0.000000 0.379995 -vn -0.727792 0.633269 0.263229 -vn -0.727792 0.633269 0.263229 -vn -0.727792 0.633269 0.263229 -vn -0.727792 0.633269 0.263229 -vn -0.545911 0.790429 0.277853 -vn -0.545911 0.790429 0.277853 -vn -0.545911 0.790429 0.277853 -vn -0.545911 0.790429 0.277853 -vn -0.755415 0.654260 0.035930 -vn -0.755415 0.654260 0.035930 -vn -0.755415 0.654260 0.035930 -vn -0.755415 0.654260 0.035930 -vn -0.567759 0.818150 0.090998 -vn -0.567759 0.818150 0.090998 -vn -0.567759 0.818150 0.090998 -vn -0.567759 0.818150 0.090998 -vn -0.076076 0.997102 0.000000 -vn -0.082933 0.960669 0.265024 -vn 0.000000 0.964593 0.263742 -vn 0.000000 1.000000 0.000000 -vn -0.942446 0.334359 0.000000 -vn -0.925651 0.362381 -0.108857 -vn -0.927519 0.290707 -0.234942 -vn -0.924989 0.164874 -0.342364 -vn -0.072505 0.898614 0.432707 -vn 0.000000 0.900969 0.433884 -vn 0.070121 -0.000000 0.997539 -vn 0.026848 -0.000000 0.999640 -vn -0.064587 0.000000 0.997912 -vn 0.015304 0.118232 0.992868 -vn 0.015304 0.118232 0.992868 -vn 0.015304 0.118232 0.992868 -vn 0.015304 0.118232 0.992868 -vn -0.022348 0.280539 0.959583 -vn -0.022348 0.280539 0.959583 -vn -0.022348 0.280539 0.959583 -vn -0.022348 0.280539 0.959583 -vn -0.051952 0.691351 0.720648 -vn -0.064587 0.432978 0.899088 -vn 0.024936 0.422951 0.905809 -vn 0.020457 0.652869 0.757194 -vn -0.430065 0.475818 0.767230 -vn -0.430065 0.475818 0.767230 -vn -0.430065 0.475818 0.767230 -vn -0.430065 0.475818 0.767230 -vn -0.264462 0.503332 0.822628 -vn -0.264462 0.503332 0.822628 -vn -0.264462 0.503332 0.822628 -vn -0.264462 0.503332 0.822628 -vn 0.079554 0.432509 0.898113 -vn 0.081210 0.779249 0.621431 -vn 0.083582 0.756709 0.648386 -vn 0.090884 0.864154 0.494952 -vn 0.074379 0.588458 0.805099 -vn 0.299258 0.416890 0.858282 -vn 0.299258 0.416890 0.858282 -vn 0.299258 0.416890 0.858282 -vn 0.299258 0.416890 0.858282 -vn 0.502967 0.815394 0.286628 -vn 0.502967 0.815394 0.286628 -vn 0.502967 0.815394 0.286628 -vn 0.502967 0.815394 0.286628 -vn 0.296862 0.477629 0.826888 -vn 0.296862 0.477629 0.826888 -vn 0.296862 0.477629 0.826888 -vn 0.296862 0.477629 0.826888 -vn 0.071428 0.391121 0.917564 -vn 0.064463 0.552834 0.830794 -vn 0.070946 0.105332 0.991903 -vn 0.070946 0.105332 0.991903 -vn 0.115643 0.269922 0.955913 -vn 0.115643 0.269922 0.955913 -vn 0.115643 0.269922 0.955913 -vn 0.115643 0.269922 0.955913 -vn 0.083582 0.756710 -0.648386 -vn 0.090884 0.864154 -0.494952 -vn 0.074379 0.588458 -0.805099 -vn 0.070946 0.105332 -0.991903 -vn 0.070946 0.105332 -0.991903 -vn 0.299258 0.416891 -0.858281 -vn 0.299258 0.416891 -0.858281 -vn 0.299258 0.416891 -0.858281 -vn 0.299258 0.416891 -0.858281 -vn 0.296862 0.477628 -0.826888 -vn 0.296862 0.477628 -0.826888 -vn 0.296862 0.477628 -0.826888 -vn 0.296862 0.477628 -0.826888 -vn 0.115643 0.269922 -0.955913 -vn 0.115643 0.269922 -0.955913 -vn 0.115643 0.269922 -0.955913 -vn 0.115643 0.269922 -0.955913 -vn 0.102431 0.896230 0.431601 -vn 0.102431 0.896230 0.431601 -vn 0.102431 0.896230 0.431601 -vn 0.102431 0.896230 0.431601 -vn 0.425735 0.904848 0.000000 -vn 0.425735 0.904848 0.000000 -vn 0.425735 0.904848 0.000000 -vn 0.102431 0.896230 -0.431601 -vn 0.102431 0.896230 -0.431601 -vn 0.102431 0.896230 -0.431601 -vn 0.102431 0.896230 -0.431601 -vn 0.968371 0.249514 0.000000 -vn 0.968371 0.249514 0.000000 -vn 0.968371 0.249514 0.000000 -vn 0.004416 0.060621 -0.998151 -vn 0.004416 0.060621 -0.998151 -vn 0.004416 0.060621 -0.998151 -vn 0.004416 0.060621 -0.998151 -vn -0.893202 0.449656 0.000001 -vn -0.893202 0.449656 0.000001 -vn -0.893202 0.449656 0.000001 -vn 0.004416 0.060620 0.998151 -vn 0.004416 0.060620 0.998151 -vn 0.004416 0.060620 0.998151 -vn 0.004416 0.060620 0.998151 -vn 0.043031 -0.112813 0.992684 -vn 0.043031 -0.112813 0.992684 -vn 0.043031 -0.112813 0.992684 -vn 0.043031 -0.112813 0.992684 -vn 0.043030 -0.112812 -0.992684 -vn 0.043030 -0.112812 -0.992684 -vn 0.043030 -0.112812 -0.992684 -vn 0.043030 -0.112812 -0.992684 -vn 0.524265 0.850274 0.046693 -vn 0.524265 0.850274 0.046693 -vn 0.524265 0.850274 0.046693 -vn 0.524265 0.850274 0.046693 -vn 0.521127 0.848248 -0.094347 -vn 0.521127 0.848248 -0.094347 -vn 0.521127 0.848248 -0.094347 -vn 0.521127 0.848248 -0.094347 -vn 0.521127 0.848248 0.094347 -vn 0.521127 0.848248 0.094347 -vn 0.521127 0.848248 0.094346 -vn 0.521127 0.848248 0.094347 -vn 0.090218 0.955033 0.282440 -vn 0.080965 0.951518 0.296745 -vn 0.493255 0.803255 0.333887 -vn 0.493255 0.803255 0.333887 -vn 0.493255 0.803255 0.333887 -vn 0.493255 0.803255 0.333887 -vn 0.102044 0.959117 0.263971 -vn 0.089030 0.996029 0.000000 -vn 0.079187 0.996860 0.000000 -vn 0.080989 0.952672 -0.293015 -vn 0.090239 0.956082 -0.278863 -vn 0.102059 0.960038 -0.260596 -vn 0.099608 0.995027 -0.000000 -vn 0.493255 0.803256 -0.333886 -vn 0.493255 0.803256 -0.333886 -vn 0.493255 0.803256 -0.333886 -vn 0.493255 0.803256 -0.333886 -vn 0.524265 0.850274 -0.046693 -vn 0.524265 0.850274 -0.046693 -vn 0.524265 0.850274 -0.046693 -vn 0.524265 0.850274 -0.046693 -vn 0.502968 0.815395 -0.286627 -vn 0.502968 0.815395 -0.286627 -vn 0.502968 0.815395 -0.286627 -vn 0.502968 0.815395 -0.286627 -vn -0.893202 0.449656 0.000002 -vn -0.893202 0.449656 0.000002 -vn -0.893202 0.449656 0.000002 -s off -f 77/85/1 78/86/2 79/87/3 80/88/4 -f 81/89/5 82/90/6 83/91/7 84/92/8 -s 1 -f 6/20/9 7/21/10 21/36/11 20/35/12 -f 7/21/10 8/22/13 22/37/14 21/36/11 -f 8/22/13 9/23/15 23/38/16 22/37/14 -f 9/23/15 10/24/17 24/39/18 23/38/16 -f 10/24/17 11/25/19 25/40/20 24/39/18 -f 11/25/19 12/26/21 26/41/22 25/40/20 -f 12/26/21 13/27/23 27/42/24 26/41/22 -f 13/27/23 14/28/25 28/43/26 27/42/24 -f 14/28/25 1/29/27 15/44/28 28/43/26 -f 20/35/12 21/36/11 35/51/29 34/50/30 -f 21/36/11 22/37/14 36/52/31 35/51/29 -f 22/37/14 23/38/16 37/53/32 36/52/31 -f 23/38/16 24/39/18 38/54/33 37/53/32 -f 24/39/18 25/40/20 39/55/34 38/54/33 -f 25/40/20 26/41/22 40/56/35 39/55/34 -f 26/41/22 27/42/24 41/57/36 40/56/35 -f 27/42/24 28/43/26 42/58/37 41/57/36 -f 35/51/29 36/52/31 50/67/38 49/66/39 -f 36/52/31 37/53/32 51/68/40 50/67/38 -f 37/53/32 38/54/33 52/69/41 51/68/40 -f 38/54/33 39/55/34 53/70/42 52/69/41 -f 39/55/34 40/56/35 54/71/43 53/70/42 -f 40/56/35 41/57/36 55/72/44 54/71/43 -s off -f 97/105/45 85/93/46 94/102/47 93/101/48 -f 95/103/49 86/94/50 99/107/51 98/106/52 -f 100/108/53 89/97/54 103/111/55 102/110/56 -s 1 -f 49/66/39 50/67/38 64/164/57 63/160/58 -f 50/67/38 51/68/40 65/139/59 64/164/57 -f 51/68/40 52/69/41 66/141/60 65/139/59 -f 52/69/41 53/70/42 67/143/61 66/141/60 -f 53/70/42 54/71/43 68/145/62 67/143/61 -f 54/71/43 55/72/44 69/148/63 68/145/62 -f 65/139/59 66/141/60 135/174/64 133/170/65 -f 66/141/60 67/143/61 137/177/66 135/174/64 -f 67/143/61 68/145/62 139/180/67 137/177/66 -f 68/145/62 69/148/63 141/183/68 139/180/67 -f 2/2/69 1/1/27 71/78/70 -f 3/3/71 2/2/69 71/78/70 -f 5/5/72 4/4/73 71/78/70 -f 6/6/9 5/5/72 71/78/70 -f 7/7/10 6/6/9 71/78/70 -f 8/8/13 7/7/10 71/78/70 -f 9/9/15 8/8/13 71/78/70 -f 10/10/17 9/9/15 71/78/70 -f 11/11/19 10/10/17 71/78/70 -f 12/12/21 11/11/19 71/78/70 -f 13/13/23 12/12/21 71/78/70 -f 14/14/25 13/13/23 71/78/70 -f 1/1/27 14/14/25 71/78/70 -f 1/15/27 2/16/69 78/86/74 77/85/75 -s off -f 2/16/76 16/31/77 79/87/78 78/86/79 -f 16/31/80 15/30/81 80/88/82 79/87/83 -s 1 -f 15/30/28 1/15/27 77/85/84 80/88/85 -f 5/19/72 6/20/9 82/90/86 81/89/87 -f 6/20/9 20/35/12 83/91/88 82/90/89 -f 20/35/12 19/34/90 84/92/91 83/91/92 -s off -f 19/34/93 5/19/94 81/89/95 84/92/96 -f 94/102/97 86/94/98 95/103/99 93/101/100 -f 95/103/101 87/95/102 96/104/103 93/101/104 -f 96/104/105 88/96/106 97/105/107 93/101/108 -f 99/107/109 89/97/110 100/108/111 98/106/112 -f 100/108/113 90/98/114 101/109/115 98/106/116 -f 101/109/117 87/95/118 95/103/119 98/106/120 -f 103/111/121 91/99/122 104/112/123 102/110/124 -f 104/112/125 92/100/126 105/113/127 102/110/128 -f 105/113/129 90/98/130 100/108/131 102/110/132 -f 121/127/133 90/98/134 105/113/135 128/134/136 -f 105/113/137 92/100/138 127/133/139 128/134/140 -s 1 -f 48/65/141 34/50/30 35/51/29 49/66/39 -s off -f 125/131/142 127/133/143 92/100/144 104/112/145 -f 128/134/146 129/150/147 60/167/148 121/127/149 -s 1 -f 62/161/150 61/77/151 126/132/152 48/65/141 -f 63/160/58 62/161/150 48/65/141 49/66/39 -f 148/194/153 146/213/154 61/77/151 62/161/150 -s off -f 128/134/155 127/133/156 61/77/157 129/150/158 -f 126/132/159 61/77/160 127/133/161 125/131/162 -s 1 -f 159/207/163 157/197/164 63/160/58 64/164/57 -f 133/170/65 159/207/163 64/164/57 65/139/59 -s off -f 119/126/165 101/109/166 90/98/167 121/127/168 -f 121/127/169 60/167/170 120/168/171 119/126/172 -s 1 -f 63/160/58 157/197/164 148/194/153 62/161/150 -f 129/150/173 145/190/174 161/209/175 60/167/176 -f 150/214/177 153/200/178 72/166/179 -f 153/200/178 155/186/180 72/166/179 -f 156/162/181 158/163/182 72/166/179 -f 158/163/182 132/140/183 72/166/179 -f 132/140/183 134/142/184 72/166/179 -f 134/142/184 136/144/185 72/166/179 -f 136/144/185 138/146/186 72/166/179 -f 138/146/186 140/185/187 72/166/179 -f 140/185/187 143/203/188 72/166/179 -f 143/203/188 150/214/177 72/166/179 -s off -f 110/118/189 113/120/190 59/159/191 111/137/192 -f 96/104/193 87/95/194 113/120/195 110/118/196 -f 120/168/197 59/159/198 113/120/199 119/126/200 -f 119/126/201 113/120/202 87/95/203 101/109/204 -s 1 -f 163/205/205 154/158/206 59/159/207 120/168/208 -f 155/186/180 162/169/209 72/166/179 -f 160/165/210 144/151/211 72/166/179 -f 144/151/211 147/152/212 72/166/179 -f 147/152/212 156/162/181 72/166/179 -f 154/158/206 152/138/213 111/137/214 59/159/207 -f 161/209/175 163/205/205 120/168/208 60/167/176 -f 72/166/179 162/169/209 160/165/210 -f 55/72/44 41/57/36 42/58/37 56/73/215 -f 69/148/63 55/72/44 56/73/215 70/149/216 -f 142/147/217 141/183/68 69/148/63 70/149/216 -s off -f 112/119/218 58/76/219 115/122/220 114/121/221 -f 114/121/222 97/105/223 88/96/224 112/119/225 -s 1 -f 151/155/226 149/156/227 57/75/228 58/76/229 -f 111/137/214 152/138/213 151/155/226 58/76/229 -f 149/153/227 142/147/217 70/149/216 57/154/228 -s off -f 110/118/230 111/137/231 58/76/232 112/119/233 -f 112/119/234 88/96/235 96/104/236 110/118/237 -s 1 -f 29/45/238 15/30/28 16/31/239 30/46/240 -f 42/58/37 28/43/26 15/44/28 29/59/238 -f 30/46/240 107/115/241 44/61/242 -s off -f 106/114/243 109/117/244 44/61/245 107/115/246 -f 108/116/247 86/94/248 94/102/249 106/114/250 -f 94/102/251 85/93/252 109/117/253 106/114/254 -s 1 -f 44/61/242 43/60/255 29/45/238 30/46/240 -f 43/74/255 56/73/215 42/58/37 29/59/238 -f 115/122/256 58/76/229 57/75/228 43/60/255 -f 57/154/228 70/149/216 56/73/215 43/74/255 -f 115/122/256 44/61/242 109/117/257 114/121/258 -s off -f 114/121/259 109/117/260 85/93/261 97/105/262 -s 1 -f 115/122/256 43/60/255 44/61/242 -f 33/49/263 19/34/90 20/35/12 34/50/30 -f 123/129/264 33/49/263 47/64/265 -f 48/65/141 47/64/265 33/49/263 34/50/30 -f 124/130/266 47/64/265 126/132/152 125/131/267 -s off -f 122/128/268 123/129/269 47/64/270 124/130/271 -f 124/130/272 91/99/273 103/111/274 122/128/275 -f 125/131/276 104/112/277 91/99/278 124/130/279 -s 1 -f 48/65/141 126/132/152 47/64/265 -s off -f 16/31/280 2/16/281 3/17/282 17/32/283 -f 73/81/284 74/79/285 75/80/286 -f 18/33/287 4/18/288 5/19/289 19/34/290 -f 74/84/291 73/82/292 76/83/293 -f 4/18/294 18/33/295 75/80/296 74/79/297 -f 130/135/298 75/80/299 18/33/300 -f 75/80/301 17/32/302 3/17/303 73/81/304 -f 3/3/305 71/78/306 76/83/307 73/82/308 -f 76/83/309 71/78/310 4/4/311 74/84/312 -f 108/116/313 45/62/314 117/124/315 116/123/316 -f 116/123/317 118/125/318 89/97/319 99/107/320 -f 116/123/321 99/107/322 86/94/323 108/116/324 -s 1 -f 31/47/325 30/46/240 16/31/239 17/32/326 -s off -f 106/114/327 107/115/328 45/62/329 108/116/330 -s 1 -f 107/115/241 30/46/240 31/47/325 45/62/331 -f 131/136/332 130/135/333 18/33/334 32/48/335 -f 33/49/263 32/48/335 18/33/334 19/34/90 -f 32/48/335 46/63/336 117/124/337 131/136/332 -s off -f 122/128/338 118/125/339 46/63/340 123/129/341 -f 117/124/342 46/63/343 118/125/344 116/123/345 -f 103/111/346 89/97/347 118/125/348 122/128/349 -s 1 -f 32/48/335 33/49/263 123/129/264 46/63/336 -f 131/136/332 117/124/337 45/62/331 31/47/325 -f 130/135/333 131/136/332 31/47/325 17/32/326 -s off -f 75/80/350 130/135/351 17/32/352 -s 1 -f 146/213/154 145/190/174 129/150/173 61/77/151 -f 133/170/65 132/171/183 158/172/182 159/207/163 -f 132/173/183 133/170/65 135/174/64 134/175/184 -f 134/176/184 135/174/64 137/177/66 136/178/185 -f 136/179/185 137/177/66 139/180/67 138/181/186 -f 138/182/186 139/180/67 141/183/68 140/184/187 -f 140/202/187 141/183/68 142/147/217 143/188/188 -f 143/216/188 142/147/217 149/153/227 150/199/177 -f 145/190/174 144/191/211 160/192/210 161/209/175 -f 144/193/211 146/213/154 148/194/153 147/195/212 -f 147/196/212 148/194/153 157/197/164 156/198/181 -f 150/189/177 149/156/227 151/155/226 153/215/178 -f 153/187/178 152/138/213 154/158/206 155/157/180 -f 155/204/180 154/158/206 163/205/205 162/211/209 -f 156/206/181 157/197/164 159/207/163 158/208/182 -f 161/209/175 160/210/210 162/211/209 163/205/205 -f 144/212/211 145/190/174 146/213/154 -f 151/155/226 152/138/213 153/201/178 -v -4.526886 2.025292 -6.500000 -v -4.526886 2.025292 6.500000 -v -2.453123 1.990687 -6.229743 -v -2.453123 1.990687 6.229743 -v -4.716847 1.835833 -6.500000 -v -4.716847 1.835833 6.500000 -v -2.453123 1.835833 6.229743 -v -2.453123 1.835833 -6.229743 -v -4.526886 2.025292 5.055555 -v -2.453123 1.835833 5.055555 -v -4.853122 1.835833 5.055555 -v -4.526886 2.025292 3.611111 -v -2.453123 1.990687 3.611111 -v -2.453123 1.835833 3.611111 -v -4.853122 1.835833 3.611111 -v -4.526886 2.025292 2.166667 -v -2.453123 1.835833 2.166667 -v -4.853123 1.835833 2.166667 -v -4.526886 2.025292 0.722222 -v -2.453123 1.990687 0.722222 -v -2.453123 1.835833 0.722222 -v -4.853123 1.835833 0.722222 -v -4.526886 2.025292 -0.722222 -v -2.453123 1.990687 -0.722222 -v -2.453123 1.835833 -0.722222 -v -4.853123 1.835833 -0.722222 -v -4.526886 2.025292 -2.166667 -v -2.453123 1.835833 -2.166667 -v -4.853123 1.835833 -2.166667 -v -4.526886 2.025292 -3.611112 -v -2.453123 1.990687 -3.611112 -v -2.453123 1.835833 -3.611112 -v -4.853123 1.835833 -3.611112 -v -4.526886 2.025292 -5.055555 -v -2.453123 1.835833 -5.055556 -v -4.853123 1.835833 -5.055556 -vt 0.616150 0.306151 -vt 0.610251 0.992489 -vt 0.731520 0.325838 -vt 0.725886 0.974777 -vt 0.591047 0.313683 -vt 0.585284 0.984520 -vt 0.476020 0.976054 -vt 0.481594 0.320254 -vt 0.605471 0.315123 -vt 0.599736 0.983336 -vt 0.717845 0.974434 -vt 0.723467 0.326044 -vt 0.579649 0.910291 -vt 0.724217 0.318026 -vt 0.720447 0.913504 -vt 0.472481 0.914051 -vt 0.598060 0.909419 -vt 0.578999 0.836511 -vt 0.718456 0.982458 -vt 0.730267 0.838710 -vt 0.471391 0.837979 -vt 0.722220 0.838546 -vt 0.598433 0.836444 -vt 0.579018 0.761838 -vt 0.602520 0.389018 -vt 0.723365 0.763360 -vt 0.470415 0.761959 -vt 0.598696 0.761928 -vt 0.579544 0.686680 -vt 0.476998 0.382224 -vt 0.732302 0.688095 -vt 0.471265 0.685937 -vt 0.724215 0.688011 -vt 0.599234 0.686836 -vt 0.580196 0.611444 -vt 0.725022 0.387043 -vt 0.732967 0.612676 -vt 0.471912 0.610366 -vt 0.724881 0.612612 -vt 0.599876 0.611634 -vt 0.580951 0.536288 -vt 0.584126 0.387830 -vt 0.725344 0.537251 -vt 0.472346 0.534318 -vt 0.600626 0.536533 -vt 0.582223 0.461596 -vt 0.601648 0.461993 -vt 0.733547 0.462028 -vt 0.474637 0.458282 -vt 0.725502 0.462044 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.050020 0.997007 0.058958 -vn 0.050020 0.997007 0.058958 -vn 0.050020 0.997007 0.058958 -vn 0.050020 0.997007 0.058958 -vn -0.591510 0.805815 -0.027903 -vn -0.591510 0.805815 -0.027903 -vn -0.591510 0.805815 -0.027903 -vn -0.591510 0.805815 -0.027903 -vn 0.122841 -0.067773 0.990110 -vn 0.122841 -0.067773 0.990110 -vn 0.122841 -0.067773 0.990110 -vn 0.122841 -0.067773 0.990110 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.122841 -0.067773 -0.990110 -vn 0.122841 -0.067773 -0.990110 -vn 0.122841 -0.067773 -0.990110 -vn 0.122841 -0.067773 -0.990110 -vn 0.050020 0.997006 -0.058958 -vn 0.050020 0.997007 -0.058958 -vn 0.050020 0.997007 -0.058958 -vn 0.050020 0.997007 -0.058958 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -0.591512 0.805814 0.027903 -vn -0.591512 0.805814 0.027903 -vn -0.591511 0.805814 0.027903 -vn -0.591512 0.805814 0.027903 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502197 0.864753 0.000000 -vn -0.502197 0.864753 0.000000 -vn -0.502197 0.864753 0.000000 -vn -0.502197 0.864753 0.000000 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn 0.016684 0.999861 0.000000 -vn 0.016684 0.999861 0.000000 -vn 0.016684 0.999861 0.000000 -vn 0.016684 0.999861 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -s off -f 168/225/353 171/228/354 198/252/355 199/241/356 -f 164/221/357 197/258/358 198/246/359 166/224/360 -f 164/221/361 168/225/362 199/241/363 197/258/364 -f 165/218/365 169/226/366 170/227/367 167/235/368 -f 198/252/369 171/228/370 166/219/371 -f 166/230/372 171/228/373 168/225/374 164/217/375 -f 172/229/376 165/222/377 167/223/378 173/232/379 -f 167/220/380 170/227/381 173/231/382 -f 174/233/383 173/231/384 170/227/385 169/226/386 -f 172/229/387 174/233/388 169/226/389 165/222/390 -f 175/234/391 172/229/392 173/232/393 176/237/394 -f 173/231/395 177/238/396 176/236/397 -f 178/239/398 177/238/399 173/231/400 174/233/401 -f 175/234/402 178/239/403 174/233/404 172/229/405 -f 179/240/406 175/234/407 176/237/408 180/243/409 -f 176/236/410 177/238/411 180/242/412 -f 181/244/413 180/242/414 177/238/415 178/239/416 -f 179/240/417 181/244/418 178/239/419 175/234/420 -f 182/245/421 179/240/422 180/243/423 183/248/424 -f 180/242/425 184/249/426 183/247/427 -f 185/250/428 184/249/429 180/242/430 181/244/431 -f 182/245/432 185/250/433 181/244/434 179/240/435 -f 186/251/436 182/245/437 183/248/438 187/254/439 -f 183/247/440 184/249/441 188/255/442 187/253/443 -f 189/256/444 188/255/445 184/249/446 185/250/447 -f 186/251/448 189/256/449 185/250/450 182/245/451 -f 190/257/452 186/251/453 187/254/454 191/260/455 -f 187/253/456 188/255/457 191/259/458 -f 192/261/459 191/259/460 188/255/461 189/256/462 -f 190/257/463 192/261/464 189/256/465 186/251/466 -f 193/262/467 190/257/468 191/260/469 194/265/470 -f 191/259/471 195/266/472 194/264/473 -f 196/263/474 195/266/475 191/259/476 192/261/477 -f 193/262/478 196/263/479 192/261/480 190/257/481 -f 197/258/482 193/262/483 194/265/484 198/246/485 -f 194/264/486 195/266/487 198/252/488 -f 199/241/489 198/252/490 195/266/491 196/263/492 -f 197/258/493 199/241/494 196/263/495 193/262/496 -v -3.559415 -0.491252 -6.500000 -v -3.559415 -0.491252 6.500000 -v -1.485652 -0.525856 -6.229743 -v -1.485653 -0.525856 6.229743 -v -3.749376 -0.680711 -6.500000 -v -3.749376 -0.680711 6.500000 -v -1.485653 -0.680711 6.229743 -v -1.485652 -0.680711 -6.229743 -v -3.559415 -0.491252 5.055555 -v -1.485652 -0.680711 5.055555 -v -3.885653 -0.680711 5.055555 -v -3.559415 -0.491252 3.611110 -v -1.485652 -0.525856 3.611110 -v -1.485652 -0.680711 3.611110 -v -3.885652 -0.680711 3.611110 -v -3.559415 -0.491252 2.166667 -v -1.485652 -0.680711 2.166667 -v -3.885653 -0.680711 2.166667 -v -3.559415 -0.491252 0.722222 -v -1.485652 -0.525856 0.722222 -v -1.485652 -0.680711 0.722222 -v -3.885652 -0.680711 0.722222 -v -3.559416 -0.491252 -0.722223 -v -1.485652 -0.525856 -0.722222 -v -1.485652 -0.680711 -0.722222 -v -3.885653 -0.680711 -0.722223 -v -3.559416 -0.491252 -2.166667 -v -1.485652 -0.680711 -2.166667 -v -3.885653 -0.680711 -2.166667 -v -3.559415 -0.491252 -3.611112 -v -1.485652 -0.525856 -3.611111 -v -1.485652 -0.680711 -3.611111 -v -3.885653 -0.680711 -3.611111 -v -3.559415 -0.491252 -5.055556 -v -1.485652 -0.680711 -5.055556 -v -3.885652 -0.680711 -5.055556 -vt 0.878803 0.306151 -vt 0.872904 0.992489 -vt 0.994173 0.325838 -vt 0.988539 0.974777 -vt 0.853700 0.313683 -vt 0.847937 0.984520 -vt 0.738673 0.976054 -vt 0.744247 0.320254 -vt 0.868124 0.315123 -vt 0.862389 0.983336 -vt 0.980498 0.974434 -vt 0.986120 0.326044 -vt 0.842302 0.910291 -vt 0.986870 0.318026 -vt 0.983099 0.913504 -vt 0.735134 0.914051 -vt 0.860713 0.909419 -vt 0.841652 0.836511 -vt 0.981109 0.982458 -vt 0.992920 0.838710 -vt 0.734044 0.837979 -vt 0.984873 0.838546 -vt 0.861086 0.836444 -vt 0.841671 0.761838 -vt 0.865172 0.389018 -vt 0.986018 0.763360 -vt 0.733068 0.761959 -vt 0.861349 0.761928 -vt 0.842197 0.686680 -vt 0.739650 0.382224 -vt 0.994955 0.688095 -vt 0.733917 0.685937 -vt 0.986868 0.688011 -vt 0.861887 0.686836 -vt 0.842849 0.611444 -vt 0.987675 0.387043 -vt 0.995620 0.612676 -vt 0.734565 0.610366 -vt 0.987534 0.612612 -vt 0.862529 0.611634 -vt 0.843604 0.536288 -vt 0.846779 0.387830 -vt 0.987996 0.537251 -vt 0.734999 0.534318 -vt 0.863279 0.536533 -vt 0.844876 0.461596 -vt 0.864301 0.461993 -vt 0.996200 0.462028 -vt 0.737290 0.458282 -vt 0.988155 0.462044 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.050020 0.997007 0.058959 -vn 0.050020 0.997007 0.058959 -vn 0.050020 0.997006 0.058959 -vn 0.050020 0.997007 0.058959 -vn -0.591510 0.805815 -0.027903 -vn -0.591510 0.805815 -0.027903 -vn -0.591510 0.805815 -0.027903 -vn -0.591510 0.805815 -0.027903 -vn 0.122841 -0.067773 0.990110 -vn 0.122841 -0.067773 0.990110 -vn 0.122841 -0.067773 0.990110 -vn 0.122841 -0.067773 0.990110 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 0.122841 -0.067772 -0.990110 -vn 0.122841 -0.067772 -0.990110 -vn 0.122841 -0.067772 -0.990110 -vn 0.122841 -0.067772 -0.990110 -vn 0.050020 0.997007 -0.058959 -vn 0.050020 0.997007 -0.058959 -vn 0.050020 0.997007 -0.058959 -vn 0.050020 0.997007 -0.058959 -vn 1.000000 0.000000 0.000001 -vn 1.000000 0.000000 0.000001 -vn 1.000000 0.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.591510 0.805815 0.027903 -vn -0.591510 0.805815 0.027903 -vn -0.591510 0.805815 0.027903 -vn -0.591510 0.805815 0.027903 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -0.502195 0.864754 -0.000000 -vn -0.502195 0.864754 -0.000000 -vn -0.502195 0.864754 -0.000000 -vn -0.502195 0.864754 -0.000000 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn 0.016684 0.999861 0.000000 -vn 0.016684 0.999861 0.000000 -vn 0.016684 0.999861 0.000000 -vn 0.016684 0.999861 0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn -0.502196 0.864754 0.000000 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 0.053867 0.997117 0.053449 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 0.053867 0.997117 -0.053449 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -vn -0.502196 0.864754 -0.000000 -s off -f 204/275/497 207/278/498 234/302/499 235/291/500 -f 200/271/501 233/308/502 234/296/503 202/274/504 -f 200/271/505 204/275/506 235/291/507 233/308/508 -f 201/268/509 205/276/510 206/277/511 203/285/512 -f 234/302/513 207/278/514 202/269/515 -f 202/280/516 207/278/517 204/275/518 200/267/519 -f 208/279/520 201/272/521 203/273/522 209/282/523 -f 203/270/524 206/277/525 209/281/526 -f 210/283/527 209/281/528 206/277/529 205/276/530 -f 208/279/531 210/283/532 205/276/533 201/272/534 -f 211/284/535 208/279/536 209/282/537 212/287/538 -f 209/281/539 213/288/540 212/286/541 -f 214/289/542 213/288/543 209/281/544 210/283/545 -f 211/284/546 214/289/547 210/283/548 208/279/549 -f 215/290/550 211/284/551 212/287/552 216/293/553 -f 212/286/554 213/288/555 216/292/556 -f 217/294/557 216/292/558 213/288/559 214/289/560 -f 215/290/561 217/294/562 214/289/563 211/284/564 -f 218/295/565 215/290/566 216/293/567 219/298/568 -f 216/292/569 220/299/570 219/297/571 -f 221/300/572 220/299/573 216/292/574 217/294/575 -f 218/295/576 221/300/577 217/294/578 215/290/579 -f 222/301/580 218/295/581 219/298/582 223/304/583 -f 219/297/584 220/299/585 224/305/586 223/303/587 -f 225/306/588 224/305/589 220/299/590 221/300/591 -f 222/301/592 225/306/593 221/300/594 218/295/595 -f 226/307/596 222/301/597 223/304/598 227/310/599 -f 223/303/600 224/305/601 227/309/602 -f 228/311/603 227/309/604 224/305/605 225/306/606 -f 226/307/607 228/311/608 225/306/609 222/301/610 -f 229/312/611 226/307/612 227/310/613 230/315/614 -f 227/309/615 231/316/616 230/314/617 -f 232/313/618 231/316/619 227/309/620 228/311/621 -f 229/312/622 232/313/623 228/311/624 226/307/625 -f 233/308/626 229/312/627 230/315/628 234/296/629 -f 230/314/630 231/316/631 234/302/632 -f 235/291/633 234/302/634 231/316/635 232/313/636 -f 233/308/637 235/291/638 232/313/639 229/312/640 -v -4.142218 0.492005 -0.689421 -v -4.278798 0.483220 -0.711072 -v -4.229631 0.565988 -0.611412 -v -4.039907 1.892682 -1.903144 -v -4.176487 1.883898 -1.924795 -v -4.127320 1.966665 -1.825134 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn 0.159359 -0.653124 -0.740293 -vn 0.159359 -0.653124 -0.740293 -vn 0.159359 -0.653124 -0.740293 -vn 0.159359 -0.653124 -0.740293 -vn -0.933302 0.271664 0.234831 -vn -0.933302 0.271664 0.234831 -vn -0.933302 0.271664 0.234831 -vn -0.933302 0.271664 0.234831 -vn 0.773945 0.381464 0.505464 -vn 0.773945 0.381464 0.505464 -vn 0.773945 0.381464 0.505464 -vn 0.773945 0.381464 0.505464 -s off -f 236/317/641 237/318/642 240/322/643 239/321/644 -f 237/318/645 238/319/646 241/323/647 240/322/648 -f 238/319/649 236/320/650 239/324/651 241/323/652 -v -3.239272 0.526544 -0.759048 -v -3.375609 0.514178 -0.780479 -v -3.327950 0.606955 -0.689259 -v -3.143238 1.854496 -2.131890 -v -3.279576 1.842130 -2.153321 -v -3.231915 1.934906 -2.062101 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn 0.171460 -0.714084 -0.678738 -vn 0.171460 -0.714084 -0.678738 -vn 0.171460 -0.714084 -0.678738 -vn 0.171460 -0.714084 -0.678738 -vn -0.937813 0.279982 0.205223 -vn -0.937813 0.279982 0.205223 -vn -0.937813 0.279982 0.205223 -vn -0.937813 0.279982 0.205223 -vn 0.766343 0.434134 0.473546 -vn 0.766343 0.434134 0.473546 -vn 0.766343 0.434134 0.473546 -vn 0.766343 0.434134 0.473546 -s off -f 242/325/653 243/326/654 246/330/655 245/329/656 -f 243/326/657 244/327/658 247/331/659 246/330/660 -f 244/327/661 242/328/662 245/332/663 247/331/664 -v -3.163166 -0.512404 -4.366673 -v -3.288760 -0.570938 -4.366673 -v -3.225963 -0.541671 -4.246673 -v -4.291037 1.907626 -4.366673 -v -4.416630 1.849092 -4.366673 -v -4.353833 1.878359 -4.246673 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn -0.784961 -0.365836 0.500000 -vn -0.784961 -0.365836 0.500000 -vn -0.784961 -0.365836 0.500000 -vn -0.784961 -0.365836 0.500000 -vn 0.784961 0.365837 0.500000 -vn 0.784961 0.365837 0.500000 -vn 0.784961 0.365837 0.500000 -vn 0.784961 0.365837 0.500000 -s off -f 248/333/665 249/334/666 252/338/667 251/337/668 -f 249/334/669 250/335/670 253/339/671 252/338/672 -f 250/335/673 248/336/674 251/340/675 253/339/676 -v -2.090913 -0.552991 -4.366673 -v -2.216506 -0.611525 -4.366673 -v -2.153710 -0.582258 -4.246673 -v -3.269892 1.976702 -4.366673 -v -3.395485 1.918168 -4.366673 -v -3.332688 1.947435 -4.246673 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn -0.000005 0.000000 -1.000000 -vn -0.000005 0.000000 -1.000000 -vn -0.000005 0.000000 -1.000000 -vn -0.000005 0.000000 -1.000000 -vn -0.784960 -0.365836 0.500001 -vn -0.784960 -0.365836 0.500001 -vn -0.784960 -0.365836 0.500001 -vn -0.784960 -0.365836 0.500001 -vn 0.784962 0.365835 0.499999 -vn 0.784962 0.365835 0.499999 -vn 0.784962 0.365835 0.499999 -vn 0.784962 0.365835 0.499999 -s off -f 254/341/677 255/342/678 258/346/679 257/345/680 -f 255/342/681 256/343/682 259/347/683 258/346/684 -f 256/343/685 254/344/686 257/348/687 259/347/688 -v -4.142218 0.492005 0.689421 -v -4.278798 0.483220 0.711072 -v -4.229631 0.565988 0.611412 -v -4.039907 1.892682 1.903144 -v -4.176487 1.883898 1.924795 -v -4.127320 1.966665 1.825134 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn -0.159359 0.653124 -0.740293 -vn -0.159359 0.653124 -0.740293 -vn -0.159359 0.653124 -0.740293 -vn -0.159359 0.653124 -0.740293 -vn 0.933302 -0.271664 0.234831 -vn 0.933302 -0.271664 0.234831 -vn 0.933302 -0.271664 0.234831 -vn 0.933302 -0.271664 0.234831 -vn -0.773945 -0.381464 0.505464 -vn -0.773945 -0.381464 0.505464 -vn -0.773945 -0.381464 0.505464 -vn -0.773945 -0.381464 0.505464 -s off -f 260/349/689 261/350/690 264/354/691 263/353/692 -f 261/350/693 262/351/694 265/355/695 264/354/696 -f 262/351/697 260/352/698 263/356/699 265/355/700 -v -3.239272 0.526544 0.759048 -v -3.375609 0.514178 0.780479 -v -3.327950 0.606955 0.689259 -v -3.143239 1.854496 2.131890 -v -3.279576 1.842130 2.153321 -v -3.231915 1.934906 2.062101 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn -0.171462 0.714082 -0.678739 -vn -0.171462 0.714082 -0.678739 -vn -0.171462 0.714082 -0.678739 -vn -0.171462 0.714082 -0.678739 -vn 0.937813 -0.279982 0.205223 -vn 0.937813 -0.279982 0.205223 -vn 0.937813 -0.279982 0.205223 -vn 0.937813 -0.279982 0.205223 -vn -0.766344 -0.434134 0.473546 -vn -0.766344 -0.434133 0.473546 -vn -0.766344 -0.434134 0.473546 -vn -0.766344 -0.434133 0.473546 -s off -f 266/357/701 267/358/702 270/362/703 269/361/704 -f 267/358/705 268/359/706 271/363/707 270/362/708 -f 268/359/709 266/360/710 269/364/711 271/363/712 -v -3.163167 -0.512404 4.366673 -v -3.288760 -0.570938 4.366673 -v -3.225963 -0.541671 4.246673 -v -4.291037 1.907626 4.366672 -v -4.416630 1.849092 4.366673 -v -4.353833 1.878359 4.246673 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.784961 0.365836 0.500000 -vn 0.784961 0.365836 0.500000 -vn 0.784961 0.365836 0.500000 -vn 0.784961 0.365836 0.500000 -vn -0.784963 -0.365836 0.499998 -vn -0.784963 -0.365836 0.499998 -vn -0.784963 -0.365836 0.499998 -vn -0.784963 -0.365836 0.499998 -s off -f 272/365/713 273/366/714 276/370/715 275/369/716 -f 273/366/717 274/367/718 277/371/719 276/370/720 -f 274/367/721 272/368/722 275/372/723 277/371/724 -v -2.090913 -0.552991 4.366673 -v -2.216506 -0.611525 4.366673 -v -2.153710 -0.582258 4.246673 -v -3.269892 1.976702 4.366673 -v -3.395485 1.918168 4.366673 -v -3.332688 1.947435 4.246673 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn 0.000005 0.000000 -1.000000 -vn 0.000005 0.000000 -1.000000 -vn 0.000005 0.000000 -1.000000 -vn 0.000005 0.000000 -1.000000 -vn 0.784961 0.365837 0.499999 -vn 0.784961 0.365837 0.499999 -vn 0.784961 0.365837 0.499999 -vn 0.784961 0.365837 0.499999 -vn -0.784962 -0.365835 0.500000 -vn -0.784962 -0.365835 0.500000 -vn -0.784962 -0.365835 0.500000 -vn -0.784962 -0.365835 0.500000 -s off -f 278/373/725 279/374/726 282/378/727 281/377/728 -f 279/374/729 280/375/730 283/379/731 282/378/732 -f 280/375/733 278/376/734 281/380/735 283/379/736 -v -5.517155 0.803553 -1.563271 -v -5.487778 -0.252819 -0.145963 -v -5.274500 -0.974333 1.464671 -v -5.274499 0.952056 -1.477533 -v -5.487779 0.252819 0.145963 -v -5.517155 -0.781276 1.576133 -v -5.303876 0.252819 0.145963 -v -5.303876 -0.252819 -0.145963 -v -5.502548 0.333527 -0.821039 -v -5.374407 0.570041 -0.684488 -v -5.289107 0.544277 -0.699363 -v -5.417247 0.307763 -0.835914 -v -5.374407 -0.585636 0.675485 -v -5.502548 -0.320803 0.828386 -v -5.417247 -0.292169 0.844918 -v -5.289107 -0.557001 0.692017 -vt 0.751894 0.271249 -vt 0.688242 0.270269 -vt 0.624590 0.269288 -vt 0.742593 0.186217 -vt 0.689223 0.206617 -vt 0.636506 0.184582 -vt 0.690203 0.142965 -vt 0.723500 0.047977 -vt 0.691184 0.079313 -vt 0.659848 0.046996 -vt 0.692165 0.015661 -vt 0.715908 0.196417 -vt 0.720068 0.270759 -vt 0.716398 0.164591 -vt 0.707342 0.063645 -vt 0.707832 0.031819 -vt 0.662864 0.195599 -vt 0.656416 0.269778 -vt 0.663355 0.163773 -vt 0.675516 0.063154 -vt 0.676006 0.031328 -vn -0.990061 0.139469 -0.018114 -vn -0.822500 0.528726 0.209628 -vn 0.317694 0.344286 -0.883481 -vn -0.317702 0.592979 -0.739893 -vn 0.822500 -0.445906 -0.353075 -vn 0.990061 -0.054049 -0.129840 -vn -0.948960 0.273223 0.157558 -vn -0.948215 -0.273253 -0.161933 -vn -0.991413 -0.129753 0.016270 -vn -0.842918 -0.500011 -0.198694 -vn 0.260994 -0.414547 0.871799 -vn -0.260998 -0.547769 0.794877 -vn 0.948215 0.276863 0.155677 -vn 0.842917 0.422079 0.333676 -vn 0.948960 -0.273060 -0.157838 -vn 0.991413 0.050787 0.120506 -s 1 -f 292/393/737 293/392/738 287/384/739 284/381/740 -f 295/395/741 292/396/737 284/388/740 -f 294/394/742 295/395/741 284/388/740 287/384/739 -f 293/392/738 294/394/742 287/384/739 -f 288/385/743 293/392/738 292/393/737 285/382/744 -f 297/397/745 296/398/746 286/383/747 289/386/748 -f 290/387/749 294/394/742 293/392/738 288/385/743 -f 298/399/750 297/397/745 289/386/748 -f 291/389/751 295/395/741 294/394/742 290/387/749 -f 299/400/752 298/399/750 289/386/748 286/390/747 -f 285/391/744 292/396/737 295/395/741 291/389/751 -f 296/401/746 299/400/752 286/390/747 -f 296/398/746 297/397/745 288/385/743 285/382/744 -f 299/400/752 296/401/746 285/391/744 291/389/751 -f 298/399/750 299/400/752 291/389/751 290/387/749 -f 297/397/745 298/399/750 290/387/749 288/385/743 -v -4.728155 0.086603 0.050000 -v -4.728154 0.086603 -0.050000 -v -4.728155 0.000000 -0.100000 -v -4.728154 -0.086603 -0.050000 -v -4.728155 -0.086603 0.050000 -v -4.728154 0.000000 0.100000 -v -5.628155 0.086603 0.050000 -v -5.628154 0.086603 -0.050000 -v -5.628155 0.000000 -0.100000 -v -5.628154 -0.086603 -0.050000 -v -5.628155 -0.086603 0.050000 -v -5.628154 0.000000 0.100000 -v -5.628154 0.000000 -0.000000 -vt 0.988488 0.024988 -vt 0.988520 0.041334 -vt 0.988552 0.057679 -vt 0.988584 0.074025 -vt 0.988616 0.090371 -vt 0.988648 0.106717 -vt 0.988680 0.123062 -vt 0.841008 0.025277 -vt 0.841040 0.041623 -vt 0.841072 0.057968 -vt 0.841104 0.074314 -vt 0.841136 0.090659 -vt 0.841168 0.107005 -vt 0.841200 0.123351 -vt 0.830926 0.091661 -vt 0.830824 0.039274 -vt 0.785404 0.013169 -vt 0.740087 0.039452 -vt 0.740190 0.091839 -vt 0.785609 0.117943 -vt 0.787602 0.065552 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn -0.000000 0.499997 -0.866027 -vn -0.000000 0.499997 -0.866027 -vn -0.000000 0.499997 -0.866027 -vn -0.000000 0.499997 -0.866027 -vn 0.000000 -0.499999 -0.866026 -vn 0.000000 -0.499999 -0.866026 -vn 0.000000 -0.499999 -0.866026 -vn 0.000000 -0.499999 -0.866026 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -0.499997 0.866027 -vn 0.000000 -0.499997 0.866027 -vn 0.000000 -0.499997 0.866027 -vn 0.000000 -0.499997 0.866027 -vn 0.000000 0.499999 0.866026 -vn 0.000000 0.499999 0.866026 -vn 0.000000 0.499999 0.866026 -vn 0.000000 0.499999 0.866026 -vn -1.000000 -0.000007 -0.000005 -vn -1.000000 0.000003 -0.000002 -vn -1.000000 0.000001 -0.000002 -vn -1.000000 0.000003 0.000005 -vn -1.000000 0.000000 -0.000002 -vn -1.000000 0.000007 -0.000005 -vn -1.000000 0.000000 0.000000 -s off -f 300/402/753 301/403/754 307/410/755 306/409/756 -f 301/403/757 302/404/758 308/411/759 307/410/760 -f 302/404/761 303/405/762 309/412/763 308/411/764 -f 303/405/765 304/406/766 310/413/767 309/412/768 -f 304/406/769 305/407/770 311/414/771 310/413/772 -f 305/407/773 300/408/774 306/415/775 311/414/776 -s 1 -f 306/420/777 307/419/778 312/422/779 -f 307/419/778 308/418/780 312/422/779 -f 308/418/780 309/417/781 312/422/779 -f 309/417/781 310/416/782 312/422/779 -f 310/416/782 311/421/783 312/422/779 -f 311/421/783 306/420/777 312/422/779 -v -3.373292 -2.034549 -1.257066 -v -3.511857 -2.034549 -1.257066 -v -3.442574 -2.094549 -1.153143 -v -3.373292 -0.302498 -0.257066 -v -3.511857 -0.302498 -0.257066 -v -3.442574 -0.362498 -0.153143 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn 0.866025 0.250000 -0.433013 -vn -0.866027 0.250000 -0.433011 -vn -0.866026 0.250000 -0.433011 -vn 0.866025 0.250001 -0.433013 -vn -0.000000 -0.499999 0.866026 -vn -0.000000 -0.499999 0.866026 -s 1 -f 313/423/784 314/424/785 317/428/786 316/427/787 -f 314/424/785 315/425/788 318/429/789 317/428/786 -f 315/425/788 313/426/784 316/430/787 318/429/789 -v -3.250543 -1.665037 -1.076869 -v -3.141562 -1.815037 -1.076869 -v -3.141562 -2.000447 -1.076869 -v -3.250544 -2.150447 -1.076869 -v -3.426880 -2.207742 -1.076869 -v -3.603215 -2.150447 -1.076869 -v -3.712196 -2.000447 -1.076869 -v -3.712196 -1.815037 -1.076869 -v -3.603215 -1.665037 -1.076869 -v -3.426879 -1.607742 -1.076869 -v -3.250543 -1.665037 -1.376869 -v -3.141562 -1.815037 -1.376869 -v -3.141562 -2.000447 -1.376869 -v -3.250544 -2.150447 -1.376869 -v -3.426880 -2.207742 -1.376870 -v -3.603215 -2.150447 -1.376869 -v -3.712196 -2.000447 -1.376870 -v -3.712196 -1.815037 -1.376869 -v -3.603215 -1.665037 -1.376869 -v -3.426879 -1.607742 -1.376869 -v -3.426879 -1.907742 -1.076869 -v -3.426879 -1.907742 -1.271261 -vt 0.252891 0.122706 -vt 0.283344 0.107201 -vt 0.298868 0.076756 -vt 0.293532 0.043002 -vt 0.269375 0.018830 -vt 0.235623 0.013474 -vt 0.205170 0.028980 -vt 0.189646 0.059424 -vt 0.194982 0.093179 -vt 0.219140 0.117351 -vt 0.987153 0.141536 -vt 0.986865 0.156219 -vt 0.986578 0.170901 -vt 0.986290 0.185584 -vt 0.986003 0.200266 -vt 0.985715 0.214949 -vt 0.985428 0.229631 -vt 0.985140 0.244313 -vt 0.984853 0.258995 -vt 0.984565 0.273678 -vt 0.984278 0.288360 -vt 0.766365 0.137213 -vt 0.766077 0.151896 -vt 0.765790 0.166578 -vt 0.765503 0.181260 -vt 0.765215 0.195943 -vt 0.764927 0.210625 -vt 0.764640 0.225307 -vt 0.764352 0.239990 -vt 0.764065 0.254672 -vt 0.763777 0.269355 -vt 0.763490 0.284037 -vt 0.498215 0.317674 -vt 0.521155 0.305994 -vt 0.532848 0.283062 -vt 0.528828 0.257636 -vt 0.510632 0.239429 -vt 0.485208 0.235394 -vt 0.462269 0.247074 -vt 0.450576 0.270006 -vt 0.454595 0.295432 -vt 0.472792 0.313640 -vt 0.246228 0.069095 -vt 0.493196 0.277291 -vn 0.545745 0.751153 0.371391 -vn 0.883034 0.286915 0.371391 -vn 0.859567 0.279290 -0.427950 -vn 0.531242 0.731191 -0.427951 -vn 0.883033 -0.286916 0.371391 -vn 0.859567 -0.279291 -0.427951 -vn 0.545744 -0.751154 0.371391 -vn 0.531242 -0.731191 -0.427951 -vn -0.000000 -0.928477 0.371390 -vn -0.000000 -0.903802 -0.427952 -vn -0.545746 -0.751153 0.371391 -vn -0.531243 -0.731191 -0.427950 -vn -0.883034 -0.286914 0.371391 -vn -0.859567 -0.279289 -0.427952 -vn -0.883034 0.286915 0.371390 -vn -0.859567 0.279290 -0.427951 -vn -0.545745 0.751153 0.371391 -vn -0.531242 0.731191 -0.427951 -vn 0.000000 0.928477 0.371390 -vn 0.000000 0.903802 -0.427951 -vn -0.000000 -0.000000 1.000000 -vn 0.000000 0.000000 -1.000000 -s 1 -f 319/441/790 320/442/791 330/453/792 329/452/793 -f 320/442/791 321/443/794 331/454/795 330/453/792 -f 321/443/794 322/444/796 332/455/797 331/454/795 -f 322/444/796 323/445/798 333/456/799 332/455/797 -f 323/445/798 324/446/800 334/457/801 333/456/799 -f 324/446/800 325/447/802 335/458/803 334/457/801 -f 325/447/802 326/448/804 336/459/805 335/458/803 -f 326/448/804 327/449/806 337/460/807 336/459/805 -f 327/449/806 328/450/808 338/461/809 337/460/807 -f 328/450/808 319/451/790 329/462/793 338/461/809 -f 320/432/791 319/431/790 339/473/810 -f 321/433/794 320/432/791 339/473/810 -f 322/434/796 321/433/794 339/473/810 -f 323/435/798 322/434/796 339/473/810 -f 324/436/800 323/435/798 339/473/810 -f 325/437/802 324/436/800 339/473/810 -f 326/438/804 325/437/802 339/473/810 -f 327/439/806 326/438/804 339/473/810 -f 328/440/808 327/439/806 339/473/810 -f 319/431/790 328/440/808 339/473/810 -f 329/471/793 330/470/792 340/474/811 -f 330/470/792 331/469/795 340/474/811 -f 331/469/795 332/468/797 340/474/811 -f 332/468/797 333/467/799 340/474/811 -f 333/467/799 334/466/801 340/474/811 -f 334/466/801 335/465/803 340/474/811 -f 335/465/803 336/464/805 340/474/811 -f 336/464/805 337/463/807 340/474/811 -f 337/463/807 338/472/809 340/474/811 -f 338/472/809 329/471/793 340/474/811 -v -3.373292 -2.034549 1.257066 -v -3.511857 -2.034549 1.257066 -v -3.442574 -2.094549 1.153143 -v -3.373292 -0.302498 0.257066 -v -3.511857 -0.302498 0.257066 -v -3.442574 -0.362498 0.153143 -vt 0.475306 0.012993 -vt 0.524059 0.012993 -vt 0.572811 0.012993 -vt 0.621564 0.012993 -vt 0.475306 0.232930 -vt 0.524059 0.232930 -vt 0.572811 0.232930 -vt 0.621564 0.232930 -vn -0.866025 -0.250000 -0.433013 -vn 0.866027 -0.249999 -0.433011 -vn 0.866026 -0.249999 -0.433011 -vn -0.866025 -0.250001 -0.433014 -vn 0.000000 0.500000 0.866025 -vn -0.000000 0.500000 0.866026 -s 1 -f 341/475/812 342/476/813 345/480/814 344/479/815 -f 342/476/813 343/477/816 346/481/817 345/480/814 -f 343/477/816 341/478/812 344/482/815 346/481/817 -v -3.250543 -1.665037 1.076869 -v -3.141562 -1.815037 1.076869 -v -3.141562 -2.000447 1.076869 -v -3.250543 -2.150447 1.076869 -v -3.426879 -2.207742 1.076869 -v -3.603214 -2.150447 1.076869 -v -3.712196 -2.000447 1.076869 -v -3.712196 -1.815037 1.076869 -v -3.603214 -1.665037 1.076869 -v -3.426879 -1.607742 1.076869 -v -3.250544 -1.665037 1.376869 -v -3.141562 -1.815037 1.376869 -v -3.141562 -2.000447 1.376869 -v -3.250544 -2.150447 1.376869 -v -3.426879 -2.207742 1.376869 -v -3.603215 -2.150447 1.376869 -v -3.712196 -2.000447 1.376869 -v -3.712196 -1.815037 1.376869 -v -3.603215 -1.665037 1.376869 -v -3.426879 -1.607742 1.376869 -v -3.426879 -1.907742 1.076869 -v -3.426879 -1.907742 1.271261 -vt 0.252891 0.122706 -vt 0.283344 0.107201 -vt 0.298868 0.076756 -vt 0.293532 0.043002 -vt 0.269375 0.018830 -vt 0.235623 0.013474 -vt 0.205170 0.028980 -vt 0.189646 0.059424 -vt 0.194982 0.093179 -vt 0.219140 0.117351 -vt 0.987153 0.141536 -vt 0.986865 0.156219 -vt 0.986578 0.170901 -vt 0.986290 0.185584 -vt 0.986003 0.200266 -vt 0.985715 0.214949 -vt 0.985428 0.229631 -vt 0.985140 0.244313 -vt 0.984853 0.258995 -vt 0.984565 0.273678 -vt 0.984278 0.288360 -vt 0.766365 0.137213 -vt 0.766077 0.151896 -vt 0.765790 0.166578 -vt 0.765503 0.181260 -vt 0.765215 0.195943 -vt 0.764927 0.210625 -vt 0.764640 0.225307 -vt 0.764352 0.239990 -vt 0.764065 0.254672 -vt 0.763777 0.269355 -vt 0.763490 0.284037 -vt 0.498215 0.317674 -vt 0.521155 0.305994 -vt 0.532848 0.283062 -vt 0.528828 0.257636 -vt 0.510632 0.239429 -vt 0.485208 0.235394 -vt 0.462269 0.247074 -vt 0.450576 0.270006 -vt 0.454595 0.295432 -vt 0.472792 0.313640 -vt 0.246228 0.069095 -vt 0.493196 0.277291 -vn -0.545745 -0.751153 0.371390 -vn -0.883034 -0.286915 0.371390 -vn -0.859567 -0.279290 -0.427951 -vn -0.531241 -0.731192 -0.427951 -vn -0.883034 0.286915 0.371390 -vn -0.859567 0.279290 -0.427952 -vn -0.545745 0.751154 0.371390 -vn -0.531240 0.731191 -0.427952 -vn 0.000000 0.928477 0.371391 -vn -0.000000 0.903802 -0.427952 -vn 0.545745 0.751153 0.371392 -vn 0.531242 0.731191 -0.427951 -vn 0.883034 0.286914 0.371391 -vn 0.859567 0.279290 -0.427951 -vn 0.883034 -0.286915 0.371391 -vn 0.859567 -0.279290 -0.427951 -vn 0.545745 -0.751154 0.371391 -vn 0.531242 -0.731191 -0.427950 -vn 0.000000 -0.928477 0.371391 -vn -0.000000 -0.903802 -0.427951 -vn -0.000000 0.000000 1.000000 -vn 0.000000 0.000000 -1.000000 -s 1 -f 347/493/818 348/494/819 358/505/820 357/504/821 -f 348/494/819 349/495/822 359/506/823 358/505/820 -f 349/495/822 350/496/824 360/507/825 359/506/823 -f 350/496/824 351/497/826 361/508/827 360/507/825 -f 351/497/826 352/498/828 362/509/829 361/508/827 -f 352/498/828 353/499/830 363/510/831 362/509/829 -f 353/499/830 354/500/832 364/511/833 363/510/831 -f 354/500/832 355/501/834 365/512/835 364/511/833 -f 355/501/834 356/502/836 366/513/837 365/512/835 -f 356/502/836 347/503/818 357/514/821 366/513/837 -f 348/484/819 347/483/818 367/525/838 -f 349/485/822 348/484/819 367/525/838 -f 350/486/824 349/485/822 367/525/838 -f 351/487/826 350/486/824 367/525/838 -f 352/488/828 351/487/826 367/525/838 -f 353/489/830 352/488/828 367/525/838 -f 354/490/832 353/489/830 367/525/838 -f 355/491/834 354/490/832 367/525/838 -f 356/492/836 355/491/834 367/525/838 -f 347/483/818 356/492/836 367/525/838 -f 357/523/821 358/522/820 368/526/839 -f 358/522/820 359/521/823 368/526/839 -f 359/521/823 360/520/825 368/526/839 -f 360/520/825 361/519/827 368/526/839 -f 361/519/827 362/518/829 368/526/839 -f 362/518/829 363/517/831 368/526/839 -f 363/517/831 364/516/833 368/526/839 -f 364/516/833 365/515/835 368/526/839 -f 365/515/835 366/524/837 368/526/839 -f 366/524/837 357/523/821 368/526/839 -v 3.068942 -0.472892 0.150000 -v 3.068942 -0.658302 0.150000 -v 2.959961 -0.808302 0.150000 -v 2.783625 -0.865597 0.150000 -v 2.607290 -0.808302 0.150000 -v 2.498308 -0.658302 0.150000 -v 2.498308 -0.472892 0.150000 -v 3.068942 -0.472892 -0.150000 -v 3.068942 -0.658302 -0.150000 -v 2.959961 -0.808302 -0.150000 -v 2.783625 -0.865597 -0.150000 -v 2.607290 -0.808302 -0.150000 -v 2.498308 -0.658302 -0.150000 -v 2.498308 -0.472892 -0.150000 -v 2.783625 -0.565597 0.150000 -v 2.783625 -0.565597 -0.044391 -vt 0.283344 0.107201 -vt 0.298868 0.076756 -vt 0.293532 0.043002 -vt 0.269375 0.018830 -vt 0.235623 0.013474 -vt 0.205170 0.028980 -vt 0.189646 0.059424 -vt 0.986865 0.156219 -vt 0.986578 0.170901 -vt 0.986290 0.185584 -vt 0.986003 0.200266 -vt 0.985715 0.214949 -vt 0.985428 0.229631 -vt 0.985140 0.244313 -vt 0.766077 0.151896 -vt 0.765790 0.166578 -vt 0.765503 0.181260 -vt 0.765215 0.195943 -vt 0.764927 0.210625 -vt 0.764640 0.225307 -vt 0.764352 0.239990 -vt 0.521155 0.305994 -vt 0.532848 0.283062 -vt 0.528828 0.257636 -vt 0.510632 0.239429 -vt 0.485208 0.235394 -vt 0.462269 0.247074 -vt 0.450576 0.270006 -vt 0.246228 0.069095 -vt 0.493196 0.277291 -vn 0.934652 0.000000 0.355563 -vn 0.883034 -0.286915 0.371391 -vn 0.859567 -0.279290 -0.427951 -vn 0.911810 0.000000 -0.410612 -vn 0.545745 -0.751153 0.371391 -vn 0.531242 -0.731191 -0.427951 -vn -0.000000 -0.928477 0.371391 -vn -0.000000 -0.903802 -0.427951 -vn -0.545745 -0.751154 0.371391 -vn -0.531241 -0.731191 -0.427951 -vn -0.883034 -0.286915 0.371391 -vn -0.859567 -0.279291 -0.427951 -vn -0.934652 0.000000 0.355563 -vn -0.911810 0.000000 -0.410612 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.186532 -0.982449 -s 1 -f 369/534/840 370/535/841 377/542/842 376/541/843 -f 370/535/841 371/536/844 378/543/845 377/542/842 -f 371/536/844 372/537/846 379/544/847 378/543/845 -f 372/537/846 373/538/848 380/545/849 379/544/847 -f 373/538/848 374/539/850 381/546/851 380/545/849 -f 374/539/850 375/540/852 382/547/853 381/546/851 -f 370/528/841 369/527/840 383/555/854 -f 371/529/844 370/528/841 383/555/854 -f 372/530/846 371/529/844 383/555/854 -f 373/531/848 372/530/846 383/555/854 -f 374/532/850 373/531/848 383/555/854 -f 375/533/852 374/532/850 383/555/854 -f 376/554/843 377/553/842 384/556/855 -f 377/553/842 378/552/845 384/556/855 -f 378/552/845 379/551/847 384/556/855 -f 379/551/847 380/550/849 384/556/855 -f 380/550/849 381/549/851 384/556/855 -f 381/549/851 382/548/853 384/556/855 diff --git a/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/diffuse_512.png b/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/diffuse_512.png deleted file mode 100644 index 930d910b947a7e494fc5430018e4f2dc33344fee..0000000000000000000000000000000000000000 Binary files a/mpu6050-master/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/diffuse_512.png and /dev/null differ diff --git a/mpu6050-master/examples/MPU6050_raw/MPU6050_raw.ino b/mpu6050-master/examples/MPU6050_raw/MPU6050_raw.ino deleted file mode 100644 index 9d5be00d56625a109fb14ce25090c30188451a00..0000000000000000000000000000000000000000 --- a/mpu6050-master/examples/MPU6050_raw/MPU6050_raw.ino +++ /dev/null @@ -1,151 +0,0 @@ -// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class -// 10/7/2011 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2013-05-08 - added multiple output formats -// - added seamless Fastwire support -// 2011-10-07 - initial release - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2011 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files -// for both classes must be in the include path of your project -#include "I2Cdev.h" -#include "MPU6050.h" - -// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation -// is used in I2Cdev.h -#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - #include "Wire.h" -#endif - -// class default I2C address is 0x68 -// specific I2C addresses may be passed as a parameter here -// AD0 low = 0x68 (default for InvenSense evaluation board) -// AD0 high = 0x69 -MPU6050 accelgyro; -//MPU6050 accelgyro(0x69); // <-- use for AD0 high - -int16_t ax, ay, az; -int16_t gx, gy, gz; - - - -// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated -// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read, -// not so easy to parse, and slow(er) over UART. -#define OUTPUT_READABLE_ACCELGYRO - -// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit -// binary, one right after the other. This is very fast (as fast as possible -// without compression or data loss), and easy to parse, but impossible to read -// for a human. -//#define OUTPUT_BINARY_ACCELGYRO - - -#define LED_PIN 13 -bool blinkState = false; - -void setup() { - // join I2C bus (I2Cdev library doesn't do this automatically) - #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - Wire.begin(); - #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE - Fastwire::setup(400, true); - #endif - - // initialize serial communication - // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but - // it's really up to you depending on your project) - Serial.begin(38400); - - // initialize device - Serial.println("Initializing I2C devices..."); - accelgyro.initialize(); - - // verify connection - Serial.println("Testing device connections..."); - Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); - - // use the code below to change accel/gyro offset values - /* - Serial.println("Updating internal sensor offsets..."); - // -76 -2359 1688 0 0 0 - Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76 - Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359 - Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688 - Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0 - Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0 - Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0 - Serial.print("\n"); - accelgyro.setXGyroOffset(220); - accelgyro.setYGyroOffset(76); - accelgyro.setZGyroOffset(-85); - Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76 - Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359 - Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688 - Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0 - Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0 - Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0 - Serial.print("\n"); - */ - - // configure Arduino LED pin for output - pinMode(LED_PIN, OUTPUT); -} - -void loop() { - // read raw accel/gyro measurements from device - accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); - - // these methods (and a few others) are also available - //accelgyro.getAcceleration(&ax, &ay, &az); - //accelgyro.getRotation(&gx, &gy, &gz); - - #ifdef OUTPUT_READABLE_ACCELGYRO - // display tab-separated accel/gyro x/y/z values - Serial.print("a/g:\t"); - Serial.print(ax); Serial.print("\t"); - Serial.print(ay); Serial.print("\t"); - Serial.print(az); Serial.print("\t"); - Serial.print(gx); Serial.print("\t"); - Serial.print(gy); Serial.print("\t"); - Serial.println(gz); - #endif - - #ifdef OUTPUT_BINARY_ACCELGYRO - Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF)); - Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF)); - Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF)); - Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF)); - Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF)); - Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF)); - #endif - - // blink LED to indicate activity - blinkState = !blinkState; - digitalWrite(LED_PIN, blinkState); -} diff --git a/mpu6050-master/keywords.txt b/mpu6050-master/keywords.txt deleted file mode 100644 index b8d6c36c27e8c6ea6ba9e1576311d614e1ba60a6..0000000000000000000000000000000000000000 --- a/mpu6050-master/keywords.txt +++ /dev/null @@ -1,50 +0,0 @@ -####################################### -# Syntax Coloring Map For MPU6050 -####################################### - -####################################### -# Class (KEYWORD1) -####################################### -MPU6050 KEYWORD1 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -initialize KEYWORD2 -testConnection KEYWORD2 - -getMotion6 KEYWORD2 -getMotion9 KEYWORD2 -getAccelerationX KEYWORD2 -getAccelerationY KEYWORD2 -getAccelerationZ KEYWORD2 - -getTemperature KEYWORD2 - -getRotation KEYWORD2 -getRotationX KEYWORD2 -getRotationY KEYWORD2 -getRotationZ KEYWORD2 - -setI2CMasterModeEnabled KEYWORD2 -setI2CBypassEnabled KEYWORD2 -setSleepEnabled KEYWORD2 -getFreefallDetectionThreshold KEYWORD2 -setFreefallDetectionThreshold KEYWORD2 -getFreefallDetectionDuration KEYWORD2 -setFreefallDetectionDuration KEYWORD2 -getMotionDetectionThreshold KEYWORD2 -setMotionDetectionThreshold KEYWORD2 -getMotionDetectionDuration KEYWORD2 -setMotionDetectionDuration KEYWORD2 - -CalibrateGyro KEYWORD2 -CalibrateAccel KEYWORD2 -PID KEYWORD2 -PrintActiveOffsets KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### - diff --git a/mpu6050-master/library.properties b/mpu6050-master/library.properties deleted file mode 100644 index 4457490af5c53057aac684c827b436b893dc056f..0000000000000000000000000000000000000000 --- a/mpu6050-master/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=MPU6050 -version=1.0.0 -author=Electronic Cats -maintainer=Electronic Cats <store@electroniccats.com> -sentence=MPU6050 Arduino Library. -paragraph=MPU-6050 6-axis accelerometer/gyroscope Arduino Library. -category=Sensors -url=https://github.com/electroniccats/mpu6050 -architectures=avr,samd,sam,esp8266,esp32,stm32 -includes=MPU6050.h diff --git a/mpu6050-master/src/MPU6050.cpp b/mpu6050-master/src/MPU6050.cpp deleted file mode 100644 index e48342d8fd7f1fb5019ced54167f908e6015a1c2..0000000000000000000000000000000000000000 --- a/mpu6050-master/src/MPU6050.cpp +++ /dev/null @@ -1,3380 +0,0 @@ -// I2Cdev library collection - MPU6050 I2C device class -// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) -// 8/24/2011 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2019-07-08 - Added Auto Calibration routine -// ... - ongoing debug release - -// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE -// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF -// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING. - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -#include "MPU6050.h" -#if defined(ARDUINO_ARCH_MBED) -#include "api/deprecated-avr-comp/avr/dtostrf.c.impl" -#endif - -#ifndef BUFFER_LENGTH -// band-aid fix for platforms without Wire-defined BUFFER_LENGTH (removed from some official implementations) -#define BUFFER_LENGTH 32 -#endif - -/** Specific address constructor. - * @param address I2C address, uses default I2C address if none is specified - * @see MPU6050_DEFAULT_ADDRESS - * @see MPU6050_ADDRESS_AD0_LOW - * @see MPU6050_ADDRESS_AD0_HIGH - */ -MPU6050::MPU6050(uint8_t address):devAddr(address) { -} - -/** Power on and prepare for general usage. - * This will activate the device and take it out of sleep mode (which must be done - * after start-up). This function also sets both the accelerometer and the gyroscope - * to their most sensitive settings, namely +/- 2g and +/- 250 degrees/sec, and sets - * the clock source to use the X Gyro for reference, which is slightly better than - * the default internal clock source. - */ -void MPU6050::initialize() { - setClockSource( (MPU6050_IMU::MPU6050_CLOCK_PLL_XGYRO)); - setFullScaleGyroRange( (MPU6050_IMU::MPU6050_GYRO_FS_250)); - setFullScaleAccelRange( (MPU6050_IMU::MPU6050_ACCEL_FS_2)); - setSleepEnabled(false); // thanks to Jack Elston for pointing this one out! -} - -/** Verify the I2C connection. - * Make sure the device is connected and responds as expected. - * @return True if connection is valid, false otherwise - */ -bool MPU6050::testConnection() { - uint8_t deviceId = getDeviceID(); - return (deviceId == 0x34) || (deviceId == 0xC); -} - -// AUX_VDDIO register (InvenSense demo code calls this RA_*G_OFFS_TC) - -/** Get the auxiliary I2C supply voltage level. - * When set to 1, the auxiliary I2C bus high logic level is VDD. When cleared to - * 0, the auxiliary I2C bus high logic level is VLOGIC. This does not apply to - * the MPU-6000, which does not have a VLOGIC pin. - * @return I2C supply voltage level (0=VLOGIC, 1=VDD) - */ -uint8_t MPU6050::getAuxVDDIOLevel() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_YG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_PWR_MODE_BIT), buffer); - return buffer[0]; -} -/** Set the auxiliary I2C supply voltage level. - * When set to 1, the auxiliary I2C bus high logic level is VDD. When cleared to - * 0, the auxiliary I2C bus high logic level is VLOGIC. This does not apply to - * the MPU-6000, which does not have a VLOGIC pin. - * @param level I2C supply voltage level (0=VLOGIC, 1=VDD) - */ -void MPU6050::setAuxVDDIOLevel(uint8_t level) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_YG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_PWR_MODE_BIT), level); -} - -// SMPLRT_DIV register - -/** Get gyroscope output rate divider. - * The sensor register output, FIFO output, DMP sampling, Motion detection, Zero - * Motion detection, and Free Fall detection are all based on the Sample Rate. - * The Sample Rate is generated by dividing the gyroscope output rate by - * SMPLRT_DIV: - * - * Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV) - * - * where Gyroscope Output Rate = 8kHz when the DLPF is disabled (DLPF_CFG = 0 or - * 7), and 1kHz when the DLPF is enabled (see Register 26). - * - * Note: The accelerometer output rate is 1kHz. This means that for a Sample - * Rate greater than 1kHz, the same accelerometer sample may be output to the - * FIFO, DMP, and sensor registers more than once. - * - * For a diagram of the gyroscope and accelerometer signal paths, see Section 8 - * of the MPU-6000/MPU-6050 Product Specification document. - * - * @return Current sample rate - * @see MPU6050_RA_SMPLRT_DIV - */ -uint8_t MPU6050::getRate() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_SMPLRT_DIV), buffer); - return buffer[0]; -} -/** Set gyroscope sample rate divider. - * @param rate New sample rate divider - * @see getRate() - * @see MPU6050_RA_SMPLRT_DIV - */ -void MPU6050::setRate(uint8_t rate) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_SMPLRT_DIV), rate); -} - -// CONFIG register - -/** Get external FSYNC configuration. - * Configures the external Frame Synchronization (FSYNC) pin sampling. An - * external signal connected to the FSYNC pin can be sampled by configuring - * EXT_SYNC_SET. Signal changes to the FSYNC pin are latched so that short - * strobes may be captured. The latched FSYNC signal will be sampled at the - * Sampling Rate, as defined in register 25. After sampling, the latch will - * reset to the current FSYNC signal state. - * - * The sampled value will be reported in place of the least significant bit in - * a sensor data register determined by the value of EXT_SYNC_SET according to - * the following table. - * - * <pre> - * EXT_SYNC_SET | FSYNC Bit Location - * -------------+------------------- - * 0 | Input disabled - * 1 | TEMP_OUT_L[0] - * 2 | GYRO_XOUT_L[0] - * 3 | GYRO_YOUT_L[0] - * 4 | GYRO_ZOUT_L[0] - * 5 | ACCEL_XOUT_L[0] - * 6 | ACCEL_YOUT_L[0] - * 7 | ACCEL_ZOUT_L[0] - * </pre> - * - * @return FSYNC configuration value - */ -uint8_t MPU6050::getExternalFrameSync() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_CONFIG), (MPU6050_IMU::MPU6050_CFG_EXT_SYNC_SET_BIT), (MPU6050_IMU::MPU6050_CFG_EXT_SYNC_SET_LENGTH), buffer); - return buffer[0]; -} -/** Set external FSYNC configuration. - * @see getExternalFrameSync() - * @see MPU6050_RA_CONFIG - * @param sync New FSYNC configuration value - */ -void MPU6050::setExternalFrameSync(uint8_t sync) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_CONFIG), (MPU6050_IMU::MPU6050_CFG_EXT_SYNC_SET_BIT), (MPU6050_IMU::MPU6050_CFG_EXT_SYNC_SET_LENGTH), sync); -} -/** Get digital low-pass filter configuration. - * The DLPF_CFG parameter sets the digital low pass filter configuration. It - * also determines the internal sampling rate used by the device as shown in - * the table below. - * - * Note: The accelerometer output rate is 1kHz. This means that for a Sample - * Rate greater than 1kHz, the same accelerometer sample may be output to the - * FIFO, DMP, and sensor registers more than once. - * - * <pre> - * | ACCELEROMETER | GYROSCOPE - * DLPF_CFG | Bandwidth | Delay | Bandwidth | Delay | Sample Rate - * ---------+-----------+--------+-----------+--------+------------- - * 0 | 260Hz | 0ms | 256Hz | 0.98ms | 8kHz - * 1 | 184Hz | 2.0ms | 188Hz | 1.9ms | 1kHz - * 2 | 94Hz | 3.0ms | 98Hz | 2.8ms | 1kHz - * 3 | 44Hz | 4.9ms | 42Hz | 4.8ms | 1kHz - * 4 | 21Hz | 8.5ms | 20Hz | 8.3ms | 1kHz - * 5 | 10Hz | 13.8ms | 10Hz | 13.4ms | 1kHz - * 6 | 5Hz | 19.0ms | 5Hz | 18.6ms | 1kHz - * 7 | -- Reserved -- | -- Reserved -- | Reserved - * </pre> - * - * @return DLFP configuration - * @see MPU6050_RA_CONFIG - * @see MPU6050_CFG_DLPF_CFG_BIT - * @see MPU6050_CFG_DLPF_CFG_LENGTH - */ -uint8_t MPU6050::getDLPFMode() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_CONFIG), (MPU6050_IMU::MPU6050_CFG_DLPF_CFG_BIT), (MPU6050_IMU::MPU6050_CFG_DLPF_CFG_LENGTH), buffer); - return buffer[0]; -} -/** Set digital low-pass filter configuration. - * @param mode New DLFP configuration setting - * @see getDLPFBandwidth() - * @see MPU6050_DLPF_BW_256 - * @see MPU6050_RA_CONFIG - * @see MPU6050_CFG_DLPF_CFG_BIT - * @see MPU6050_CFG_DLPF_CFG_LENGTH - */ -void MPU6050::setDLPFMode(uint8_t mode) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_CONFIG), (MPU6050_IMU::MPU6050_CFG_DLPF_CFG_BIT), (MPU6050_IMU::MPU6050_CFG_DLPF_CFG_LENGTH), mode); -} - -// GYRO_CONFIG register - -/** Get full-scale gyroscope range. - * The FS_SEL parameter allows setting the full-scale range of the gyro sensors, - * as described in the table below. - * - * <pre> - * 0 = +/- 250 degrees/sec - * 1 = +/- 500 degrees/sec - * 2 = +/- 1000 degrees/sec - * 3 = +/- 2000 degrees/sec - * </pre> - * - * @return Current full-scale gyroscope range setting - * @see MPU6050_GYRO_FS_250 - * @see MPU6050_RA_GYRO_CONFIG - * @see MPU6050_GCONFIG_FS_SEL_BIT - * @see (MPU6050_IMU::MPU6050_GCONFIG_FS_SEL_LENGTH) - */ -uint8_t MPU6050::getFullScaleGyroRange() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_GYRO_CONFIG), (MPU6050_IMU::MPU6050_GCONFIG_FS_SEL_BIT), (MPU6050_IMU::MPU6050_GCONFIG_FS_SEL_LENGTH), buffer); - return buffer[0]; -} -/** Set full-scale gyroscope range. - * @param range New full-scale gyroscope range value - * @see getFullScaleRange() - * @see MPU6050_GYRO_FS_250 - * @see MPU6050_RA_GYRO_CONFIG - * @see MPU6050_GCONFIG_FS_SEL_BIT - * @see (MPU6050_IMU::MPU6050_GCONFIG_FS_SEL_LENGTH) - */ -void MPU6050::setFullScaleGyroRange(uint8_t range) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_GYRO_CONFIG), (MPU6050_IMU::MPU6050_GCONFIG_FS_SEL_BIT), (MPU6050_IMU::MPU6050_GCONFIG_FS_SEL_LENGTH), range); -} - -// SELF TEST FACTORY TRIM VALUES - -/** Get self-test factory trim value for accelerometer X axis. - * @return factory trim value - * @see MPU6050_RA_SELF_TEST_X - */ -uint8_t MPU6050::getAccelXSelfTestFactoryTrim() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_SELF_TEST_X), &buffer[0]); - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_SELF_TEST_A), &buffer[1]); - return (buffer[0]>>3) | ((buffer[1]>>4) & 0x03); -} - -/** Get self-test factory trim value for accelerometer Y axis. - * @return factory trim value - * @see MPU6050_RA_SELF_TEST_Y - */ -uint8_t MPU6050::getAccelYSelfTestFactoryTrim() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_SELF_TEST_Y), &buffer[0]); - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_SELF_TEST_A), &buffer[1]); - return (buffer[0]>>3) | ((buffer[1]>>2) & 0x03); -} - -/** Get self-test factory trim value for accelerometer Z axis. - * @return factory trim value - * @see MPU6050_RA_SELF_TEST_Z - */ -uint8_t MPU6050::getAccelZSelfTestFactoryTrim() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_SELF_TEST_Z), 2, buffer); - return (buffer[0]>>3) | (buffer[1] & 0x03); -} - -/** Get self-test factory trim value for gyro X axis. - * @return factory trim value - * @see MPU6050_RA_SELF_TEST_X - */ -uint8_t MPU6050::getGyroXSelfTestFactoryTrim() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_SELF_TEST_X), buffer); - return (buffer[0] & 0x1F); -} - -/** Get self-test factory trim value for gyro Y axis. - * @return factory trim value - * @see MPU6050_RA_SELF_TEST_Y - */ -uint8_t MPU6050::getGyroYSelfTestFactoryTrim() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_SELF_TEST_Y), buffer); - return (buffer[0] & 0x1F); -} - -/** Get self-test factory trim value for gyro Z axis. - * @return factory trim value - * @see MPU6050_RA_SELF_TEST_Z - */ -uint8_t MPU6050::getGyroZSelfTestFactoryTrim() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_SELF_TEST_Z), buffer); - return (buffer[0] & 0x1F); -} - -// ACCEL_CONFIG register - -/** Get self-test enabled setting for accelerometer X axis. - * @return Self-test enabled value - * @see MPU6050_RA_ACCEL_CONFIG - */ -bool MPU6050::getAccelXSelfTest() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_XA_ST_BIT), buffer); - return buffer[0]; -} -/** Get self-test enabled setting for accelerometer X axis. - * @param enabled Self-test enabled value - * @see MPU6050_RA_ACCEL_CONFIG - */ -void MPU6050::setAccelXSelfTest(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_XA_ST_BIT), enabled); -} -/** Get self-test enabled value for accelerometer Y axis. - * @return Self-test enabled value - * @see MPU6050_RA_ACCEL_CONFIG - */ -bool MPU6050::getAccelYSelfTest() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_YA_ST_BIT), buffer); - return buffer[0]; -} -/** Get self-test enabled value for accelerometer Y axis. - * @param enabled Self-test enabled value - * @see MPU6050_RA_ACCEL_CONFIG - */ -void MPU6050::setAccelYSelfTest(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_YA_ST_BIT), enabled); -} -/** Get self-test enabled value for accelerometer Z axis. - * @return Self-test enabled value - * @see MPU6050_RA_ACCEL_CONFIG - */ -bool MPU6050::getAccelZSelfTest() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_ZA_ST_BIT), buffer); - return buffer[0]; -} -/** Set self-test enabled value for accelerometer Z axis. - * @param enabled Self-test enabled value - * @see MPU6050_RA_ACCEL_CONFIG - */ -void MPU6050::setAccelZSelfTest(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_ZA_ST_BIT), enabled); -} -/** Get full-scale accelerometer range. - * The FS_SEL parameter allows setting the full-scale range of the accelerometer - * sensors, as described in the table below. - * - * <pre> - * 0 = +/- 2g - * 1 = +/- 4g - * 2 = +/- 8g - * 3 = +/- 16g - * </pre> - * - * @return Current full-scale accelerometer range setting - * @see MPU6050_ACCEL_FS_2 - * @see MPU6050_RA_ACCEL_CONFIG - * @see MPU6050_ACONFIG_AFS_SEL_BIT - * @see (MPU6050_IMU::MPU6050_ACONFIG_AFS_SEL_LENGTH) - */ -uint8_t MPU6050::getFullScaleAccelRange() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_AFS_SEL_BIT), (MPU6050_IMU::MPU6050_ACONFIG_AFS_SEL_LENGTH), buffer); - return buffer[0]; -} -/** Set full-scale accelerometer range. - * @param range New full-scale accelerometer range setting - * @see getFullScaleAccelRange() - */ -void MPU6050::setFullScaleAccelRange(uint8_t range) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_AFS_SEL_BIT), (MPU6050_IMU::MPU6050_ACONFIG_AFS_SEL_LENGTH), range); -} -/** Get the high-pass filter configuration. - * The DHPF is a filter module in the path leading to motion detectors (Free - * Fall, Motion threshold, and Zero Motion). The high pass filter output is not - * available to the data registers (see Figure in Section 8 of the MPU-6000/ - * MPU-6050 Product Specification document). - * - * The high pass filter has three modes: - * - * <pre> - * Reset: The filter output settles to zero within one sample. This - * effectively disables the high pass filter. This mode may be toggled - * to quickly settle the filter. - * - * On: The high pass filter will pass signals above the cut off frequency. - * - * Hold: When triggered, the filter holds the present sample. The filter - * output will be the difference between the input sample and the held - * sample. - * </pre> - * - * <pre> - * ACCEL_HPF | Filter Mode | Cut-off Frequency - * ----------+-------------+------------------ - * 0 | Reset | None - * 1 | On | 5Hz - * 2 | On | 2.5Hz - * 3 | On | 1.25Hz - * 4 | On | 0.63Hz - * 7 | Hold | None - * </pre> - * - * @return Current high-pass filter configuration - * @see MPU6050_DHPF_RESET - * @see MPU6050_RA_ACCEL_CONFIG - */ -uint8_t MPU6050::getDHPFMode() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_ACCEL_HPF_BIT), (MPU6050_IMU::MPU6050_ACONFIG_ACCEL_HPF_LENGTH), buffer); - return buffer[0]; -} -/** Set the high-pass filter configuration. - * @param bandwidth New high-pass filter configuration - * @see setDHPFMode() - * @see MPU6050_DHPF_RESET - * @see MPU6050_RA_ACCEL_CONFIG - */ -void MPU6050::setDHPFMode(uint8_t bandwidth) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_CONFIG), (MPU6050_IMU::MPU6050_ACONFIG_ACCEL_HPF_BIT), (MPU6050_IMU::MPU6050_ACONFIG_ACCEL_HPF_LENGTH), bandwidth); -} - -// FF_THR register - -/** Get free-fall event acceleration threshold. - * This register configures the detection threshold for Free Fall event - * detection. The unit of FF_THR is 1LSB = 2mg. Free Fall is detected when the - * absolute value of the accelerometer measurements for the three axes are each - * less than the detection threshold. This condition increments the Free Fall - * duration counter (Register 30). The Free Fall interrupt is triggered when the - * Free Fall duration counter reaches the time specified in FF_DUR. - * - * For more details on the Free Fall detection interrupt, see Section 8.2 of the - * MPU-6000/MPU-6050 Product Specification document as well as Registers 56 and - * 58 of this document. - * - * @return Current free-fall acceleration threshold value (LSB = 2mg) - * @see MPU6050_RA_FF_THR - */ -uint8_t MPU6050::getFreefallDetectionThreshold() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_FF_THR), buffer); - return buffer[0]; -} -/** Get free-fall event acceleration threshold. - * @param threshold New free-fall acceleration threshold value (LSB = 2mg) - * @see getFreefallDetectionThreshold() - * @see MPU6050_RA_FF_THR - */ -void MPU6050::setFreefallDetectionThreshold(uint8_t threshold) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_FF_THR), threshold); -} - -// FF_DUR register - -/** Get free-fall event duration threshold. - * This register configures the duration counter threshold for Free Fall event - * detection. The duration counter ticks at 1kHz, therefore FF_DUR has a unit - * of 1 LSB = 1 ms. - * - * The Free Fall duration counter increments while the absolute value of the - * accelerometer measurements are each less than the detection threshold - * (Register 29). The Free Fall interrupt is triggered when the Free Fall - * duration counter reaches the time specified in this register. - * - * For more details on the Free Fall detection interrupt, see Section 8.2 of - * the MPU-6000/MPU-6050 Product Specification document as well as Registers 56 - * and 58 of this document. - * - * @return Current free-fall duration threshold value (LSB = 1ms) - * @see MPU6050_RA_FF_DUR - */ -uint8_t MPU6050::getFreefallDetectionDuration() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_FF_DUR), buffer); - return buffer[0]; -} -/** Get free-fall event duration threshold. - * @param duration New free-fall duration threshold value (LSB = 1ms) - * @see getFreefallDetectionDuration() - * @see MPU6050_RA_FF_DUR - */ -void MPU6050::setFreefallDetectionDuration(uint8_t duration) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_FF_DUR), duration); -} - -// MOT_THR register - -/** Get motion detection event acceleration threshold. - * This register configures the detection threshold for Motion interrupt - * generation. The unit of MOT_THR is 1LSB = 2mg. Motion is detected when the - * absolute value of any of the accelerometer measurements exceeds this Motion - * detection threshold. This condition increments the Motion detection duration - * counter (Register 32). The Motion detection interrupt is triggered when the - * Motion Detection counter reaches the time count specified in MOT_DUR - * (Register 32). - * - * The Motion interrupt will indicate the axis and polarity of detected motion - * in MOT_DETECT_STATUS (Register 97). - * - * For more details on the Motion detection interrupt, see Section 8.3 of the - * MPU-6000/MPU-6050 Product Specification document as well as Registers 56 and - * 58 of this document. - * - * @return Current motion detection acceleration threshold value (LSB = 2mg) - * @see MPU6050_RA_MOT_THR - */ -uint8_t MPU6050::getMotionDetectionThreshold() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_THR), buffer); - return buffer[0]; -} -/** Set motion detection event acceleration threshold. - * @param threshold New motion detection acceleration threshold value (LSB = 2mg) - * @see getMotionDetectionThreshold() - * @see MPU6050_RA_MOT_THR - */ -void MPU6050::setMotionDetectionThreshold(uint8_t threshold) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_THR), threshold); -} - -// MOT_DUR register - -/** Get motion detection event duration threshold. - * This register configures the duration counter threshold for Motion interrupt - * generation. The duration counter ticks at 1 kHz, therefore MOT_DUR has a unit - * of 1LSB = 1ms. The Motion detection duration counter increments when the - * absolute value of any of the accelerometer measurements exceeds the Motion - * detection threshold (Register 31). The Motion detection interrupt is - * triggered when the Motion detection counter reaches the time count specified - * in this register. - * - * For more details on the Motion detection interrupt, see Section 8.3 of the - * MPU-6000/MPU-6050 Product Specification document. - * - * @return Current motion detection duration threshold value (LSB = 1ms) - * @see MPU6050_RA_MOT_DUR - */ -uint8_t MPU6050::getMotionDetectionDuration() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DUR), buffer); - return buffer[0]; -} -/** Set motion detection event duration threshold. - * @param duration New motion detection duration threshold value (LSB = 1ms) - * @see getMotionDetectionDuration() - * @see MPU6050_RA_MOT_DUR - */ -void MPU6050::setMotionDetectionDuration(uint8_t duration) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DUR), duration); -} - -// ZRMOT_THR register - -/** Get zero motion detection event acceleration threshold. - * This register configures the detection threshold for Zero Motion interrupt - * generation. The unit of ZRMOT_THR is 1LSB = 2mg. Zero Motion is detected when - * the absolute value of the accelerometer measurements for the 3 axes are each - * less than the detection threshold. This condition increments the Zero Motion - * duration counter (Register 34). The Zero Motion interrupt is triggered when - * the Zero Motion duration counter reaches the time count specified in - * ZRMOT_DUR (Register 34). - * - * Unlike Free Fall or Motion detection, Zero Motion detection triggers an - * interrupt both when Zero Motion is first detected and when Zero Motion is no - * longer detected. - * - * When a zero motion event is detected, a Zero Motion Status will be indicated - * in the MOT_DETECT_STATUS register (Register 97). When a motion-to-zero-motion - * condition is detected, the status bit is set to 1. When a zero-motion-to- - * motion condition is detected, the status bit is set to 0. - * - * For more details on the Zero Motion detection interrupt, see Section 8.4 of - * the MPU-6000/MPU-6050 Product Specification document as well as Registers 56 - * and 58 of this document. - * - * @return Current zero motion detection acceleration threshold value (LSB = 2mg) - * @see MPU6050_RA_ZRMOT_THR - */ -uint8_t MPU6050::getZeroMotionDetectionThreshold() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_ZRMOT_THR), buffer); - return buffer[0]; -} -/** Set zero motion detection event acceleration threshold. - * @param threshold New zero motion detection acceleration threshold value (LSB = 2mg) - * @see getZeroMotionDetectionThreshold() - * @see MPU6050_RA_ZRMOT_THR - */ -void MPU6050::setZeroMotionDetectionThreshold(uint8_t threshold) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_ZRMOT_THR), threshold); -} - -// ZRMOT_DUR register - -/** Get zero motion detection event duration threshold. - * This register configures the duration counter threshold for Zero Motion - * interrupt generation. The duration counter ticks at 16 Hz, therefore - * ZRMOT_DUR has a unit of 1 LSB = 64 ms. The Zero Motion duration counter - * increments while the absolute value of the accelerometer measurements are - * each less than the detection threshold (Register 33). The Zero Motion - * interrupt is triggered when the Zero Motion duration counter reaches the time - * count specified in this register. - * - * For more details on the Zero Motion detection interrupt, see Section 8.4 of - * the MPU-6000/MPU-6050 Product Specification document, as well as Registers 56 - * and 58 of this document. - * - * @return Current zero motion detection duration threshold value (LSB = 64ms) - * @see MPU6050_RA_ZRMOT_DUR - */ -uint8_t MPU6050::getZeroMotionDetectionDuration() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_ZRMOT_DUR), buffer); - return buffer[0]; -} -/** Set zero motion detection event duration threshold. - * @param duration New zero motion detection duration threshold value (LSB = 1ms) - * @see getZeroMotionDetectionDuration() - * @see MPU6050_RA_ZRMOT_DUR - */ -void MPU6050::setZeroMotionDetectionDuration(uint8_t duration) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_ZRMOT_DUR), duration); -} - -// FIFO_EN register - -/** Get temperature FIFO enabled value. - * When set to 1, this bit enables TEMP_OUT_H and TEMP_OUT_L (Registers 65 and - * 66) to be written into the FIFO buffer. - * @return Current temperature FIFO enabled value - * @see MPU6050_RA_FIFO_EN - */ -bool MPU6050::getTempFIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_TEMP_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set temperature FIFO enabled value. - * @param enabled New temperature FIFO enabled value - * @see getTempFIFOEnabled() - * @see MPU6050_RA_FIFO_EN - */ -void MPU6050::setTempFIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_TEMP_FIFO_EN_BIT), enabled); -} -/** Get gyroscope X-axis FIFO enabled value. - * When set to 1, this bit enables GYRO_XOUT_H and GYRO_XOUT_L (Registers 67 and - * 68) to be written into the FIFO buffer. - * @return Current gyroscope X-axis FIFO enabled value - * @see MPU6050_RA_FIFO_EN - */ -bool MPU6050::getXGyroFIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_XG_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set gyroscope X-axis FIFO enabled value. - * @param enabled New gyroscope X-axis FIFO enabled value - * @see getXGyroFIFOEnabled() - * @see MPU6050_RA_FIFO_EN - */ -void MPU6050::setXGyroFIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_XG_FIFO_EN_BIT), enabled); -} -/** Get gyroscope Y-axis FIFO enabled value. - * When set to 1, this bit enables GYRO_YOUT_H and GYRO_YOUT_L (Registers 69 and - * 70) to be written into the FIFO buffer. - * @return Current gyroscope Y-axis FIFO enabled value - * @see MPU6050_RA_FIFO_EN - */ -bool MPU6050::getYGyroFIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_YG_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set gyroscope Y-axis FIFO enabled value. - * @param enabled New gyroscope Y-axis FIFO enabled value - * @see getYGyroFIFOEnabled() - * @see MPU6050_RA_FIFO_EN - */ -void MPU6050::setYGyroFIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_YG_FIFO_EN_BIT), enabled); -} -/** Get gyroscope Z-axis FIFO enabled value. - * When set to 1, this bit enables GYRO_ZOUT_H and GYRO_ZOUT_L (Registers 71 and - * 72) to be written into the FIFO buffer. - * @return Current gyroscope Z-axis FIFO enabled value - * @see MPU6050_RA_FIFO_EN - */ -bool MPU6050::getZGyroFIFOEnabled() { - I2Cdev::readBit (devAddr, (MPU6050_IMU:: MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_ZG_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set gyroscope Z-axis FIFO enabled value. - * @param enabled New gyroscope Z-axis FIFO enabled value - * @see getZGyroFIFOEnabled() - * @see MPU6050_RA_FIFO_EN - */ -void MPU6050::setZGyroFIFOEnabled(bool enabled) { - I2Cdev::writeBit (devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_ZG_FIFO_EN_BIT), enabled); -} -/** Get accelerometer FIFO enabled value. - * When set to 1, this bit enables ACCEL_XOUT_H, ACCEL_XOUT_L, ACCEL_YOUT_H, - * ACCEL_YOUT_L, ACCEL_ZOUT_H, and ACCEL_ZOUT_L (Registers 59 to 64) to be - * written into the FIFO buffer. - * @return Current accelerometer FIFO enabled value - * @see MPU6050_RA_FIFO_EN - */ -bool MPU6050::getAccelFIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_ACCEL_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set accelerometer FIFO enabled value. - * @param enabled New accelerometer FIFO enabled value - * @see getAccelFIFOEnabled() - * @see MPU6050_RA_FIFO_EN - */ -void MPU6050::setAccelFIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_ACCEL_FIFO_EN_BIT), enabled); -} -/** Get Slave 2 FIFO enabled value. - * When set to 1, this bit enables EXT_SENS_DATA registers (Registers 73 to 96) - * associated with Slave 2 to be written into the FIFO buffer. - * @return Current Slave 2 FIFO enabled value - * @see MPU6050_RA_FIFO_EN - */ -bool MPU6050::getSlave2FIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_SLV2_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set Slave 2 FIFO enabled value. - * @param enabled New Slave 2 FIFO enabled value - * @see getSlave2FIFOEnabled() - * @see MPU6050_RA_FIFO_EN - */ -void MPU6050::setSlave2FIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_SLV2_FIFO_EN_BIT), enabled); -} -/** Get Slave 1 FIFO enabled value. - * When set to 1, this bit enables EXT_SENS_DATA registers (Registers 73 to 96) - * associated with Slave 1 to be written into the FIFO buffer. - * @return Current Slave 1 FIFO enabled value - * @see MPU6050_RA_FIFO_EN - */ -bool MPU6050::getSlave1FIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_SLV1_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set Slave 1 FIFO enabled value. - * @param enabled New Slave 1 FIFO enabled value - * @see getSlave1FIFOEnabled() - * @see MPU6050_RA_FIFO_EN - */ -void MPU6050::setSlave1FIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_SLV1_FIFO_EN_BIT), enabled); -} -/** Get Slave 0 FIFO enabled value. - * When set to 1, this bit enables EXT_SENS_DATA registers (Registers 73 to 96) - * associated with Slave 0 to be written into the FIFO buffer. - * @return Current Slave 0 FIFO enabled value - * @see MPU6050_RA_FIFO_EN - */ -bool MPU6050::getSlave0FIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_SLV0_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set Slave 0 FIFO enabled value. - * @param enabled New Slave 0 FIFO enabled value - * @see getSlave0FIFOEnabled() - * @see MPU6050_RA_FIFO_EN - */ -void MPU6050::setSlave0FIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_EN), (MPU6050_IMU::MPU6050_SLV0_FIFO_EN_BIT), enabled); -} - -// I2C_MST_CTRL register - -/** Get multi-master enabled value. - * Multi-master capability allows multiple I2C masters to operate on the same - * bus. In circuits where multi-master capability is required, set MULT_MST_EN - * to 1. This will increase current drawn by approximately 30uA. - * - * In circuits where multi-master capability is required, the state of the I2C - * bus must always be monitored by each separate I2C Master. Before an I2C - * Master can assume arbitration of the bus, it must first confirm that no other - * I2C Master has arbitration of the bus. When MULT_MST_EN is set to 1, the - * MPU-60X0's bus arbitration detection logic is turned on, enabling it to - * detect when the bus is available. - * - * @return Current multi-master enabled value - * @see MPU6050_RA_I2C_MST_CTRL - */ -bool MPU6050::getMultiMasterEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_MULT_MST_EN_BIT), buffer); - return buffer[0]; -} -/** Set multi-master enabled value. - * @param enabled New multi-master enabled value - * @see getMultiMasterEnabled() - * @see MPU6050_RA_I2C_MST_CTRL - */ -void MPU6050::setMultiMasterEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_MULT_MST_EN_BIT), enabled); -} -/** Get wait-for-external-sensor-data enabled value. - * When the WAIT_FOR_ES bit is set to 1, the Data Ready interrupt will be - * delayed until External Sensor data from the Slave Devices are loaded into the - * EXT_SENS_DATA registers. This is used to ensure that both the internal sensor - * data (i.e. from gyro and accel) and external sensor data have been loaded to - * their respective data registers (i.e. the data is synced) when the Data Ready - * interrupt is triggered. - * - * @return Current wait-for-external-sensor-data enabled value - * @see MPU6050_RA_I2C_MST_CTRL - */ -bool MPU6050::getWaitForExternalSensorEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_WAIT_FOR_ES_BIT), buffer); - return buffer[0]; -} -/** Set wait-for-external-sensor-data enabled value. - * @param enabled New wait-for-external-sensor-data enabled value - * @see getWaitForExternalSensorEnabled() - * @see MPU6050_RA_I2C_MST_CTRL - */ -void MPU6050::setWaitForExternalSensorEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_WAIT_FOR_ES_BIT), enabled); -} -/** Get Slave 3 FIFO enabled value. - * When set to 1, this bit enables EXT_SENS_DATA registers (Registers 73 to 96) - * associated with Slave 3 to be written into the FIFO buffer. - * @return Current Slave 3 FIFO enabled value - * @see MPU6050_RA_MST_CTRL - */ -bool MPU6050::getSlave3FIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_SLV_3_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set Slave 3 FIFO enabled value. - * @param enabled New Slave 3 FIFO enabled value - * @see getSlave3FIFOEnabled() - * @see MPU6050_RA_MST_CTRL - */ -void MPU6050::setSlave3FIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_SLV_3_FIFO_EN_BIT), enabled); -} -/** Get slave read/write transition enabled value. - * The I2C_MST_P_NSR bit configures the I2C Master's transition from one slave - * read to the next slave read. If the bit equals 0, there will be a restart - * between reads. If the bit equals 1, there will be a stop followed by a start - * of the following read. When a write transaction follows a read transaction, - * the stop followed by a start of the successive write will be always used. - * - * @return Current slave read/write transition enabled value - * @see MPU6050_RA_I2C_MST_CTRL - */ -bool MPU6050::getSlaveReadWriteTransitionEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_I2C_MST_P_NSR_BIT), buffer); - return buffer[0]; -} -/** Set slave read/write transition enabled value. - * @param enabled New slave read/write transition enabled value - * @see getSlaveReadWriteTransitionEnabled() - * @see MPU6050_RA_I2C_MST_CTRL - */ -void MPU6050::setSlaveReadWriteTransitionEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_I2C_MST_P_NSR_BIT), enabled); -} -/** Get I2C master clock speed. - * I2C_MST_CLK is a 4 bit unsigned value which configures a divider on the - * MPU-60X0 internal 8MHz clock. It sets the I2C master clock speed according to - * the following table: - * - * <pre> - * I2C_MST_CLK | I2C Master Clock Speed | 8MHz Clock Divider - * ------------+------------------------+------------------- - * 0 | 348kHz | 23 - * 1 | 333kHz | 24 - * 2 | 320kHz | 25 - * 3 | 308kHz | 26 - * 4 | 296kHz | 27 - * 5 | 286kHz | 28 - * 6 | 276kHz | 29 - * 7 | 267kHz | 30 - * 8 | 258kHz | 31 - * 9 | 500kHz | 16 - * 10 | 471kHz | 17 - * 11 | 444kHz | 18 - * 12 | 421kHz | 19 - * 13 | 400kHz | 20 - * 14 | 381kHz | 21 - * 15 | 364kHz | 22 - * </pre> - * - * @return Current I2C master clock speed - * @see MPU6050_RA_I2C_MST_CTRL - */ -uint8_t MPU6050::getMasterClockSpeed() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_I2C_MST_CLK_BIT), (MPU6050_IMU::MPU6050_I2C_MST_CLK_LENGTH), buffer); - return buffer[0]; -} -/** Set I2C master clock speed. - * @reparam speed Current I2C master clock speed - * @see MPU6050_RA_I2C_MST_CTRL - */ -void MPU6050::setMasterClockSpeed(uint8_t speed) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_CTRL), (MPU6050_IMU::MPU6050_I2C_MST_CLK_BIT), (MPU6050_IMU::MPU6050_I2C_MST_CLK_LENGTH), speed); -} - -// I2C_SLV* registers (Slave 0-3) - -/** Get the I2C address of the specified slave (0-3). - * Note that Bit 7 (MSB) controls read/write mode. If Bit 7 is set, it's a read - * operation, and if it is cleared, then it's a write operation. The remaining - * bits (6-0) are the 7-bit device address of the slave device. - * - * In read mode, the result of the read is placed in the lowest available - * EXT_SENS_DATA register. For further information regarding the allocation of - * read results, please refer to the EXT_SENS_DATA register description - * (Registers 73 - 96). - * - * The MPU-6050 supports a total of five slaves, but Slave 4 has unique - * characteristics, and so it has its own functions (getSlave4* and setSlave4*). - * - * I2C data transactions are performed at the Sample Rate, as defined in - * Register 25. The user is responsible for ensuring that I2C data transactions - * to and from each enabled Slave can be completed within a single period of the - * Sample Rate. - * - * The I2C slave access rate can be reduced relative to the Sample Rate. This - * reduced access rate is determined by I2C_MST_DLY (Register 52). Whether a - * slave's access rate is reduced relative to the Sample Rate is determined by - * I2C_MST_DELAY_CTRL (Register 103). - * - * The processing order for the slaves is fixed. The sequence followed for - * processing the slaves is Slave 0, Slave 1, Slave 2, Slave 3 and Slave 4. If a - * particular Slave is disabled it will be skipped. - * - * Each slave can either be accessed at the sample rate or at a reduced sample - * rate. In a case where some slaves are accessed at the Sample Rate and some - * slaves are accessed at the reduced rate, the sequence of accessing the slaves - * (Slave 0 to Slave 4) is still followed. However, the reduced rate slaves will - * be skipped if their access rate dictates that they should not be accessed - * during that particular cycle. For further information regarding the reduced - * access rate, please refer to Register 52. Whether a slave is accessed at the - * Sample Rate or at the reduced rate is determined by the Delay Enable bits in - * Register 103. - * - * @param num Slave number (0-3) - * @return Current address for specified slave - * @see MPU6050_RA_I2C_SLV0_ADDR - */ -uint8_t MPU6050::getSlaveAddress(uint8_t num) { - if (num > 3) return 0; - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_ADDR) + num*3, buffer); - return buffer[0]; -} -/** Set the I2C address of the specified slave (0-3). - * @param num Slave number (0-3) - * @param address New address for specified slave - * @see getSlaveAddress() - * @see MPU6050_RA_I2C_SLV0_ADDR - */ -void MPU6050::setSlaveAddress(uint8_t num, uint8_t address) { - if (num > 3) return; - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_ADDR) + num*3, address); -} -/** Get the active internal register for the specified slave (0-3). - * Read/write operations for this slave will be done to whatever internal - * register address is stored in this MPU register. - * - * The MPU-6050 supports a total of five slaves, but Slave 4 has unique - * characteristics, and so it has its own functions. - * - * @param num Slave number (0-3) - * @return Current active register for specified slave - * @see MPU6050_RA_I2C_SLV0_REG - */ -uint8_t MPU6050::getSlaveRegister(uint8_t num) { - if (num > 3) return 0; - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_REG) + num*3, buffer); - return buffer[0]; -} -/** Set the active internal register for the specified slave (0-3). - * @param num Slave number (0-3) - * @param reg New active register for specified slave - * @see getSlaveRegister() - * @see MPU6050_RA_I2C_SLV0_REG - */ -void MPU6050::setSlaveRegister(uint8_t num, uint8_t reg) { - if (num > 3) return; - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_REG) + num*3, reg); -} -/** Get the enabled value for the specified slave (0-3). - * When set to 1, this bit enables Slave 0 for data transfer operations. When - * cleared to 0, this bit disables Slave 0 from data transfer operations. - * @param num Slave number (0-3) - * @return Current enabled value for specified slave - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -bool MPU6050::getSlaveEnabled(uint8_t num) { - if (num > 3) return 0; - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_EN_BIT), buffer); - return buffer[0]; -} -/** Set the enabled value for the specified slave (0-3). - * @param num Slave number (0-3) - * @param enabled New enabled value for specified slave - * @see getSlaveEnabled() - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -void MPU6050::setSlaveEnabled(uint8_t num, bool enabled) { - if (num > 3) return; - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_EN_BIT), enabled); -} -/** Get word pair byte-swapping enabled for the specified slave (0-3). - * When set to 1, this bit enables byte swapping. When byte swapping is enabled, - * the high and low bytes of a word pair are swapped. Please refer to - * I2C_SLV0_GRP for the pairing convention of the word pairs. When cleared to 0, - * bytes transferred to and from Slave 0 will be written to EXT_SENS_DATA - * registers in the order they were transferred. - * - * @param num Slave number (0-3) - * @return Current word pair byte-swapping enabled value for specified slave - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -bool MPU6050::getSlaveWordByteSwap(uint8_t num) { - if (num > 3) return 0; - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_BYTE_SW_BIT), buffer); - return buffer[0]; -} -/** Set word pair byte-swapping enabled for the specified slave (0-3). - * @param num Slave number (0-3) - * @param enabled New word pair byte-swapping enabled value for specified slave - * @see getSlaveWordByteSwap() - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -void MPU6050::setSlaveWordByteSwap(uint8_t num, bool enabled) { - if (num > 3) return; - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_BYTE_SW_BIT), enabled); -} -/** Get write mode for the specified slave (0-3). - * When set to 1, the transaction will read or write data only. When cleared to - * 0, the transaction will write a register address prior to reading or writing - * data. This should equal 0 when specifying the register address within the - * Slave device to/from which the ensuing data transaction will take place. - * - * @param num Slave number (0-3) - * @return Current write mode for specified slave (0 = register address + data, 1 = data only) - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -bool MPU6050::getSlaveWriteMode(uint8_t num) { - if (num > 3) return 0; - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_REG_DIS_BIT), buffer); - return buffer[0]; -} -/** Set write mode for the specified slave (0-3). - * @param num Slave number (0-3) - * @param mode New write mode for specified slave (0 = register address + data, 1 = data only) - * @see getSlaveWriteMode() - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -void MPU6050::setSlaveWriteMode(uint8_t num, bool mode) { - if (num > 3) return; - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_REG_DIS_BIT), mode); -} -/** Get word pair grouping order offset for the specified slave (0-3). - * This sets specifies the grouping order of word pairs received from registers. - * When cleared to 0, bytes from register addresses 0 and 1, 2 and 3, etc (even, - * then odd register addresses) are paired to form a word. When set to 1, bytes - * from register addresses are paired 1 and 2, 3 and 4, etc. (odd, then even - * register addresses) are paired to form a word. - * - * @param num Slave number (0-3) - * @return Current word pair grouping order offset for specified slave - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -bool MPU6050::getSlaveWordGroupOffset(uint8_t num) { - if (num > 3) return 0; - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_GRP_BIT), buffer); - return buffer[0]; -} -/** Set word pair grouping order offset for the specified slave (0-3). - * @param num Slave number (0-3) - * @param enabled New word pair grouping order offset for specified slave - * @see getSlaveWordGroupOffset() - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -void MPU6050::setSlaveWordGroupOffset(uint8_t num, bool enabled) { - if (num > 3) return; - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_GRP_BIT), enabled); -} -/** Get number of bytes to read for the specified slave (0-3). - * Specifies the number of bytes transferred to and from Slave 0. Clearing this - * bit to 0 is equivalent to disabling the register by writing 0 to I2C_SLV0_EN. - * @param num Slave number (0-3) - * @return Number of bytes to read for specified slave - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -uint8_t MPU6050::getSlaveDataLength(uint8_t num) { - if (num > 3) return 0; - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_LEN_BIT), (MPU6050_IMU::MPU6050_I2C_SLV_LEN_LENGTH), buffer); - return buffer[0]; -} -/** Set number of bytes to read for the specified slave (0-3). - * @param num Slave number (0-3) - * @param length Number of bytes to read for specified slave - * @see getSlaveDataLength() - * @see MPU6050_RA_I2C_SLV0_CTRL - */ -void MPU6050::setSlaveDataLength(uint8_t num, uint8_t length) { - if (num > 3) return; - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_CTRL) + num*3, (MPU6050_IMU::MPU6050_I2C_SLV_LEN_BIT), (MPU6050_IMU::MPU6050_I2C_SLV_LEN_LENGTH), length); -} - -// I2C_SLV* registers (Slave 4) - -/** Get the I2C address of Slave 4. - * Note that Bit 7 (MSB) controls read/write mode. If Bit 7 is set, it's a read - * operation, and if it is cleared, then it's a write operation. The remaining - * bits (6-0) are the 7-bit device address of the slave device. - * - * @return Current address for Slave 4 - * @see getSlaveAddress() - * @see MPU6050_RA_I2C_SLV4_ADDR - */ -uint8_t MPU6050::getSlave4Address() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_ADDR), buffer); - return buffer[0]; -} -/** Set the I2C address of Slave 4. - * @param address New address for Slave 4 - * @see getSlave4Address() - * @see MPU6050_RA_I2C_SLV4_ADDR - */ -void MPU6050::setSlave4Address(uint8_t address) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_ADDR), address); -} -/** Get the active internal register for the Slave 4. - * Read/write operations for this slave will be done to whatever internal - * register address is stored in this MPU register. - * - * @return Current active register for Slave 4 - * @see MPU6050_RA_I2C_SLV4_REG - */ -uint8_t MPU6050::getSlave4Register() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_REG), buffer); - return buffer[0]; -} -/** Set the active internal register for Slave 4. - * @param reg New active register for Slave 4 - * @see getSlave4Register() - * @see MPU6050_RA_I2C_SLV4_REG - */ -void MPU6050::setSlave4Register(uint8_t reg) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_REG), reg); -} -/** Set new byte to write to Slave 4. - * This register stores the data to be written into the Slave 4. If I2C_SLV4_RW - * is set 1 (set to read), this register has no effect. - * @param data New byte to write to Slave 4 - * @see MPU6050_RA_I2C_SLV4_DO - */ -void MPU6050::setSlave4OutputByte(uint8_t data) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_DO), data); -} -/** Get the enabled value for the Slave 4. - * When set to 1, this bit enables Slave 4 for data transfer operations. When - * cleared to 0, this bit disables Slave 4 from data transfer operations. - * @return Current enabled value for Slave 4 - * @see MPU6050_RA_I2C_SLV4_CTRL - */ -bool MPU6050::getSlave4Enabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_CTRL), (MPU6050_IMU::MPU6050_I2C_SLV4_EN_BIT), buffer); - return buffer[0]; -} -/** Set the enabled value for Slave 4. - * @param enabled New enabled value for Slave 4 - * @see getSlave4Enabled() - * @see MPU6050_RA_I2C_SLV4_CTRL - */ -void MPU6050::setSlave4Enabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_CTRL), (MPU6050_IMU::MPU6050_I2C_SLV4_EN_BIT), enabled); -} -/** Get the enabled value for Slave 4 transaction interrupts. - * When set to 1, this bit enables the generation of an interrupt signal upon - * completion of a Slave 4 transaction. When cleared to 0, this bit disables the - * generation of an interrupt signal upon completion of a Slave 4 transaction. - * The interrupt status can be observed in Register 54. - * - * @return Current enabled value for Slave 4 transaction interrupts. - * @see MPU6050_RA_I2C_SLV4_CTRL - */ -bool MPU6050::getSlave4InterruptEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_CTRL), (MPU6050_IMU::MPU6050_I2C_SLV4_INT_EN_BIT), buffer); - return buffer[0]; -} -/** Set the enabled value for Slave 4 transaction interrupts. - * @param enabled New enabled value for Slave 4 transaction interrupts. - * @see getSlave4InterruptEnabled() - * @see MPU6050_RA_I2C_SLV4_CTRL - */ -void MPU6050::setSlave4InterruptEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_CTRL), (MPU6050_IMU::MPU6050_I2C_SLV4_INT_EN_BIT), enabled); -} -/** Get write mode for Slave 4. - * When set to 1, the transaction will read or write data only. When cleared to - * 0, the transaction will write a register address prior to reading or writing - * data. This should equal 0 when specifying the register address within the - * Slave device to/from which the ensuing data transaction will take place. - * - * @return Current write mode for Slave 4 (0 = register address + data, 1 = data only) - * @see MPU6050_RA_I2C_SLV4_CTRL - */ -bool MPU6050::getSlave4WriteMode() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_CTRL), (MPU6050_IMU::MPU6050_I2C_SLV4_REG_DIS_BIT), buffer); - return buffer[0]; -} -/** Set write mode for the Slave 4. - * @param mode New write mode for Slave 4 (0 = register address + data, 1 = data only) - * @see getSlave4WriteMode() - * @see MPU6050_RA_I2C_SLV4_CTRL - */ -void MPU6050::setSlave4WriteMode(bool mode) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_CTRL), (MPU6050_IMU::MPU6050_I2C_SLV4_REG_DIS_BIT), mode); -} -/** Get Slave 4 master delay value. - * This configures the reduced access rate of I2C slaves relative to the Sample - * Rate. When a slave's access rate is decreased relative to the Sample Rate, - * the slave is accessed every: - * - * 1 / (1 + I2C_MST_DLY) samples - * - * This base Sample Rate in turn is determined by SMPLRT_DIV (register 25) and - * DLPF_CFG (register 26). Whether a slave's access rate is reduced relative to - * the Sample Rate is determined by I2C_MST_DELAY_CTRL (register 103). For - * further information regarding the Sample Rate, please refer to register 25. - * - * @return Current Slave 4 master delay value - * @see MPU6050_RA_I2C_SLV4_CTRL - */ -uint8_t MPU6050::getSlave4MasterDelay() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_CTRL), (MPU6050_IMU::MPU6050_I2C_SLV4_MST_DLY_BIT), (MPU6050_IMU::MPU6050_I2C_SLV4_MST_DLY_LENGTH), buffer); - return buffer[0]; -} -/** Set Slave 4 master delay value. - * @param delay New Slave 4 master delay value - * @see getSlave4MasterDelay() - * @see MPU6050_RA_I2C_SLV4_CTRL - */ -void MPU6050::setSlave4MasterDelay(uint8_t delay) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_CTRL), (MPU6050_IMU::MPU6050_I2C_SLV4_MST_DLY_BIT), (MPU6050_IMU::MPU6050_I2C_SLV4_MST_DLY_LENGTH), delay); -} -/** Get last available byte read from Slave 4. - * This register stores the data read from Slave 4. This field is populated - * after a read transaction. - * @return Last available byte read from to Slave 4 - * @see MPU6050_RA_I2C_SLV4_DI - */ -uint8_t MPU6050::getSlate4InputByte() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV4_DI), buffer); - return buffer[0]; -} - -// I2C_MST_STATUS register - -/** Get FSYNC interrupt status. - * This bit reflects the status of the FSYNC interrupt from an external device - * into the MPU-60X0. This is used as a way to pass an external interrupt - * through the MPU-60X0 to the host application processor. When set to 1, this - * bit will cause an interrupt if FSYNC_INT_EN is asserted in INT_PIN_CFG - * (Register 55). - * @return FSYNC interrupt status - * @see MPU6050_RA_I2C_MST_STATUS - */ -bool MPU6050::getPassthroughStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_STATUS), (MPU6050_IMU::MPU6050_MST_PASS_THROUGH_BIT), buffer); - return buffer[0]; -} -/** Get Slave 4 transaction done status. - * Automatically sets to 1 when a Slave 4 transaction has completed. This - * triggers an interrupt if the I2C_MST_INT_EN bit in the INT_ENABLE register - * (Register 56) is asserted and if the SLV_4_DONE_INT bit is asserted in the - * I2C_SLV4_CTRL register (Register 52). - * @return Slave 4 transaction done status - * @see MPU6050_RA_I2C_MST_STATUS - */ -bool MPU6050::getSlave4IsDone() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_STATUS), (MPU6050_IMU::MPU6050_MST_I2C_SLV4_DONE_BIT), buffer); - return buffer[0]; -} -/** Get master arbitration lost status. - * This bit automatically sets to 1 when the I2C Master has lost arbitration of - * the auxiliary I2C bus (an error condition). This triggers an interrupt if the - * I2C_MST_INT_EN bit in the INT_ENABLE register (Register 56) is asserted. - * @return Master arbitration lost status - * @see MPU6050_RA_I2C_MST_STATUS - */ -bool MPU6050::getLostArbitration() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_STATUS), (MPU6050_IMU::MPU6050_MST_I2C_LOST_ARB_BIT), buffer); - return buffer[0]; -} -/** Get Slave 4 NACK status. - * This bit automatically sets to 1 when the I2C Master receives a NACK in a - * transaction with Slave 4. This triggers an interrupt if the I2C_MST_INT_EN - * bit in the INT_ENABLE register (Register 56) is asserted. - * @return Slave 4 NACK interrupt status - * @see MPU6050_RA_I2C_MST_STATUS - */ -bool MPU6050::getSlave4Nack() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_STATUS), (MPU6050_IMU::MPU6050_MST_I2C_SLV4_NACK_BIT), buffer); - return buffer[0]; -} -/** Get Slave 3 NACK status. - * This bit automatically sets to 1 when the I2C Master receives a NACK in a - * transaction with Slave 3. This triggers an interrupt if the I2C_MST_INT_EN - * bit in the INT_ENABLE register (Register 56) is asserted. - * @return Slave 3 NACK interrupt status - * @see MPU6050_RA_I2C_MST_STATUS - */ -bool MPU6050::getSlave3Nack() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_STATUS), (MPU6050_IMU::MPU6050_MST_I2C_SLV3_NACK_BIT), buffer); - return buffer[0]; -} -/** Get Slave 2 NACK status. - * This bit automatically sets to 1 when the I2C Master receives a NACK in a - * transaction with Slave 2. This triggers an interrupt if the I2C_MST_INT_EN - * bit in the INT_ENABLE register (Register 56) is asserted. - * @return Slave 2 NACK interrupt status - * @see MPU6050_RA_I2C_MST_STATUS - */ -bool MPU6050::getSlave2Nack() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_STATUS), (MPU6050_IMU::MPU6050_MST_I2C_SLV2_NACK_BIT), buffer); - return buffer[0]; -} -/** Get Slave 1 NACK status. - * This bit automatically sets to 1 when the I2C Master receives a NACK in a - * transaction with Slave 1. This triggers an interrupt if the I2C_MST_INT_EN - * bit in the INT_ENABLE register (Register 56) is asserted. - * @return Slave 1 NACK interrupt status - * @see MPU6050_RA_I2C_MST_STATUS - */ -bool MPU6050::getSlave1Nack() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_STATUS), (MPU6050_IMU::MPU6050_MST_I2C_SLV1_NACK_BIT), buffer); - return buffer[0]; -} -/** Get Slave 0 NACK status. - * This bit automatically sets to 1 when the I2C Master receives a NACK in a - * transaction with Slave 0. This triggers an interrupt if the I2C_MST_INT_EN - * bit in the INT_ENABLE register (Register 56) is asserted. - * @return Slave 0 NACK interrupt status - * @see MPU6050_RA_I2C_MST_STATUS - */ -bool MPU6050::getSlave0Nack() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_STATUS), (MPU6050_IMU::MPU6050_MST_I2C_SLV0_NACK_BIT), buffer); - return buffer[0]; -} - -// INT_PIN_CFG register - -/** Get interrupt logic level mode. - * Will be set 0 for active-high, 1 for active-low. - * @return Current interrupt mode (0=active-high, 1=active-low) - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_INT_LEVEL_BIT - */ -bool MPU6050::getInterruptMode() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_INT_LEVEL_BIT), buffer); - return buffer[0]; -} -/** Set interrupt logic level mode. - * @param mode New interrupt mode (0=active-high, 1=active-low) - * @see getInterruptMode() - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_INT_LEVEL_BIT - */ -void MPU6050::setInterruptMode(bool mode) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_INT_LEVEL_BIT), mode); -} -/** Get interrupt drive mode. - * Will be set 0 for push-pull, 1 for open-drain. - * @return Current interrupt drive mode (0=push-pull, 1=open-drain) - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_INT_OPEN_BIT - */ -bool MPU6050::getInterruptDrive() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_INT_OPEN_BIT), buffer); - return buffer[0]; -} -/** Set interrupt drive mode. - * @param drive New interrupt drive mode (0=push-pull, 1=open-drain) - * @see getInterruptDrive() - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_INT_OPEN_BIT - */ -void MPU6050::setInterruptDrive(bool drive) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_INT_OPEN_BIT), drive); -} -/** Get interrupt latch mode. - * Will be set 0 for 50us-pulse, 1 for latch-until-int-cleared. - * @return Current latch mode (0=50us-pulse, 1=latch-until-int-cleared) - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_LATCH_INT_EN_BIT - */ -bool MPU6050::getInterruptLatch() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_LATCH_INT_EN_BIT), buffer); - return buffer[0]; -} -/** Set interrupt latch mode. - * @param latch New latch mode (0=50us-pulse, 1=latch-until-int-cleared) - * @see getInterruptLatch() - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_LATCH_INT_EN_BIT - */ -void MPU6050::setInterruptLatch(bool latch) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_LATCH_INT_EN_BIT), latch); -} -/** Get interrupt latch clear mode. - * Will be set 0 for status-read-only, 1 for any-register-read. - * @return Current latch clear mode (0=status-read-only, 1=any-register-read) - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_INT_RD_CLEAR_BIT - */ -bool MPU6050::getInterruptLatchClear() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_INT_RD_CLEAR_BIT), buffer); - return buffer[0]; -} -/** Set interrupt latch clear mode. - * @param clear New latch clear mode (0=status-read-only, 1=any-register-read) - * @see getInterruptLatchClear() - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_INT_RD_CLEAR_BIT - */ -void MPU6050::setInterruptLatchClear(bool clear) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_INT_RD_CLEAR_BIT), clear); -} -/** Get FSYNC interrupt logic level mode. - * @return Current FSYNC interrupt mode (0=active-high, 1=active-low) - * @see getFSyncInterruptMode() - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT - */ -bool MPU6050::getFSyncInterruptLevel() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT), buffer); - return buffer[0]; -} -/** Set FSYNC interrupt logic level mode. - * @param mode New FSYNC interrupt mode (0=active-high, 1=active-low) - * @see getFSyncInterruptMode() - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT - */ -void MPU6050::setFSyncInterruptLevel(bool level) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT), level); -} -/** Get FSYNC pin interrupt enabled setting. - * Will be set 0 for disabled, 1 for enabled. - * @return Current interrupt enabled setting - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_FSYNC_INT_EN_BIT - */ -bool MPU6050::getFSyncInterruptEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_FSYNC_INT_EN_BIT), buffer); - return buffer[0]; -} -/** Set FSYNC pin interrupt enabled setting. - * @param enabled New FSYNC pin interrupt enabled setting - * @see getFSyncInterruptEnabled() - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_FSYNC_INT_EN_BIT - */ -void MPU6050::setFSyncInterruptEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_FSYNC_INT_EN_BIT), enabled); -} -/** Get I2C bypass enabled status. - * When this bit is equal to 1 and I2C_MST_EN (Register 106 bit[5]) is equal to - * 0, the host application processor will be able to directly access the - * auxiliary I2C bus of the MPU-60X0. When this bit is equal to 0, the host - * application processor will not be able to directly access the auxiliary I2C - * bus of the MPU-60X0 regardless of the state of I2C_MST_EN (Register 106 - * bit[5]). - * @return Current I2C bypass enabled status - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_I2C_BYPASS_EN_BIT - */ -bool MPU6050::getI2CBypassEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_I2C_BYPASS_EN_BIT), buffer); - return buffer[0]; -} -/** Set I2C bypass enabled status. - * When this bit is equal to 1 and I2C_MST_EN (Register 106 bit[5]) is equal to - * 0, the host application processor will be able to directly access the - * auxiliary I2C bus of the MPU-60X0. When this bit is equal to 0, the host - * application processor will not be able to directly access the auxiliary I2C - * bus of the MPU-60X0 regardless of the state of I2C_MST_EN (Register 106 - * bit[5]). - * @param enabled New I2C bypass enabled status - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_I2C_BYPASS_EN_BIT - */ -void MPU6050::setI2CBypassEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_I2C_BYPASS_EN_BIT), enabled); -} -/** Get reference clock output enabled status. - * When this bit is equal to 1, a reference clock output is provided at the - * CLKOUT pin. When this bit is equal to 0, the clock output is disabled. For - * further information regarding CLKOUT, please refer to the MPU-60X0 Product - * Specification document. - * @return Current reference clock output enabled status - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_CLKOUT_EN_BIT - */ -bool MPU6050::getClockOutputEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_CLKOUT_EN_BIT), buffer); - return buffer[0]; -} -/** Set reference clock output enabled status. - * When this bit is equal to 1, a reference clock output is provided at the - * CLKOUT pin. When this bit is equal to 0, the clock output is disabled. For - * further information regarding CLKOUT, please refer to the MPU-60X0 Product - * Specification document. - * @param enabled New reference clock output enabled status - * @see MPU6050_RA_INT_PIN_CFG - * @see MPU6050_INTCFG_CLKOUT_EN_BIT - */ -void MPU6050::setClockOutputEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_PIN_CFG), (MPU6050_IMU::MPU6050_INTCFG_CLKOUT_EN_BIT), enabled); -} - -// INT_ENABLE register - -/** Get full interrupt enabled status. - * Full register byte for all interrupts, for quick reading. Each bit will be - * set 0 for disabled, 1 for enabled. - * @return Current interrupt enabled status - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_FF_BIT - **/ -uint8_t MPU6050::getIntEnabled() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), buffer); - return buffer[0]; -} -/** Set full interrupt enabled status. - * Full register byte for all interrupts, for quick reading. Each bit should be - * set 0 for disabled, 1 for enabled. - * @param enabled New interrupt enabled status - * @see getIntFreefallEnabled() - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_FF_BIT - **/ -void MPU6050::setIntEnabled(uint8_t enabled) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), enabled); -} -/** Get Free Fall interrupt enabled status. - * Will be set 0 for disabled, 1 for enabled. - * @return Current interrupt enabled status - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_FF_BIT - **/ -bool MPU6050::getIntFreefallEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_FF_BIT), buffer); - return buffer[0]; -} -/** Set Free Fall interrupt enabled status. - * @param enabled New interrupt enabled status - * @see getIntFreefallEnabled() - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_FF_BIT - **/ -void MPU6050::setIntFreefallEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_FF_BIT), enabled); -} -/** Get Motion Detection interrupt enabled status. - * Will be set 0 for disabled, 1 for enabled. - * @return Current interrupt enabled status - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_MOT_BIT - **/ -bool MPU6050::getIntMotionEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_MOT_BIT), buffer); - return buffer[0]; -} -/** Set Motion Detection interrupt enabled status. - * @param enabled New interrupt enabled status - * @see getIntMotionEnabled() - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_MOT_BIT - **/ -void MPU6050::setIntMotionEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_MOT_BIT), enabled); -} -/** Get Zero Motion Detection interrupt enabled status. - * Will be set 0 for disabled, 1 for enabled. - * @return Current interrupt enabled status - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_ZMOT_BIT - **/ -bool MPU6050::getIntZeroMotionEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_ZMOT_BIT), buffer); - return buffer[0]; -} -/** Set Zero Motion Detection interrupt enabled status. - * @param enabled New interrupt enabled status - * @see getIntZeroMotionEnabled() - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_ZMOT_BIT - **/ -void MPU6050::setIntZeroMotionEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_ZMOT_BIT), enabled); -} -/** Get FIFO Buffer Overflow interrupt enabled status. - * Will be set 0 for disabled, 1 for enabled. - * @return Current interrupt enabled status - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_FIFO_OFLOW_BIT - **/ -bool MPU6050::getIntFIFOBufferOverflowEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_FIFO_OFLOW_BIT), buffer); - return buffer[0]; -} -/** Set FIFO Buffer Overflow interrupt enabled status. - * @param enabled New interrupt enabled status - * @see getIntFIFOBufferOverflowEnabled() - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_FIFO_OFLOW_BIT - **/ -void MPU6050::setIntFIFOBufferOverflowEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_FIFO_OFLOW_BIT), enabled); -} -/** Get I2C Master interrupt enabled status. - * This enables any of the I2C Master interrupt sources to generate an - * interrupt. Will be set 0 for disabled, 1 for enabled. - * @return Current interrupt enabled status - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_I2C_MST_INT_BIT - **/ -bool MPU6050::getIntI2CMasterEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_I2C_MST_INT_BIT), buffer); - return buffer[0]; -} -/** Set I2C Master interrupt enabled status. - * @param enabled New interrupt enabled status - * @see getIntI2CMasterEnabled() - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_I2C_MST_INT_BIT - **/ -void MPU6050::setIntI2CMasterEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_I2C_MST_INT_BIT), enabled); -} -/** Get Data Ready interrupt enabled setting. - * This event occurs each time a write operation to all of the sensor registers - * has been completed. Will be set 0 for disabled, 1 for enabled. - * @return Current interrupt enabled status - * @see MPU6050_RA_INT_ENABLE - * @see MPU6050_INTERRUPT_DATA_RDY_BIT - */ -bool MPU6050::getIntDataReadyEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_DATA_RDY_BIT), buffer); - return buffer[0]; -} -/** Set Data Ready interrupt enabled status. - * @param enabled New interrupt enabled status - * @see getIntDataReadyEnabled() - * @see MPU6050_RA_INT_CFG - * @see MPU6050_INTERRUPT_DATA_RDY_BIT - */ -void MPU6050::setIntDataReadyEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_DATA_RDY_BIT), enabled); -} - -// INT_STATUS register - -/** Get full set of interrupt status bits. - * These bits clear to 0 after the register has been read. Very useful - * for getting multiple INT statuses, since each single bit read clears - * all of them because it has to read the whole byte. - * @return Current interrupt status - * @see MPU6050_RA_INT_STATUS - */ -uint8_t MPU6050::getIntStatus() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), buffer); - return buffer[0]; -} -/** Get Free Fall interrupt status. - * This bit automatically sets to 1 when a Free Fall interrupt has been - * generated. The bit clears to 0 after the register has been read. - * @return Current interrupt status - * @see MPU6050_RA_INT_STATUS - * @see MPU6050_INTERRUPT_FF_BIT - */ -bool MPU6050::getIntFreefallStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), (MPU6050_IMU::MPU6050_INTERRUPT_FF_BIT), buffer); - return buffer[0]; -} -/** Get Motion Detection interrupt status. - * This bit automatically sets to 1 when a Motion Detection interrupt has been - * generated. The bit clears to 0 after the register has been read. - * @return Current interrupt status - * @see MPU6050_RA_INT_STATUS - * @see MPU6050_INTERRUPT_MOT_BIT - */ -bool MPU6050::getIntMotionStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), (MPU6050_IMU::MPU6050_INTERRUPT_MOT_BIT), buffer); - return buffer[0]; -} -/** Get Zero Motion Detection interrupt status. - * This bit automatically sets to 1 when a Zero Motion Detection interrupt has - * been generated. The bit clears to 0 after the register has been read. - * @return Current interrupt status - * @see MPU6050_RA_INT_STATUS - * @see MPU6050_INTERRUPT_ZMOT_BIT - */ -bool MPU6050::getIntZeroMotionStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), (MPU6050_IMU::MPU6050_INTERRUPT_ZMOT_BIT), buffer); - return buffer[0]; -} -/** Get FIFO Buffer Overflow interrupt status. - * This bit automatically sets to 1 when a Free Fall interrupt has been - * generated. The bit clears to 0 after the register has been read. - * @return Current interrupt status - * @see MPU6050_RA_INT_STATUS - * @see MPU6050_INTERRUPT_FIFO_OFLOW_BIT - */ -bool MPU6050::getIntFIFOBufferOverflowStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), (MPU6050_IMU::MPU6050_INTERRUPT_FIFO_OFLOW_BIT), buffer); - return buffer[0]; -} -/** Get I2C Master interrupt status. - * This bit automatically sets to 1 when an I2C Master interrupt has been - * generated. For a list of I2C Master interrupts, please refer to Register 54. - * The bit clears to 0 after the register has been read. - * @return Current interrupt status - * @see MPU6050_RA_INT_STATUS - * @see MPU6050_INTERRUPT_I2C_MST_INT_BIT - */ -bool MPU6050::getIntI2CMasterStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), (MPU6050_IMU::MPU6050_INTERRUPT_I2C_MST_INT_BIT), buffer); - return buffer[0]; -} -/** Get Data Ready interrupt status. - * This bit automatically sets to 1 when a Data Ready interrupt has been - * generated. The bit clears to 0 after the register has been read. - * @return Current interrupt status - * @see MPU6050_RA_INT_STATUS - * @see MPU6050_INTERRUPT_DATA_RDY_BIT - */ -bool MPU6050::getIntDataReadyStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), (MPU6050_IMU::MPU6050_INTERRUPT_DATA_RDY_BIT), buffer); - return buffer[0]; -} - -// ACCEL_*OUT_* registers - -/** Get raw 9-axis motion sensor readings (accel/gyro/compass). - * FUNCTION NOT FULLY IMPLEMENTED YET. - * @param ax 16-bit signed integer container for accelerometer X-axis value - * @param ay 16-bit signed integer container for accelerometer Y-axis value - * @param az 16-bit signed integer container for accelerometer Z-axis value - * @param gx 16-bit signed integer container for gyroscope X-axis value - * @param gy 16-bit signed integer container for gyroscope Y-axis value - * @param gz 16-bit signed integer container for gyroscope Z-axis value - * @param mx 16-bit signed integer container for magnetometer X-axis value - * @param my 16-bit signed integer container for magnetometer Y-axis value - * @param mz 16-bit signed integer container for magnetometer Z-axis value - * @see getMotion6() - * @see getAcceleration() - * @see getRotation() - * @see MPU6050_RA_ACCEL_XOUT_H - */ -void MPU6050::getMotion9(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz, int16_t* mx, int16_t* my, int16_t* mz) { - getMotion6(ax, ay, az, gx, gy, gz); - // TODO: magnetometer integration -} -/** Get raw 6-axis motion sensor readings (accel/gyro). - * Retrieves all currently available motion sensor values. - * @param ax 16-bit signed integer container for accelerometer X-axis value - * @param ay 16-bit signed integer container for accelerometer Y-axis value - * @param az 16-bit signed integer container for accelerometer Z-axis value - * @param gx 16-bit signed integer container for gyroscope X-axis value - * @param gy 16-bit signed integer container for gyroscope Y-axis value - * @param gz 16-bit signed integer container for gyroscope Z-axis value - * @see getAcceleration() - * @see getRotation() - * @see MPU6050_RA_ACCEL_XOUT_H - */ -void MPU6050::getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz) { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_XOUT_H), 14, buffer); - *ax = (((int16_t)buffer[0]) << 8) | buffer[1]; - *ay = (((int16_t)buffer[2]) << 8) | buffer[3]; - *az = (((int16_t)buffer[4]) << 8) | buffer[5]; - *gx = (((int16_t)buffer[8]) << 8) | buffer[9]; - *gy = (((int16_t)buffer[10]) << 8) | buffer[11]; - *gz = (((int16_t)buffer[12]) << 8) | buffer[13]; -} -/** Get 3-axis accelerometer readings. - * These registers store the most recent accelerometer measurements. - * Accelerometer measurements are written to these registers at the Sample Rate - * as defined in Register 25. - * - * The accelerometer measurement registers, along with the temperature - * measurement registers, gyroscope measurement registers, and external sensor - * data registers, are composed of two sets of registers: an internal register - * set and a user-facing read register set. - * - * The data within the accelerometer sensors' internal register set is always - * updated at the Sample Rate. Meanwhile, the user-facing read register set - * duplicates the internal register set's data values whenever the serial - * interface is idle. This guarantees that a burst read of sensor registers will - * read measurements from the same sampling instant. Note that if burst reads - * are not used, the user is responsible for ensuring a set of single byte reads - * correspond to a single sampling instant by checking the Data Ready interrupt. - * - * Each 16-bit accelerometer measurement has a full scale defined in ACCEL_FS - * (Register 28). For each full scale setting, the accelerometers' sensitivity - * per LSB in ACCEL_xOUT is shown in the table below: - * - * <pre> - * AFS_SEL | Full Scale Range | LSB Sensitivity - * --------+------------------+---------------- - * 0 | +/- 2g | 8192 LSB/mg - * 1 | +/- 4g | 4096 LSB/mg - * 2 | +/- 8g | 2048 LSB/mg - * 3 | +/- 16g | 1024 LSB/mg - * </pre> - * - * @param x 16-bit signed integer container for X-axis acceleration - * @param y 16-bit signed integer container for Y-axis acceleration - * @param z 16-bit signed integer container for Z-axis acceleration - * @see MPU6050_RA_GYRO_XOUT_H - */ -void MPU6050::getAcceleration(int16_t* x, int16_t* y, int16_t* z) { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_XOUT_H), 6, buffer); - *x = (((int16_t)buffer[0]) << 8) | buffer[1]; - *y = (((int16_t)buffer[2]) << 8) | buffer[3]; - *z = (((int16_t)buffer[4]) << 8) | buffer[5]; -} -/** Get X-axis accelerometer reading. - * @return X-axis acceleration measurement in 16-bit 2's complement format - * @see getMotion6() - * @see MPU6050_RA_ACCEL_XOUT_H - */ -int16_t MPU6050::getAccelerationX() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_XOUT_H), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -/** Get Y-axis accelerometer reading. - * @return Y-axis acceleration measurement in 16-bit 2's complement format - * @see getMotion6() - * @see MPU6050_RA_ACCEL_YOUT_H - */ -int16_t MPU6050::getAccelerationY() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_YOUT_H), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -/** Get Z-axis accelerometer reading. - * @return Z-axis acceleration measurement in 16-bit 2's complement format - * @see getMotion6() - * @see MPU6050_RA_ACCEL_ZOUT_H - */ -int16_t MPU6050::getAccelerationZ() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_ACCEL_ZOUT_H), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} - -// TEMP_OUT_* registers - -/** Get current internal temperature. - * @return Temperature reading in 16-bit 2's complement format - * @see MPU6050_RA_TEMP_OUT_H - */ -int16_t MPU6050::getTemperature() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_TEMP_OUT_H), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} - -// GYRO_*OUT_* registers - -/** Get 3-axis gyroscope readings. - * These gyroscope measurement registers, along with the accelerometer - * measurement registers, temperature measurement registers, and external sensor - * data registers, are composed of two sets of registers: an internal register - * set and a user-facing read register set. - * The data within the gyroscope sensors' internal register set is always - * updated at the Sample Rate. Meanwhile, the user-facing read register set - * duplicates the internal register set's data values whenever the serial - * interface is idle. This guarantees that a burst read of sensor registers will - * read measurements from the same sampling instant. Note that if burst reads - * are not used, the user is responsible for ensuring a set of single byte reads - * correspond to a single sampling instant by checking the Data Ready interrupt. - * - * Each 16-bit gyroscope measurement has a full scale defined in FS_SEL - * (Register 27). For each full scale setting, the gyroscopes' sensitivity per - * LSB in GYRO_xOUT is shown in the table below: - * - * <pre> - * FS_SEL | Full Scale Range | LSB Sensitivity - * -------+--------------------+---------------- - * 0 | +/- 250 degrees/s | 131 LSB/deg/s - * 1 | +/- 500 degrees/s | 65.5 LSB/deg/s - * 2 | +/- 1000 degrees/s | 32.8 LSB/deg/s - * 3 | +/- 2000 degrees/s | 16.4 LSB/deg/s - * </pre> - * - * @param x 16-bit signed integer container for X-axis rotation - * @param y 16-bit signed integer container for Y-axis rotation - * @param z 16-bit signed integer container for Z-axis rotation - * @see getMotion6() - * @see MPU6050_RA_GYRO_XOUT_H - */ -void MPU6050::getRotation(int16_t* x, int16_t* y, int16_t* z) { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_GYRO_XOUT_H), 6, buffer); - *x = (((int16_t)buffer[0]) << 8) | buffer[1]; - *y = (((int16_t)buffer[2]) << 8) | buffer[3]; - *z = (((int16_t)buffer[4]) << 8) | buffer[5]; -} -/** Get X-axis gyroscope reading. - * @return X-axis rotation measurement in 16-bit 2's complement format - * @see getMotion6() - * @see MPU6050_RA_GYRO_XOUT_H - */ -int16_t MPU6050::getRotationX() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_GYRO_XOUT_H), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -/** Get Y-axis gyroscope reading. - * @return Y-axis rotation measurement in 16-bit 2's complement format - * @see getMotion6() - * @see MPU6050_RA_GYRO_YOUT_H - */ -int16_t MPU6050::getRotationY() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_GYRO_YOUT_H), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -/** Get Z-axis gyroscope reading. - * @return Z-axis rotation measurement in 16-bit 2's complement format - * @see getMotion6() - * @see MPU6050_RA_GYRO_ZOUT_H - */ -int16_t MPU6050::getRotationZ() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_GYRO_ZOUT_H), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} - -// EXT_SENS_DATA_* registers - -/** Read single byte from external sensor data register. - * These registers store data read from external sensors by the Slave 0, 1, 2, - * and 3 on the auxiliary I2C interface. Data read by Slave 4 is stored in - * I2C_SLV4_DI (Register 53). - * - * External sensor data is written to these registers at the Sample Rate as - * defined in Register 25. This access rate can be reduced by using the Slave - * Delay Enable registers (Register 103). - * - * External sensor data registers, along with the gyroscope measurement - * registers, accelerometer measurement registers, and temperature measurement - * registers, are composed of two sets of registers: an internal register set - * and a user-facing read register set. - * - * The data within the external sensors' internal register set is always updated - * at the Sample Rate (or the reduced access rate) whenever the serial interface - * is idle. This guarantees that a burst read of sensor registers will read - * measurements from the same sampling instant. Note that if burst reads are not - * used, the user is responsible for ensuring a set of single byte reads - * correspond to a single sampling instant by checking the Data Ready interrupt. - * - * Data is placed in these external sensor data registers according to - * I2C_SLV0_CTRL, I2C_SLV1_CTRL, I2C_SLV2_CTRL, and I2C_SLV3_CTRL (Registers 39, - * 42, 45, and 48). When more than zero bytes are read (I2C_SLVx_LEN > 0) from - * an enabled slave (I2C_SLVx_EN = 1), the slave is read at the Sample Rate (as - * defined in Register 25) or delayed rate (if specified in Register 52 and - * 103). During each Sample cycle, slave reads are performed in order of Slave - * number. If all slaves are enabled with more than zero bytes to be read, the - * order will be Slave 0, followed by Slave 1, Slave 2, and Slave 3. - * - * Each enabled slave will have EXT_SENS_DATA registers associated with it by - * number of bytes read (I2C_SLVx_LEN) in order of slave number, starting from - * EXT_SENS_DATA_00. Note that this means enabling or disabling a slave may - * change the higher numbered slaves' associated registers. Furthermore, if - * fewer total bytes are being read from the external sensors as a result of - * such a change, then the data remaining in the registers which no longer have - * an associated slave device (i.e. high numbered registers) will remain in - * these previously allocated registers unless reset. - * - * If the sum of the read lengths of all SLVx transactions exceed the number of - * available EXT_SENS_DATA registers, the excess bytes will be dropped. There - * are 24 EXT_SENS_DATA registers and hence the total read lengths between all - * the slaves cannot be greater than 24 or some bytes will be lost. - * - * Note: Slave 4's behavior is distinct from that of Slaves 0-3. For further - * information regarding the characteristics of Slave 4, please refer to - * Registers 49 to 53. - * - * EXAMPLE: - * Suppose that Slave 0 is enabled with 4 bytes to be read (I2C_SLV0_EN = 1 and - * I2C_SLV0_LEN = 4) while Slave 1 is enabled with 2 bytes to be read so that - * I2C_SLV1_EN = 1 and I2C_SLV1_LEN = 2. In such a situation, EXT_SENS_DATA _00 - * through _03 will be associated with Slave 0, while EXT_SENS_DATA _04 and 05 - * will be associated with Slave 1. If Slave 2 is enabled as well, registers - * starting from EXT_SENS_DATA_06 will be allocated to Slave 2. - * - * If Slave 2 is disabled while Slave 3 is enabled in this same situation, then - * registers starting from EXT_SENS_DATA_06 will be allocated to Slave 3 - * instead. - * - * REGISTER ALLOCATION FOR DYNAMIC DISABLE VS. NORMAL DISABLE: - * If a slave is disabled at any time, the space initially allocated to the - * slave in the EXT_SENS_DATA register, will remain associated with that slave. - * This is to avoid dynamic adjustment of the register allocation. - * - * The allocation of the EXT_SENS_DATA registers is recomputed only when (1) all - * slaves are disabled, or (2) the I2C_MST_RST bit is set (Register 106). - * - * This above is also true if one of the slaves gets NACKed and stops - * functioning. - * - * @param position Starting position (0-23) - * @return Byte read from register - */ -uint8_t MPU6050::getExternalSensorByte(int position) { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_EXT_SENS_DATA_00) + position, buffer); - return buffer[0]; -} -/** Read word (2 bytes) from external sensor data registers. - * @param position Starting position (0-21) - * @return Word read from register - * @see getExternalSensorByte() - */ -uint16_t MPU6050::getExternalSensorWord(int position) { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_EXT_SENS_DATA_00) + position, 2, buffer); - return (((uint16_t)buffer[0]) << 8) | buffer[1]; -} -/** Read double word (4 bytes) from external sensor data registers. - * @param position Starting position (0-20) - * @return Double word read from registers - * @see getExternalSensorByte() - */ -uint32_t MPU6050::getExternalSensorDWord(int position) { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_EXT_SENS_DATA_00) + position, 4, buffer); - return (((uint32_t)buffer[0]) << 24) | (((uint32_t)buffer[1]) << 16) | (((uint16_t)buffer[2]) << 8) | buffer[3]; -} - -// MOT_DETECT_STATUS register - -/** Get full motion detection status register content (all bits). - * @return Motion detection status byte - * @see MPU6050_RA_MOT_DETECT_STATUS - */ -uint8_t MPU6050::getMotionStatus() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_STATUS), buffer); - return buffer[0]; -} -/** Get X-axis negative motion detection interrupt status. - * @return Motion detection status - * @see MPU6050_RA_MOT_DETECT_STATUS - * @see MPU6050_MOTION_MOT_XNEG_BIT - */ -bool MPU6050::getXNegMotionDetected() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_STATUS), (MPU6050_IMU::MPU6050_MOTION_MOT_XNEG_BIT), buffer); - return buffer[0]; -} -/** Get X-axis positive motion detection interrupt status. - * @return Motion detection status - * @see MPU6050_RA_MOT_DETECT_STATUS - * @see MPU6050_MOTION_MOT_XPOS_BIT - */ -bool MPU6050::getXPosMotionDetected() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_STATUS), (MPU6050_IMU::MPU6050_MOTION_MOT_XPOS_BIT), buffer); - return buffer[0]; -} -/** Get Y-axis negative motion detection interrupt status. - * @return Motion detection status - * @see MPU6050_RA_MOT_DETECT_STATUS - * @see MPU6050_MOTION_MOT_YNEG_BIT - */ -bool MPU6050::getYNegMotionDetected() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_STATUS), (MPU6050_IMU::MPU6050_MOTION_MOT_YNEG_BIT), buffer); - return buffer[0]; -} -/** Get Y-axis positive motion detection interrupt status. - * @return Motion detection status - * @see MPU6050_RA_MOT_DETECT_STATUS - * @see MPU6050_MOTION_MOT_YPOS_BIT - */ -bool MPU6050::getYPosMotionDetected() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_STATUS), (MPU6050_IMU::MPU6050_MOTION_MOT_YPOS_BIT), buffer); - return buffer[0]; -} -/** Get Z-axis negative motion detection interrupt status. - * @return Motion detection status - * @see MPU6050_RA_MOT_DETECT_STATUS - * @see MPU6050_MOTION_MOT_ZNEG_BIT - */ -bool MPU6050::getZNegMotionDetected() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_STATUS), (MPU6050_IMU::MPU6050_MOTION_MOT_ZNEG_BIT), buffer); - return buffer[0]; -} -/** Get Z-axis positive motion detection interrupt status. - * @return Motion detection status - * @see MPU6050_RA_MOT_DETECT_STATUS - * @see MPU6050_MOTION_MOT_ZPOS_BIT - */ -bool MPU6050::getZPosMotionDetected() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_STATUS), (MPU6050_IMU::MPU6050_MOTION_MOT_ZPOS_BIT), buffer); - return buffer[0]; -} -/** Get zero motion detection interrupt status. - * @return Motion detection status - * @see MPU6050_RA_MOT_DETECT_STATUS - * @see MPU6050_MOTION_MOT_ZRMOT_BIT - */ -bool MPU6050::getZeroMotionDetected() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_STATUS), (MPU6050_IMU::MPU6050_MOTION_MOT_ZRMOT_BIT), buffer); - return buffer[0]; -} - -// I2C_SLV*_DO register - -/** Write byte to Data Output container for specified slave. - * This register holds the output data written into Slave when Slave is set to - * write mode. For further information regarding Slave control, please - * refer to Registers 37 to 39 and immediately following. - * @param num Slave number (0-3) - * @param data Byte to write - * @see MPU6050_RA_I2C_SLV0_DO - */ -void MPU6050::setSlaveOutputByte(uint8_t num, uint8_t data) { - if (num > 3) return; - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_SLV0_DO) + num, data); -} - -// I2C_MST_DELAY_CTRL register - -/** Get external data shadow delay enabled status. - * This register is used to specify the timing of external sensor data - * shadowing. When DELAY_ES_SHADOW is set to 1, shadowing of external - * sensor data is delayed until all data has been received. - * @return Current external data shadow delay enabled status. - * @see MPU6050_RA_I2C_MST_DELAY_CTRL - * @see MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT - */ -bool MPU6050::getExternalShadowDelayEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_DELAY_CTRL), (MPU6050_IMU::MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT), buffer); - return buffer[0]; -} -/** Set external data shadow delay enabled status. - * @param enabled New external data shadow delay enabled status. - * @see getExternalShadowDelayEnabled() - * @see MPU6050_RA_I2C_MST_DELAY_CTRL - * @see MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT - */ -void MPU6050::setExternalShadowDelayEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_DELAY_CTRL), (MPU6050_IMU::MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT), enabled); -} -/** Get slave delay enabled status. - * When a particular slave delay is enabled, the rate of access for the that - * slave device is reduced. When a slave's access rate is decreased relative to - * the Sample Rate, the slave is accessed every: - * - * 1 / (1 + I2C_MST_DLY) Samples - * - * This base Sample Rate in turn is determined by SMPLRT_DIV (register * 25) - * and DLPF_CFG (register 26). - * - * For further information regarding I2C_MST_DLY, please refer to register 52. - * For further information regarding the Sample Rate, please refer to register 25. - * - * @param num Slave number (0-4) - * @return Current slave delay enabled status. - * @see MPU6050_RA_I2C_MST_DELAY_CTRL - * @see MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT - */ -bool MPU6050::getSlaveDelayEnabled(uint8_t num) { - // MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT is 4, SLV3 is 3, etc. - if (num > 4) return 0; - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_DELAY_CTRL), num, buffer); - return buffer[0]; -} -/** Set slave delay enabled status. - * @param num Slave number (0-4) - * @param enabled New slave delay enabled status. - * @see MPU6050_RA_I2C_MST_DELAY_CTRL - * @see MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT - */ -void MPU6050::setSlaveDelayEnabled(uint8_t num, bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_I2C_MST_DELAY_CTRL), num, enabled); -} - -// SIGNAL_PATH_RESET register - -/** Reset gyroscope signal path. - * The reset will revert the signal path analog to digital converters and - * filters to their power up configurations. - * @see MPU6050_RA_SIGNAL_PATH_RESET - * @see MPU6050_PATHRESET_GYRO_RESET_BIT - */ -void MPU6050::resetGyroscopePath() { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_SIGNAL_PATH_RESET), (MPU6050_IMU::MPU6050_PATHRESET_GYRO_RESET_BIT), true); -} -/** Reset accelerometer signal path. - * The reset will revert the signal path analog to digital converters and - * filters to their power up configurations. - * @see MPU6050_RA_SIGNAL_PATH_RESET - * @see MPU6050_PATHRESET_ACCEL_RESET_BIT - */ -void MPU6050::resetAccelerometerPath() { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_SIGNAL_PATH_RESET), (MPU6050_IMU::MPU6050_PATHRESET_ACCEL_RESET_BIT), true); -} -/** Reset temperature sensor signal path. - * The reset will revert the signal path analog to digital converters and - * filters to their power up configurations. - * @see MPU6050_RA_SIGNAL_PATH_RESET - * @see MPU6050_PATHRESET_TEMP_RESET_BIT - */ -void MPU6050::resetTemperaturePath() { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_SIGNAL_PATH_RESET), (MPU6050_IMU::MPU6050_PATHRESET_TEMP_RESET_BIT), true); -} - -// MOT_DETECT_CTRL register - -/** Get accelerometer power-on delay. - * The accelerometer data path provides samples to the sensor registers, Motion - * detection, Zero Motion detection, and Free Fall detection modules. The - * signal path contains filters which must be flushed on wake-up with new - * samples before the detection modules begin operations. The default wake-up - * delay, of 4ms can be lengthened by up to 3ms. This additional delay is - * specified in ACCEL_ON_DELAY in units of 1 LSB = 1 ms. The user may select - * any value above zero unless instructed otherwise by InvenSense. Please refer - * to Section 8 of the MPU-6000/MPU-6050 Product Specification document for - * further information regarding the detection modules. - * @return Current accelerometer power-on delay - * @see MPU6050_RA_MOT_DETECT_CTRL - * @see MPU6050_DETECT_ACCEL_ON_DELAY_BIT - */ -uint8_t MPU6050::getAccelerometerPowerOnDelay() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_CTRL), (MPU6050_IMU::MPU6050_DETECT_ACCEL_ON_DELAY_BIT), (MPU6050_IMU::MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH), buffer); - return buffer[0]; -} -/** Set accelerometer power-on delay. - * @param delay New accelerometer power-on delay (0-3) - * @see getAccelerometerPowerOnDelay() - * @see MPU6050_RA_MOT_DETECT_CTRL - * @see MPU6050_DETECT_ACCEL_ON_DELAY_BIT - */ -void MPU6050::setAccelerometerPowerOnDelay(uint8_t delay) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_CTRL), (MPU6050_IMU::MPU6050_DETECT_ACCEL_ON_DELAY_BIT), (MPU6050_IMU::MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH), delay); -} -/** Get Free Fall detection counter decrement configuration. - * Detection is registered by the Free Fall detection module after accelerometer - * measurements meet their respective threshold conditions over a specified - * number of samples. When the threshold conditions are met, the corresponding - * detection counter increments by 1. The user may control the rate at which the - * detection counter decrements when the threshold condition is not met by - * configuring FF_COUNT. The decrement rate can be set according to the - * following table: - * - * <pre> - * FF_COUNT | Counter Decrement - * ---------+------------------ - * 0 | Reset - * 1 | 1 - * 2 | 2 - * 3 | 4 - * </pre> - * - * When FF_COUNT is configured to 0 (reset), any non-qualifying sample will - * reset the counter to 0. For further information on Free Fall detection, - * please refer to Registers 29 to 32. - * - * @return Current decrement configuration - * @see MPU6050_RA_MOT_DETECT_CTRL - * @see MPU6050_DETECT_FF_COUNT_BIT - */ -uint8_t MPU6050::getFreefallDetectionCounterDecrement() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_CTRL), (MPU6050_IMU::MPU6050_DETECT_FF_COUNT_BIT), (MPU6050_IMU::MPU6050_DETECT_FF_COUNT_LENGTH), buffer); - return buffer[0]; -} -/** Set Free Fall detection counter decrement configuration. - * @param decrement New decrement configuration value - * @see getFreefallDetectionCounterDecrement() - * @see MPU6050_RA_MOT_DETECT_CTRL - * @see MPU6050_DETECT_FF_COUNT_BIT - */ -void MPU6050::setFreefallDetectionCounterDecrement(uint8_t decrement) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_CTRL), (MPU6050_IMU::MPU6050_DETECT_FF_COUNT_BIT), (MPU6050_IMU::MPU6050_DETECT_FF_COUNT_LENGTH), decrement); -} -/** Get Motion detection counter decrement configuration. - * Detection is registered by the Motion detection module after accelerometer - * measurements meet their respective threshold conditions over a specified - * number of samples. When the threshold conditions are met, the corresponding - * detection counter increments by 1. The user may control the rate at which the - * detection counter decrements when the threshold condition is not met by - * configuring MOT_COUNT. The decrement rate can be set according to the - * following table: - * - * <pre> - * MOT_COUNT | Counter Decrement - * ----------+------------------ - * 0 | Reset - * 1 | 1 - * 2 | 2 - * 3 | 4 - * </pre> - * - * When MOT_COUNT is configured to 0 (reset), any non-qualifying sample will - * reset the counter to 0. For further information on Motion detection, - * please refer to Registers 29 to 32. - * - */ -uint8_t MPU6050::getMotionDetectionCounterDecrement() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_CTRL), (MPU6050_IMU::MPU6050_DETECT_MOT_COUNT_BIT), (MPU6050_IMU::MPU6050_DETECT_MOT_COUNT_LENGTH), buffer); - return buffer[0]; -} -/** Set Motion detection counter decrement configuration. - * @param decrement New decrement configuration value - * @see getMotionDetectionCounterDecrement() - * @see MPU6050_RA_MOT_DETECT_CTRL - * @see MPU6050_DETECT_MOT_COUNT_BIT - */ -void MPU6050::setMotionDetectionCounterDecrement(uint8_t decrement) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_MOT_DETECT_CTRL), (MPU6050_IMU::MPU6050_DETECT_MOT_COUNT_BIT), (MPU6050_IMU::MPU6050_DETECT_MOT_COUNT_LENGTH), decrement); -} - -// USER_CTRL register - -/** Get FIFO enabled status. - * When this bit is set to 0, the FIFO buffer is disabled. The FIFO buffer - * cannot be written to or read from while disabled. The FIFO buffer's state - * does not change unless the MPU-60X0 is power cycled. - * @return Current FIFO enabled status - * @see MPU6050_RA_USER_CTRL - * @see MPU6050_USERCTRL_FIFO_EN_BIT - */ -bool MPU6050::getFIFOEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_FIFO_EN_BIT), buffer); - return buffer[0]; -} -/** Set FIFO enabled status. - * @param enabled New FIFO enabled status - * @see getFIFOEnabled() - * @see MPU6050_RA_USER_CTRL - * @see MPU6050_USERCTRL_FIFO_EN_BIT - */ -void MPU6050::setFIFOEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_FIFO_EN_BIT), enabled); -} -/** Get I2C Master Mode enabled status. - * When this mode is enabled, the MPU-60X0 acts as the I2C Master to the - * external sensor slave devices on the auxiliary I2C bus. When this bit is - * cleared to 0, the auxiliary I2C bus lines (AUX_DA and AUX_CL) are logically - * driven by the primary I2C bus (SDA and SCL). This is a precondition to - * enabling Bypass Mode. For further information regarding Bypass Mode, please - * refer to Register 55. - * @return Current I2C Master Mode enabled status - * @see MPU6050_RA_USER_CTRL - * @see MPU6050_USERCTRL_I2C_MST_EN_BIT - */ -bool MPU6050::getI2CMasterModeEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_I2C_MST_EN_BIT), buffer); - return buffer[0]; -} -/** Set I2C Master Mode enabled status. - * @param enabled New I2C Master Mode enabled status - * @see getI2CMasterModeEnabled() - * @see MPU6050_RA_USER_CTRL - * @see MPU6050_USERCTRL_I2C_MST_EN_BIT - */ -void MPU6050::setI2CMasterModeEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_I2C_MST_EN_BIT), enabled); -} -/** Switch from I2C to SPI mode (MPU-6000 only) - * If this is set, the primary SPI interface will be enabled in place of the - * disabled primary I2C interface. - */ -void MPU6050::switchSPIEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_I2C_IF_DIS_BIT), enabled); -} -/** Reset the FIFO. - * This bit resets the FIFO buffer when set to 1 while FIFO_EN equals 0. This - * bit automatically clears to 0 after the reset has been triggered. - * @see MPU6050_RA_USER_CTRL - * @see MPU6050_USERCTRL_FIFO_RESET_BIT - */ -void MPU6050::resetFIFO() { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_FIFO_RESET_BIT), true); -} -/** Reset the I2C Master. - * This bit resets the I2C Master when set to 1 while I2C_MST_EN equals 0. - * This bit automatically clears to 0 after the reset has been triggered. - * @see MPU6050_RA_USER_CTRL - * @see MPU6050_USERCTRL_I2C_MST_RESET_BIT - */ -void MPU6050::resetI2CMaster() { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_I2C_MST_RESET_BIT), true); -} -/** Reset all sensor registers and signal paths. - * When set to 1, this bit resets the signal paths for all sensors (gyroscopes, - * accelerometers, and temperature sensor). This operation will also clear the - * sensor registers. This bit automatically clears to 0 after the reset has been - * triggered. - * - * When resetting only the signal path (and not the sensor registers), please - * use Register 104, SIGNAL_PATH_RESET. - * - * @see MPU6050_RA_USER_CTRL - * @see MPU6050_USERCTRL_SIG_COND_RESET_BIT - */ -void MPU6050::resetSensors() { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_SIG_COND_RESET_BIT), true); -} - -// PWR_MGMT_1 register - -/** Trigger a full device reset. - * A small delay of ~50ms may be desirable after triggering a reset. - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_DEVICE_RESET_BIT - */ -void MPU6050::reset() { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_DEVICE_RESET_BIT), true); -} -/** Get sleep mode status. - * Setting the SLEEP bit in the register puts the device into very low power - * sleep mode. In this mode, only the serial interface and internal registers - * remain active, allowing for a very low standby current. Clearing this bit - * puts the device back into normal mode. To save power, the individual standby - * selections for each of the gyros should be used if any gyro axis is not used - * by the application. - * @return Current sleep mode enabled status - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_SLEEP_BIT - */ -bool MPU6050::getSleepEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_SLEEP_BIT), buffer); - return buffer[0]; -} -/** Set sleep mode status. - * @param enabled New sleep mode enabled status - * @see getSleepEnabled() - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_SLEEP_BIT - */ -void MPU6050::setSleepEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_SLEEP_BIT), enabled); -} -/** Get wake cycle enabled status. - * When this bit is set to 1 and SLEEP is disabled, the MPU-60X0 will cycle - * between sleep mode and waking up to take a single sample of data from active - * sensors at a rate determined by LP_WAKE_CTRL (register 108). - * @return Current sleep mode enabled status - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_CYCLE_BIT - */ -bool MPU6050::getWakeCycleEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_CYCLE_BIT), buffer); - return buffer[0]; -} -/** Set wake cycle enabled status. - * @param enabled New sleep mode enabled status - * @see getWakeCycleEnabled() - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_CYCLE_BIT - */ -void MPU6050::setWakeCycleEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_CYCLE_BIT), enabled); -} -/** Get temperature sensor enabled status. - * Control the usage of the internal temperature sensor. - * - * Note: this register stores the *disabled* value, but for consistency with the - * rest of the code, the function is named and used with standard true/false - * values to indicate whether the sensor is enabled or disabled, respectively. - * - * @return Current temperature sensor enabled status - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_TEMP_DIS_BIT - */ -bool MPU6050::getTempSensorEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_TEMP_DIS_BIT), buffer); - return buffer[0] == 0; // 1 is actually disabled here -} -/** Set temperature sensor enabled status. - * Note: this register stores the *disabled* value, but for consistency with the - * rest of the code, the function is named and used with standard true/false - * values to indicate whether the sensor is enabled or disabled, respectively. - * - * @param enabled New temperature sensor enabled status - * @see getTempSensorEnabled() - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_TEMP_DIS_BIT - */ -void MPU6050::setTempSensorEnabled(bool enabled) { - // 1 is actually disabled here - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_TEMP_DIS_BIT), !enabled); -} -/** Get clock source setting. - * @return Current clock source setting - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_CLKSEL_BIT - * @see (MPU6050_IMU::MPU6050_PWR1_CLKSEL_LENGTH) - */ -uint8_t MPU6050::getClockSource() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_CLKSEL_BIT), (MPU6050_IMU::MPU6050_PWR1_CLKSEL_LENGTH), buffer); - return buffer[0]; -} -/** Set clock source setting. - * An internal 8MHz oscillator, gyroscope based clock, or external sources can - * be selected as the MPU-60X0 clock source. When the internal 8 MHz oscillator - * or an external source is chosen as the clock source, the MPU-60X0 can operate - * in low power modes with the gyroscopes disabled. - * - * Upon power up, the MPU-60X0 clock source defaults to the internal oscillator. - * However, it is highly recommended that the device be configured to use one of - * the gyroscopes (or an external clock source) as the clock reference for - * improved stability. The clock source can be selected according to the following table: - * - * <pre> - * CLK_SEL | Clock Source - * --------+-------------------------------------- - * 0 | Internal oscillator - * 1 | PLL with X Gyro reference - * 2 | PLL with Y Gyro reference - * 3 | PLL with Z Gyro reference - * 4 | PLL with external 32.768kHz reference - * 5 | PLL with external 19.2MHz reference - * 6 | Reserved - * 7 | Stops the clock and keeps the timing generator in reset - * </pre> - * - * @param source New clock source setting - * @see getClockSource() - * @see MPU6050_RA_PWR_MGMT_1 - * @see MPU6050_PWR1_CLKSEL_BIT - * @see (MPU6050_IMU::MPU6050_PWR1_CLKSEL_LENGTH) - */ -void MPU6050::setClockSource(uint8_t source) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_1), (MPU6050_IMU::MPU6050_PWR1_CLKSEL_BIT), (MPU6050_IMU::MPU6050_PWR1_CLKSEL_LENGTH), source); -} - -// PWR_MGMT_2 register - -/** Get wake frequency in Accel-Only Low Power Mode. - * The MPU-60X0 can be put into Accerlerometer Only Low Power Mode by setting - * PWRSEL to 1 in the Power Management 1 register (Register 107). In this mode, - * the device will power off all devices except for the primary I2C interface, - * waking only the accelerometer at fixed intervals to take a single - * measurement. The frequency of wake-ups can be configured with LP_WAKE_CTRL - * as shown below: - * - * <pre> - * LP_WAKE_CTRL | Wake-up Frequency - * -------------+------------------ - * 0 | 1.25 Hz - * 1 | 2.5 Hz - * 2 | 5 Hz - * 3 | 10 Hz - * </pre> - * - * For further information regarding the MPU-60X0's power modes, please refer to - * Register 107. - * - * @return Current wake frequency - * @see MPU6050_RA_PWR_MGMT_2 - */ -uint8_t MPU6050::getWakeFrequency() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_LP_WAKE_CTRL_BIT), (MPU6050_IMU::MPU6050_PWR2_LP_WAKE_CTRL_LENGTH), buffer); - return buffer[0]; -} -/** Set wake frequency in Accel-Only Low Power Mode. - * @param frequency New wake frequency - * @see MPU6050_RA_PWR_MGMT_2 - */ -void MPU6050::setWakeFrequency(uint8_t frequency) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_LP_WAKE_CTRL_BIT), (MPU6050_IMU::MPU6050_PWR2_LP_WAKE_CTRL_LENGTH), frequency); -} - -/** Get X-axis accelerometer standby enabled status. - * If enabled, the X-axis will not gather or report data (or use power). - * @return Current X-axis standby enabled status - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_XA_BIT - */ -bool MPU6050::getStandbyXAccelEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_XA_BIT), buffer); - return buffer[0]; -} -/** Set X-axis accelerometer standby enabled status. - * @param New X-axis standby enabled status - * @see getStandbyXAccelEnabled() - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_XA_BIT - */ -void MPU6050::setStandbyXAccelEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_XA_BIT), enabled); -} -/** Get Y-axis accelerometer standby enabled status. - * If enabled, the Y-axis will not gather or report data (or use power). - * @return Current Y-axis standby enabled status - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_YA_BIT - */ -bool MPU6050::getStandbyYAccelEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_YA_BIT), buffer); - return buffer[0]; -} -/** Set Y-axis accelerometer standby enabled status. - * @param New Y-axis standby enabled status - * @see getStandbyYAccelEnabled() - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_YA_BIT - */ -void MPU6050::setStandbyYAccelEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_YA_BIT), enabled); -} -/** Get Z-axis accelerometer standby enabled status. - * If enabled, the Z-axis will not gather or report data (or use power). - * @return Current Z-axis standby enabled status - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_ZA_BIT - */ -bool MPU6050::getStandbyZAccelEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_ZA_BIT), buffer); - return buffer[0]; -} -/** Set Z-axis accelerometer standby enabled status. - * @param New Z-axis standby enabled status - * @see getStandbyZAccelEnabled() - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_ZA_BIT - */ -void MPU6050::setStandbyZAccelEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_ZA_BIT), enabled); -} -/** Get X-axis gyroscope standby enabled status. - * If enabled, the X-axis will not gather or report data (or use power). - * @return Current X-axis standby enabled status - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_XG_BIT - */ -bool MPU6050::getStandbyXGyroEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_XG_BIT), buffer); - return buffer[0]; -} -/** Set X-axis gyroscope standby enabled status. - * @param New X-axis standby enabled status - * @see getStandbyXGyroEnabled() - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_XG_BIT - */ -void MPU6050::setStandbyXGyroEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_XG_BIT), enabled); -} -/** Get Y-axis gyroscope standby enabled status. - * If enabled, the Y-axis will not gather or report data (or use power). - * @return Current Y-axis standby enabled status - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_YG_BIT - */ -bool MPU6050::getStandbyYGyroEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_YG_BIT), buffer); - return buffer[0]; -} -/** Set Y-axis gyroscope standby enabled status. - * @param New Y-axis standby enabled status - * @see getStandbyYGyroEnabled() - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_YG_BIT - */ -void MPU6050::setStandbyYGyroEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_YG_BIT), enabled); -} -/** Get Z-axis gyroscope standby enabled status. - * If enabled, the Z-axis will not gather or report data (or use power). - * @return Current Z-axis standby enabled status - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_ZG_BIT - */ -bool MPU6050::getStandbyZGyroEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_ZG_BIT), buffer); - return buffer[0]; -} -/** Set Z-axis gyroscope standby enabled status. - * @param New Z-axis standby enabled status - * @see getStandbyZGyroEnabled() - * @see MPU6050_RA_PWR_MGMT_2 - * @see MPU6050_PWR2_STBY_ZG_BIT - */ -void MPU6050::setStandbyZGyroEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_PWR_MGMT_2), (MPU6050_IMU::MPU6050_PWR2_STBY_ZG_BIT), enabled); -} - -// FIFO_COUNT* registers - -/** Get current FIFO buffer size. - * This value indicates the number of bytes stored in the FIFO buffer. This - * number is in turn the number of bytes that can be read from the FIFO buffer - * and it is directly proportional to the number of samples available given the - * set of sensor data bound to be stored in the FIFO (register 35 and 36). - * @return Current FIFO buffer size - */ -uint16_t MPU6050::getFIFOCount() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_COUNTH), 2, buffer); - return (((uint16_t)buffer[0]) << 8) | buffer[1]; -} - -// FIFO_R_W register - -/** Get byte from FIFO buffer. - * This register is used to read and write data from the FIFO buffer. Data is - * written to the FIFO in order of register number (from lowest to highest). If - * all the FIFO enable flags (see below) are enabled and all External Sensor - * Data registers (Registers 73 to 96) are associated with a Slave device, the - * contents of registers 59 through 96 will be written in order at the Sample - * Rate. - * - * The contents of the sensor data registers (Registers 59 to 96) are written - * into the FIFO buffer when their corresponding FIFO enable flags are set to 1 - * in FIFO_EN (Register 35). An additional flag for the sensor data registers - * associated with I2C Slave 3 can be found in I2C_MST_CTRL (Register 36). - * - * If the FIFO buffer has overflowed, the status bit FIFO_OFLOW_INT is - * automatically set to 1. This bit is located in INT_STATUS (Register 58). - * When the FIFO buffer has overflowed, the oldest data will be lost and new - * data will be written to the FIFO. - * - * If the FIFO buffer is empty, reading this register will return the last byte - * that was previously read from the FIFO until new data is available. The user - * should check FIFO_COUNT to ensure that the FIFO buffer is not read when - * empty. - * - * @return Byte from FIFO buffer - */ -uint8_t MPU6050::getFIFOByte() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_R_W), buffer); - return buffer[0]; -} -void MPU6050::getFIFOBytes(uint8_t *data, uint8_t length) { - if(length > 0){ - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_R_W), length, data); - } else { - *data = 0; - } -} - -/** Get latest byte from FIFO buffer no matter how much time has passed. - * === GetCurrentFIFOPacket === - * ================================================================ - * Returns 1) when nothing special was done - * 2) when recovering from overflow - * 0) when no valid data is available - * ================================================================ */ - int8_t MPU6050::GetCurrentFIFOPacket(uint8_t *data, uint8_t length) { // overflow proof - int16_t fifoC; - // This section of code is for when we allowed more than 1 packet to be acquired - uint32_t BreakTimer = micros(); - do { - if ((fifoC = getFIFOCount()) > length) { - - if (fifoC > 200) { // if you waited to get the FIFO buffer to > 200 bytes it will take longer to get the last packet in the FIFO Buffer than it will take to reset the buffer and wait for the next to arrive - resetFIFO(); // Fixes any overflow corruption - fifoC = 0; - while (!(fifoC = getFIFOCount()) && ((micros() - BreakTimer) <= (11000))); // Get Next New Packet - } else { //We have more than 1 packet but less than 200 bytes of data in the FIFO Buffer - uint8_t Trash[BUFFER_LENGTH]; - while ((fifoC = getFIFOCount()) > length) { // Test each time just in case the MPU is writing to the FIFO Buffer - fifoC = fifoC - length; // Save the last packet - uint16_t RemoveBytes; - while (fifoC) { // fifo count will reach zero so this is safe - RemoveBytes = min((int)fifoC, BUFFER_LENGTH); // Buffer Length is different than the packet length this will efficiently clear the buffer - getFIFOBytes(Trash, (uint8_t)RemoveBytes); - fifoC -= RemoveBytes; - } - } - } - } - if (!fifoC) return 0; // Called too early no data or we timed out after FIFO Reset - // We have 1 packet - if ((micros() - BreakTimer) > (11000)) return 0; - } while (fifoC != length); - getFIFOBytes(data, length); //Get 1 packet - return 1; -} - - -/** Write byte to FIFO buffer. - * @see getFIFOByte() - * @see MPU6050_RA_FIFO_R_W - */ -void MPU6050::setFIFOByte(uint8_t data) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_FIFO_R_W), data); -} - -// WHO_AM_I register - -/** Get Device ID. - * This register is used to verify the identity of the device (0b110100, 0x34). - * @return Device ID (6 bits only! should be 0x34) - * @see MPU6050_RA_WHO_AM_I - * @see MPU6050_WHO_AM_I_BIT - * @see (MPU6050_IMU::MPU6050_WHO_AM_I_LENGTH) - */ -uint8_t MPU6050::getDeviceID() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_WHO_AM_I), (MPU6050_IMU::MPU6050_WHO_AM_I_BIT), (MPU6050_IMU::MPU6050_WHO_AM_I_LENGTH), buffer); - return buffer[0]; -} -/** Set Device ID. - * Write a new ID into the WHO_AM_I register (no idea why this should ever be - * necessary though). - * @param id New device ID to set. - * @see getDeviceID() - * @see MPU6050_RA_WHO_AM_I - * @see MPU6050_WHO_AM_I_BIT - * @see (MPU6050_WHO_AM_I_LENGTH) - */ -void MPU6050::setDeviceID(uint8_t id) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_WHO_AM_I), (MPU6050_IMU::MPU6050_WHO_AM_I_BIT), (MPU6050_IMU::MPU6050_WHO_AM_I_LENGTH), id); -} - -// ======== UNDOCUMENTED/DMP REGISTERS/METHODS ======== - -// XG_OFFS_TC register - -uint8_t MPU6050::getOTPBankValid() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_XG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_OTP_BNK_VLD_BIT), buffer); - return buffer[0]; -} -void MPU6050::setOTPBankValid(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_XG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_OTP_BNK_VLD_BIT), enabled); -} -int8_t MPU6050::getXGyroOffsetTC() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_XG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_OFFSET_BIT), (MPU6050_IMU::MPU6050_TC_OFFSET_LENGTH), buffer); - return buffer[0]; -} -void MPU6050::setXGyroOffsetTC(int8_t offset) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_XG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_OFFSET_BIT), (MPU6050_IMU::MPU6050_TC_OFFSET_LENGTH), offset); -} - -// YG_OFFS_TC register - -int8_t MPU6050::getYGyroOffsetTC() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_YG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_OFFSET_BIT), (MPU6050_IMU::MPU6050_TC_OFFSET_LENGTH), buffer); - return buffer[0]; -} -void MPU6050::setYGyroOffsetTC(int8_t offset) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_YG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_OFFSET_BIT), (MPU6050_IMU::MPU6050_TC_OFFSET_LENGTH), offset); -} - -// ZG_OFFS_TC register - -int8_t MPU6050::getZGyroOffsetTC() { - I2Cdev::readBits(devAddr, (MPU6050_IMU::MPU6050_RA_ZG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_OFFSET_BIT), (MPU6050_IMU::MPU6050_TC_OFFSET_LENGTH), buffer); - return buffer[0]; -} -void MPU6050::setZGyroOffsetTC(int8_t offset) { - I2Cdev::writeBits(devAddr, (MPU6050_IMU::MPU6050_RA_ZG_OFFS_TC), (MPU6050_IMU::MPU6050_TC_OFFSET_BIT), (MPU6050_IMU::MPU6050_TC_OFFSET_LENGTH), offset); -} - -// X_FINE_GAIN register - -int8_t MPU6050::getXFineGain() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_X_FINE_GAIN), buffer); - return buffer[0]; -} -void MPU6050::setXFineGain(int8_t gain) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_X_FINE_GAIN), gain); -} - -// Y_FINE_GAIN register - -int8_t MPU6050::getYFineGain() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_Y_FINE_GAIN), buffer); - return buffer[0]; -} -void MPU6050::setYFineGain(int8_t gain) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_Y_FINE_GAIN), gain); -} - -// Z_FINE_GAIN register - -int8_t MPU6050::getZFineGain() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_Z_FINE_GAIN), buffer); - return buffer[0]; -} -void MPU6050::setZFineGain(int8_t gain) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_Z_FINE_GAIN), gain); -} - -// XA_OFFS_* registers - -int16_t MPU6050::getXAccelOffset() { - uint8_t SaveAddress = ((getDeviceID() < 0x38 )? (MPU6050_IMU::MPU6050_RA_XA_OFFS_H):0x77); // MPU6050,MPU9150 Vs MPU6500,MPU9250 - I2Cdev::readBytes(devAddr, SaveAddress, 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -void MPU6050::setXAccelOffset(int16_t offset) { - uint8_t SaveAddress = ((getDeviceID() < 0x38 )? (MPU6050_IMU::MPU6050_RA_XA_OFFS_H):0x77); // MPU6050,MPU9150 Vs MPU6500,MPU9250 - I2Cdev::writeWord(devAddr, SaveAddress, offset); -} - -// YA_OFFS_* register - -int16_t MPU6050::getYAccelOffset() { - uint8_t SaveAddress = ((getDeviceID() < 0x38 )? (MPU6050_IMU::MPU6050_RA_YA_OFFS_H):0x7A); // MPU6050,MPU9150 Vs MPU6500,MPU9250 - I2Cdev::readBytes(devAddr, SaveAddress, 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -void MPU6050::setYAccelOffset(int16_t offset) { - uint8_t SaveAddress = ((getDeviceID() < 0x38 )? (MPU6050_IMU::MPU6050_RA_YA_OFFS_H):0x7A); // MPU6050,MPU9150 Vs MPU6500,MPU9250 - I2Cdev::writeWord(devAddr, SaveAddress, offset); -} - -// ZA_OFFS_* register - -int16_t MPU6050::getZAccelOffset() { - uint8_t SaveAddress = ((getDeviceID() < 0x38 )? (MPU6050_IMU::MPU6050_RA_ZA_OFFS_H):0x7D); // MPU6050,MPU9150 Vs MPU6500,MPU9250 - I2Cdev::readBytes(devAddr, SaveAddress, 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -void MPU6050::setZAccelOffset(int16_t offset) { - uint8_t SaveAddress = ((getDeviceID() < 0x38 )? (MPU6050_IMU::MPU6050_RA_ZA_OFFS_H):0x7D); // MPU6050,MPU9150 Vs MPU6500,MPU9250 - I2Cdev::writeWord(devAddr, SaveAddress, offset); -} - -// XG_OFFS_USR* registers - -int16_t MPU6050::getXGyroOffset() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_XG_OFFS_USRH), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -void MPU6050::setXGyroOffset(int16_t offset) { - I2Cdev::writeWord(devAddr, (MPU6050_IMU::MPU6050_RA_XG_OFFS_USRH), offset); -} - -// YG_OFFS_USR* register - -int16_t MPU6050::getYGyroOffset() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_YG_OFFS_USRH), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -void MPU6050::setYGyroOffset(int16_t offset) { - I2Cdev::writeWord(devAddr, (MPU6050_IMU::MPU6050_RA_YG_OFFS_USRH), offset); -} - -// ZG_OFFS_USR* register - -int16_t MPU6050::getZGyroOffset() { - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_ZG_OFFS_USRH), 2, buffer); - return (((int16_t)buffer[0]) << 8) | buffer[1]; -} -void MPU6050::setZGyroOffset(int16_t offset) { - I2Cdev::writeWord(devAddr, (MPU6050_IMU::MPU6050_RA_ZG_OFFS_USRH), offset); -} - -// INT_ENABLE register (DMP functions) - -bool MPU6050::getIntPLLReadyEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_PLL_RDY_INT_BIT), buffer); - return buffer[0]; -} -void MPU6050::setIntPLLReadyEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_PLL_RDY_INT_BIT), enabled); -} -bool MPU6050::getIntDMPEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_DMP_INT_BIT), buffer); - return buffer[0]; -} -void MPU6050::setIntDMPEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), (MPU6050_IMU::MPU6050_INTERRUPT_DMP_INT_BIT), enabled); -} - -// DMP_INT_STATUS - -bool MPU6050::getDMPInt5Status() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_INT_STATUS), (MPU6050_IMU::MPU6050_DMPINT_5_BIT), buffer); - return buffer[0]; -} -bool MPU6050::getDMPInt4Status() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_INT_STATUS), (MPU6050_IMU::MPU6050_DMPINT_4_BIT), buffer); - return buffer[0]; -} -bool MPU6050::getDMPInt3Status() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_INT_STATUS), (MPU6050_IMU::MPU6050_DMPINT_3_BIT), buffer); - return buffer[0]; -} -bool MPU6050::getDMPInt2Status() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_INT_STATUS), (MPU6050_IMU::MPU6050_DMPINT_2_BIT), buffer); - return buffer[0]; -} -bool MPU6050::getDMPInt1Status() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_INT_STATUS), (MPU6050_IMU::MPU6050_DMPINT_1_BIT), buffer); - return buffer[0]; -} -bool MPU6050::getDMPInt0Status() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_INT_STATUS), (MPU6050_IMU::MPU6050_DMPINT_0_BIT), buffer); - return buffer[0]; -} - -// INT_STATUS register (DMP functions) - -bool MPU6050::getIntPLLReadyStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), (MPU6050_IMU::MPU6050_INTERRUPT_PLL_RDY_INT_BIT), buffer); - return buffer[0]; -} -bool MPU6050::getIntDMPStatus() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_INT_STATUS), (MPU6050_IMU::MPU6050_INTERRUPT_DMP_INT_BIT), buffer); - return buffer[0]; -} - -// USER_CTRL register (DMP functions) - -bool MPU6050::getDMPEnabled() { - I2Cdev::readBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_DMP_EN_BIT), buffer); - return buffer[0]; -} -void MPU6050::setDMPEnabled(bool enabled) { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_DMP_EN_BIT), enabled); -} -void MPU6050::resetDMP() { - I2Cdev::writeBit(devAddr, (MPU6050_IMU::MPU6050_RA_USER_CTRL), (MPU6050_IMU::MPU6050_USERCTRL_DMP_RESET_BIT), true); -} - -// BANK_SEL register - -void MPU6050::setMemoryBank(uint8_t bank, bool prefetchEnabled, bool userBank) { - bank &= 0x1F; - if (userBank) bank |= 0x20; - if (prefetchEnabled) bank |= 0x40; - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_BANK_SEL), bank); -} - -// MEM_START_ADDR register - -void MPU6050::setMemoryStartAddress(uint8_t address) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_MEM_START_ADDR), address); -} - -// MEM_R_W register - -uint8_t MPU6050::readMemoryByte() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_MEM_R_W), buffer); - return buffer[0]; -} -void MPU6050::writeMemoryByte(uint8_t data) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_MEM_R_W), data); -} -void MPU6050::readMemoryBlock(uint8_t *data, uint16_t dataSize, uint8_t bank, uint8_t address) { - setMemoryBank(bank); - setMemoryStartAddress(address); - uint8_t chunkSize; - for (uint16_t i = 0; i < dataSize;) { - // determine correct chunk size according to bank position and data size - chunkSize = (MPU6050_IMU::MPU6050_DMP_MEMORY_CHUNK_SIZE); - - // make sure we don't go past the data size - if (i + chunkSize > dataSize) chunkSize = dataSize - i; - - // make sure this chunk doesn't go past the bank boundary (256 bytes) - if (chunkSize > 256 - address) chunkSize = 256 - address; - - // read the chunk of data as specified - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_MEM_R_W), chunkSize, data + i); - - // increase byte index by [chunkSize] - i += chunkSize; - - // uint8_t automatically wraps to 0 at 256 - address += chunkSize; - - // if we aren't done, update bank (if necessary) and address - if (i < dataSize) { - if (address == 0) bank++; - setMemoryBank(bank); - setMemoryStartAddress(address); - } - } -} -bool MPU6050::writeMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank, uint8_t address, bool verify, bool useProgMem) { - setMemoryBank(bank); - setMemoryStartAddress(address); - uint8_t chunkSize; - uint8_t *verifyBuffer=0; - uint8_t *progBuffer=0; - uint16_t i; - uint8_t j; - if (verify) verifyBuffer = (uint8_t *)malloc((MPU6050_IMU::MPU6050_DMP_MEMORY_CHUNK_SIZE)); - if (useProgMem) progBuffer = (uint8_t *)malloc((MPU6050_IMU::MPU6050_DMP_MEMORY_CHUNK_SIZE)); - for (i = 0; i < dataSize;) { - // determine correct chunk size according to bank position and data size - chunkSize = (MPU6050_IMU::MPU6050_DMP_MEMORY_CHUNK_SIZE); - - // make sure we don't go past the data size - if (i + chunkSize > dataSize) chunkSize = dataSize - i; - - // make sure this chunk doesn't go past the bank boundary (256 bytes) - if (chunkSize > 256 - address) chunkSize = 256 - address; - - if (useProgMem) { - // write the chunk of data as specified - for (j = 0; j < chunkSize; j++) progBuffer[j] = pgm_read_byte(data + i + j); - } else { - // write the chunk of data as specified - progBuffer = (uint8_t *)data + i; - } - - I2Cdev::writeBytes(devAddr, (MPU6050_IMU::MPU6050_RA_MEM_R_W), chunkSize, progBuffer); - - // verify data if needed - if (verify && verifyBuffer) { - setMemoryBank(bank); - setMemoryStartAddress(address); - I2Cdev::readBytes(devAddr, (MPU6050_IMU::MPU6050_RA_MEM_R_W), chunkSize, verifyBuffer); - if (memcmp(progBuffer, verifyBuffer, chunkSize) != 0) { - /*Serial.print("Block write verification error, bank "); - Serial.print(bank, DEC); - Serial.print(", address "); - Serial.print(address, DEC); - Serial.print("!\nExpected:"); - for (j = 0; j < chunkSize; j++) { - Serial.print(" 0x"); - if (progBuffer[j] < 16) Serial.print("0"); - Serial.print(progBuffer[j], HEX); - } - Serial.print("\nReceived:"); - for (uint8_t j = 0; j < chunkSize; j++) { - Serial.print(" 0x"); - if (verifyBuffer[i + j] < 16) Serial.print("0"); - Serial.print(verifyBuffer[i + j], HEX); - } - Serial.print("\n");*/ - free(verifyBuffer); - if (useProgMem) free(progBuffer); - return false; // uh oh. - } - } - - // increase byte index by [chunkSize] - i += chunkSize; - - // uint8_t automatically wraps to 0 at 256 - address += chunkSize; - - // if we aren't done, update bank (if necessary) and address - if (i < dataSize) { - if (address == 0) bank++; - setMemoryBank(bank); - setMemoryStartAddress(address); - } - } - if (verify) free(verifyBuffer); - if (useProgMem) free(progBuffer); - return true; -} -bool MPU6050::writeProgMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank, uint8_t address, bool verify) { - return writeMemoryBlock(data, dataSize, bank, address, verify, true); -} -bool MPU6050::writeDMPConfigurationSet(const uint8_t *data, uint16_t dataSize, bool useProgMem) { - uint8_t *progBuffer = 0; - uint8_t success, special; - uint16_t i, j; - if (useProgMem) { - progBuffer = (uint8_t *)malloc(8); // assume 8-byte blocks, realloc later if necessary - } - - // config set data is a long string of blocks with the following structure: - // [bank] [offset] [length] [byte[0], byte[1], ..., byte[length]] - uint8_t bank, offset, length; - for (i = 0; i < dataSize;) { - if (useProgMem) { - bank = pgm_read_byte(data + i++); - offset = pgm_read_byte(data + i++); - length = pgm_read_byte(data + i++); - } else { - bank = data[i++]; - offset = data[i++]; - length = data[i++]; - } - - // write data or perform special action - if (length > 0) { - // regular block of data to write - /*Serial.print("Writing config block to bank "); - Serial.print(bank); - Serial.print(", offset "); - Serial.print(offset); - Serial.print(", length="); - Serial.println(length);*/ - if (useProgMem) { - if (sizeof(progBuffer) < length) progBuffer = (uint8_t *)realloc(progBuffer, length); - for (j = 0; j < length; j++) progBuffer[j] = pgm_read_byte(data + i + j); - } else { - progBuffer = (uint8_t *)data + i; - } - success = writeMemoryBlock(progBuffer, length, bank, offset, true); - i += length; - } else { - // special instruction - // NOTE: this kind of behavior (what and when to do certain things) - // is totally undocumented. This code is in here based on observed - // behavior only, and exactly why (or even whether) it has to be here - // is anybody's guess for now. - if (useProgMem) { - special = pgm_read_byte(data + i++); - } else { - special = data[i++]; - } - /*Serial.print("Special command code "); - Serial.print(special, HEX); - Serial.println(" found...");*/ - if (special == 0x01) { - // enable DMP-related interrupts - - //setIntZeroMotionEnabled(true); - //setIntFIFOBufferOverflowEnabled(true); - //setIntDMPEnabled(true); - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_INT_ENABLE), 0x32); // single operation - - success = true; - } else { - // unknown special command - success = false; - } - } - - if (!success) { - if (useProgMem) free(progBuffer); - return false; // uh oh - } - } - if (useProgMem) free(progBuffer); - return true; -} -bool MPU6050::writeProgDMPConfigurationSet(const uint8_t *data, uint16_t dataSize) { - return writeDMPConfigurationSet(data, dataSize, true); -} - -// DMP_CFG_1 register - -uint8_t MPU6050::getDMPConfig1() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_CFG_1), buffer); - return buffer[0]; -} -void MPU6050::setDMPConfig1(uint8_t config) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_CFG_1), config); -} - -// DMP_CFG_2 register - -uint8_t MPU6050::getDMPConfig2() { - I2Cdev::readByte(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_CFG_2), buffer); - return buffer[0]; -} -void MPU6050::setDMPConfig2(uint8_t config) { - I2Cdev::writeByte(devAddr, (MPU6050_IMU::MPU6050_RA_DMP_CFG_2), config); -} - - -//*************************************************************************************** -//********************** Calibration Routines ********************** -//*************************************************************************************** -/** - @brief Fully calibrate Gyro from ZERO in about 6-7 Loops 600-700 readings -*/ -void MPU6050::CalibrateGyro(uint8_t Loops ) { - double kP = 0.3; - double kI = 90; - float x; - x = (100 - map(Loops, 1, 5, 20, 0)) * .01; - kP *= x; - kI *= x; - - PID( 0x43, kP, kI, Loops); -} - -/** - @brief Fully calibrate Accel from ZERO in about 6-7 Loops 600-700 readings -*/ -void MPU6050::CalibrateAccel(uint8_t Loops ) { - - float kP = 0.3; - float kI = 20; - float x; - x = (100 - map(Loops, 1, 5, 20, 0)) * .01; - kP *= x; - kI *= x; - PID( 0x3B, kP, kI, Loops); -} - -void MPU6050::PID(uint8_t ReadAddress, float kP,float kI, uint8_t Loops){ - uint8_t SaveAddress = (ReadAddress == 0x3B)?((getDeviceID() < 0x38 )? 0x06:0x77):0x13; - - int16_t Data; - float Reading; - int16_t BitZero[3]; - uint8_t shift =(SaveAddress == 0x77)?3:2; - float Error, PTerm, ITerm[3]; - int16_t eSample; - uint32_t eSum ; - Serial.write('>'); - for (int i = 0; i < 3; i++) { - I2Cdev::readWords(devAddr, SaveAddress + (i * shift), 1, (uint16_t *)&Data); // reads 1 or more 16 bit integers (Word) - Reading = Data; - if(SaveAddress != 0x13){ - BitZero[i] = Data & 1; // Capture Bit Zero to properly handle Accelerometer calibration - ITerm[i] = ((float)Reading) * 8; - } else { - ITerm[i] = Reading * 4; - } - } - for (int L = 0; L < Loops; L++) { - eSample = 0; - for (int c = 0; c < 100; c++) {// 100 PI Calculations - eSum = 0; - for (int i = 0; i < 3; i++) { - I2Cdev::readWords(devAddr, ReadAddress + (i * 2), 1, (uint16_t *)&Data); // reads 1 or more 16 bit integers (Word) - Reading = Data; - if ((ReadAddress == 0x3B)&&(i == 2)) Reading -= 16384; //remove Gravity - Error = -Reading; - eSum += abs(Reading); - PTerm = kP * Error; - ITerm[i] += (Error * 0.001) * kI; // Integral term 1000 Calculations a second = 0.001 - if(SaveAddress != 0x13){ - Data = round((PTerm + ITerm[i] ) / 8); //Compute PID Output - Data = ((Data)&0xFFFE) |BitZero[i]; // Insert Bit0 Saved at beginning - } else Data = round((PTerm + ITerm[i] ) / 4); //Compute PID Output - I2Cdev::writeWords(devAddr, SaveAddress + (i * shift), 1, (uint16_t *)&Data); - } - if((c == 99) && eSum > 1000){ // Error is still to great to continue - c = 0; - Serial.write('*'); - } - if((eSum * ((ReadAddress == 0x3B)?.05: 1)) < 5) eSample++; // Successfully found offsets prepare to advance - if((eSum < 100) && (c > 10) && (eSample >= 10)) break; // Advance to next Loop - delay(1); - } - Serial.write('.'); - kP *= .75; - kI *= .75; - for (int i = 0; i < 3; i++){ - if(SaveAddress != 0x13) { - Data = round((ITerm[i] ) / 8); //Compute PID Output - Data = ((Data)&0xFFFE) |BitZero[i]; // Insert Bit0 Saved at beginning - } else Data = round((ITerm[i]) / 4); - I2Cdev::writeWords(devAddr, SaveAddress + (i * shift), 1, (uint16_t *)&Data); - } - } - resetFIFO(); - resetDMP(); -} - -#define printfloatx(Name,Variable,Spaces,Precision,EndTxt) { Serial.print(F(Name)); {char S[(Spaces + Precision + 3)];Serial.print(F(" ")); Serial.print(dtostrf((float)Variable,Spaces,Precision ,S));}Serial.print(F(EndTxt)); }//Name,Variable,Spaces,Precision,EndTxt -void MPU6050::PrintActiveOffsets() { - uint8_t AOffsetRegister = (getDeviceID() < 0x38 )? (MPU6050_IMU::MPU6050_RA_XA_OFFS_H):0x77; - int16_t Data[3]; - //Serial.print(F("Offset Register 0x")); - //Serial.print(AOffsetRegister>>4,HEX);Serial.print(AOffsetRegister&0x0F,HEX); - Serial.print(F("\n// X Accel Y Accel Z Accel X Gyro Y Gyro Z Gyro\n//OFFSETS ")); - if(AOffsetRegister == 0x06) I2Cdev::readWords(devAddr, AOffsetRegister, 3, (uint16_t *)Data); - else { - I2Cdev::readWords(devAddr, AOffsetRegister, 1, (uint16_t *)Data); - I2Cdev::readWords(devAddr, AOffsetRegister+3, 1, (uint16_t *)Data+1); - I2Cdev::readWords(devAddr, AOffsetRegister+6, 1, (uint16_t *)Data+2); - } - // A_OFFSET_H_READ_A_OFFS(Data); - printfloatx("", Data[0], 5, 0, ", "); - printfloatx("", Data[1], 5, 0, ", "); - printfloatx("", Data[2], 5, 0, ", "); - I2Cdev::readWords(devAddr, 0x13, 3, (uint16_t *)Data); - // XG_OFFSET_H_READ_OFFS_USR(Data); - printfloatx("", Data[0], 5, 0, ", "); - printfloatx("", Data[1], 5, 0, ", "); - printfloatx("", Data[2], 5, 0, "\n"); -} diff --git a/mpu6050-master/src/MPU6050.h b/mpu6050-master/src/MPU6050.h deleted file mode 100644 index 15d3be6f21da82552d8e48ead1541843eb22b397..0000000000000000000000000000000000000000 --- a/mpu6050-master/src/MPU6050.h +++ /dev/null @@ -1,1181 +0,0 @@ -// I2Cdev library collection - MPU6050 I2C device class -// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) -// 10/3/2011 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// ... - ongoing debug release - -// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE -// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF -// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING. - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -#ifndef _MPU6050_H_ -#define _MPU6050_H_ - -#include "I2Cdev.h" - -// supporting link: http://forum.arduino.cc/index.php?&topic=143444.msg1079517#msg1079517 -// also: http://forum.arduino.cc/index.php?&topic=141571.msg1062899#msg1062899s - -#ifdef __AVR__ -#include <avr/pgmspace.h> -#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_RENESAS) -#include <avr/dtostrf.h> - #ifndef BUFFER_LENGTH - #define BUFFER_LENGTH 32 - #endif -#else -//#define PROGMEM /* empty */ -//#define pgm_read_byte(x) (*(x)) -//#define pgm_read_word(x) (*(x)) -//#define pgm_read_float(x) (*(x)) -//#define PSTR(STR) STR -#endif - - - - -/****************************************************************************************************************************************/ - -namespace MPU6050_IMU{ - /*integer type cast for variable*/ - // #define uint_cast(x) static_cast<uint8_t>(x) - - /****************************MPU6050 Address definitions*******************************/ - - constexpr uint8_t MPU6050_ADDRESS_AD0_LOW = 0x68; // address pin low (GND), default for InvenSense evaluation board - constexpr uint8_t MPU6050_ADDRESS_AD0_HIGH = 0x69; // address pin high (VCC) - constexpr uint8_t MPU6050_DEFAULT_ADDRESS = MPU6050_ADDRESS_AD0_LOW; - - /******************************MPU6050 Registers******************************/ - - enum MPU6050_REG{ - MPU6050_RA_XG_OFFS_TC = 0x00, - MPU6050_RA_YG_OFFS_TC, - MPU6050_RA_ZG_OFFS_TC, - MPU6050_RA_X_FINE_GAIN, - MPU6050_RA_Y_FINE_GAIN, - MPU6050_RA_Z_FINE_GAIN, - MPU6050_RA_XA_OFFS_H, - MPU6050_RA_XA_OFFS_L_TC, - MPU6050_RA_YA_OFFS_H, - MPU6050_RA_YA_OFFS_L_TC, - MPU6050_RA_ZA_OFFS_H = 0x0A, - MPU6050_RA_ZA_OFFS_L_TC, - MPU6050_RA_SELF_TEST_X = 0x0D, - MPU6050_RA_SELF_TEST_Y, - MPU6050_RA_SELF_TEST_Z, - MPU6050_RA_SELF_TEST_A = 0x10, - MPU6050_RA_XG_OFFS_USRH = 0x13, - MPU6050_RA_XG_OFFS_USRL, - MPU6050_RA_YG_OFFS_USRH, - MPU6050_RA_YG_OFFS_USRL, - MPU6050_RA_ZG_OFFS_USRH, - MPU6050_RA_ZG_OFFS_USRL, - MPU6050_RA_SMPLRT_DIV, - MPU6050_RA_CONFIG = 0x1A, - MPU6050_RA_GYRO_CONFIG, - MPU6050_RA_ACCEL_CONFIG, - MPU6050_RA_FF_THR, - MPU6050_RA_FF_DUR, - MPU6050_RA_MOT_THR, - MPU6050_RA_MOT_DUR = 0x20, - MPU6050_RA_ZRMOT_THR, - MPU6050_RA_ZRMOT_DUR, - MPU6050_RA_FIFO_EN, - MPU6050_RA_I2C_MST_CTRL, - MPU6050_RA_I2C_SLV0_ADDR, - MPU6050_RA_I2C_SLV0_REG, - MPU6050_RA_I2C_SLV0_CTRL, - MPU6050_RA_I2C_SLV1_ADDR, - MPU6050_RA_I2C_SLV1_REG, - MPU6050_RA_I2C_SLV1_CTRL = 0x2A, - MPU6050_RA_I2C_SLV2_ADDR, - MPU6050_RA_I2C_SLV2_REG, - MPU6050_RA_I2C_SLV2_CTRL, - MPU6050_RA_I2C_SLV3_ADDR, - MPU6050_RA_I2C_SLV3_REG, - MPU6050_RA_I2C_SLV3_CTRL = 0x30, - MPU6050_RA_I2C_SLV4_ADDR, - MPU6050_RA_I2C_SLV4_REG, - MPU6050_RA_I2C_SLV4_DO, - MPU6050_RA_I2C_SLV4_CTRL, - MPU6050_RA_I2C_SLV4_DI, - MPU6050_RA_I2C_MST_STATUS, - MPU6050_RA_INT_PIN_CFG, - MPU6050_RA_INT_ENABLE, - MPU6050_RA_DMP_INT_STATUS, - MPU6050_RA_INT_STATUS = 0x3A, - MPU6050_RA_ACCEL_XOUT_H, - MPU6050_RA_ACCEL_XOUT_L, - MPU6050_RA_ACCEL_YOUT_H, - MPU6050_RA_ACCEL_YOUT_L, - MPU6050_RA_ACCEL_ZOUT_H, - MPU6050_RA_ACCEL_ZOUT_L = 0x40, - MPU6050_RA_TEMP_OUT_H, - MPU6050_RA_TEMP_OUT_L, - MPU6050_RA_GYRO_XOUT_H, - MPU6050_RA_GYRO_XOUT_L, - MPU6050_RA_GYRO_YOUT_H, - MPU6050_RA_GYRO_YOUT_L, - MPU6050_RA_GYRO_ZOUT_H, - MPU6050_RA_GYRO_ZOUT_L, - MPU6050_RA_EXT_SENS_DATA_00, - MPU6050_RA_EXT_SENS_DATA_01 = 0x4A, - MPU6050_RA_EXT_SENS_DATA_02, - MPU6050_RA_EXT_SENS_DATA_03, - MPU6050_RA_EXT_SENS_DATA_04, - MPU6050_RA_EXT_SENS_DATA_05, - MPU6050_RA_EXT_SENS_DATA_06, - MPU6050_RA_EXT_SENS_DATA_07 = 0x50, - MPU6050_RA_EXT_SENS_DATA_08, - MPU6050_RA_EXT_SENS_DATA_09, - MPU6050_RA_EXT_SENS_DATA_10, - MPU6050_RA_EXT_SENS_DATA_11, - MPU6050_RA_EXT_SENS_DATA_12, - MPU6050_RA_EXT_SENS_DATA_13, - MPU6050_RA_EXT_SENS_DATA_14, - MPU6050_RA_EXT_SENS_DATA_15, - MPU6050_RA_EXT_SENS_DATA_16, - MPU6050_RA_EXT_SENS_DATA_17 = 0x5A, - MPU6050_RA_EXT_SENS_DATA_18, - MPU6050_RA_EXT_SENS_DATA_19, - MPU6050_RA_EXT_SENS_DATA_20, - MPU6050_RA_EXT_SENS_DATA_21, - MPU6050_RA_EXT_SENS_DATA_22, - MPU6050_RA_EXT_SENS_DATA_23 = 0x60, - MPU6050_RA_MOT_DETECT_STATUS, - MPU6050_RA_I2C_SLV0_DO = 0x63, - MPU6050_RA_I2C_SLV1_DO, - MPU6050_RA_I2C_SLV2_DO, - MPU6050_RA_I2C_SLV3_DO, - MPU6050_RA_I2C_MST_DELAY_CTRL, - MPU6050_RA_SIGNAL_PATH_RESET, - MPU6050_RA_MOT_DETECT_CTRL, - MPU6050_RA_USER_CTRL = 0x6A, - MPU6050_RA_PWR_MGMT_1, - MPU6050_RA_PWR_MGMT_2, - MPU6050_RA_BANK_SEL, - MPU6050_RA_MEM_START_ADDR, - MPU6050_RA_MEM_R_W, - MPU6050_RA_DMP_CFG_1 = 0x70, - MPU6050_RA_DMP_CFG_2, - MPU6050_RA_FIFO_COUNTH, - MPU6050_RA_FIFO_COUNTL, - MPU6050_RA_FIFO_R_W, - MPU6050_RA_WHO_AM_I - - }; - - /**********************SELF TEST definitions************************/ - - constexpr uint8_t MPU6050_SELF_TEST_XA_1_LENGTH = 0x03; - constexpr uint8_t MPU6050_SELF_TEST_XA_2_LENGTH = 0x02; - - constexpr uint8_t MPU6050_SELF_TEST_YA_1_LENGTH = 0x03; - constexpr uint8_t MPU6050_SELF_TEST_YA_2_LENGTH = 0x02; - - constexpr uint8_t MPU6050_SELF_TEST_ZA_1_LENGTH = 0x03; - constexpr uint8_t MPU6050_SELF_TEST_ZA_2_LENGTH = 0x02; - - constexpr uint8_t MPU6050_SELF_TEST_XG_1_LENGTH = 0x05; - constexpr uint8_t MPU6050_SELF_TEST_YG_1_LENGTH = 0x05; - constexpr uint8_t MPU6050_SELF_TEST_ZG_1_LENGTH = 0x05; - - enum SELF_TEST_REG_BIT{ - MPU6050_SELF_TEST_XA_1_BIT = 0x07, - MPU6050_SELF_TEST_XA_2_BIT = 0x05, - MPU6050_SELF_TEST_YA_1_BIT = 0x07, - MPU6050_SELF_TEST_YA_2_BIT = 0x03, - MPU6050_SELF_TEST_ZA_1_BIT = 0x07, - MPU6050_SELF_TEST_ZA_2_BIT = 0x01, - MPU6050_SELF_TEST_XG_1_BIT = 0x04, - MPU6050_SELF_TEST_YG_1_BIT = 0x04, - MPU6050_SELF_TEST_ZG_1_BIT = 0x04 - }; - - /*************************OFFSET definitions************************/ - - constexpr uint8_t MPU6050_TC_OFFSET_LENGTH = 6; - constexpr uint8_t MPU6050_VDDIO_LEVEL_VLOGIC = 0; - constexpr uint8_t MPU6050_VDDIO_LEVEL_VDD = 1; - - enum OFFS_TC_REG_BIT{ - MPU6050_TC_OTP_BNK_VLD_BIT = 0, - MPU6050_TC_OFFSET_BIT = 6, - MPU6050_TC_PWR_MODE_BIT, - }; - - /****************************CONFIG definitions**************************/ - - constexpr uint8_t MPU6050_CFG_EXT_SYNC_SET_LENGTH = 3; - constexpr uint8_t MPU6050_CFG_DLPF_CFG_LENGTH = 3; - - enum CONFIG_REG_BIT{ - MPU6050_CFG_DLPF_CFG_BIT = 2, - MPU6050_CFG_EXT_SYNC_SET_BIT = 5, - }; - - enum EXT_SYNC_SET{ - MPU6050_EXT_SYNC_DISABLED = 0x00, - MPU6050_EXT_SYNC_TEMP_OUT_L, - MPU6050_EXT_SYNC_GYRO_XOUT_L, - MPU6050_EXT_SYNC_GYRO_YOUT_L, - MPU6050_EXT_SYNC_GYRO_ZOUT_L, - MPU6050_EXT_SYNC_ACCEL_XOUT_L, - MPU6050_EXT_SYNC_ACCEL_YOUT_L, - MPU6050_EXT_SYNC_ACCEL_ZOUT_L, - }; - - enum DLPF_CFG{ - MPU6050_DLPF_BW_256 = 0x00, - MPU6050_DLPF_BW_188, - MPU6050_DLPF_BW_98, - MPU6050_DLPF_BW_42, - MPU6050_DLPF_BW_20, - MPU6050_DLPF_BW_10, - MPU6050_DLPF_BW_5, - }; - - /*****************************GYRO_CONFIG definitions****************************/ - - constexpr uint8_t MPU6050_GCONFIG_FS_SEL_LENGTH = 2; - - enum GYRO_CONFIG_REG_BIT{ - MPU6050_GCONFIG_FS_SEL_BIT = 4, - MPU6050_ACONFIG_ZG_ST_BIT, - MPU6050_ACONFIG_YG_ST_BIT, - MPU6050_ACONFIG_XG_ST_BIT, - }; - - enum GYRO_FS{ - MPU6050_GYRO_FS_250 = 0x00, - MPU6050_GYRO_FS_500, - MPU6050_GYRO_FS_1000, - MPU6050_GYRO_FS_2000, - }; - - /*******************************ACCEL_CONFIG definitions**************************/ - - constexpr uint8_t MPU6050_ACONFIG_AFS_SEL_LENGTH = 2; - constexpr uint8_t MPU6050_ACONFIG_ACCEL_HPF_LENGTH = 3; - - enum ACCEL_CONFIG_REG_BIT{ - MPU6050_ACONFIG_ACCEL_HPF_BIT = 2, - MPU6050_ACONFIG_AFS_SEL_BIT = 4, - MPU6050_ACONFIG_ZA_ST_BIT, - MPU6050_ACONFIG_YA_ST_BIT, - MPU6050_ACONFIG_XA_ST_BIT - }; - - enum ACCEL_FS{ - MPU6050_ACCEL_FS_2 = 0x00, - MPU6050_ACCEL_FS_4, - MPU6050_ACCEL_FS_8, - MPU6050_ACCEL_FS_16, - }; - - enum ACCEL_HPF{ - MPU6050_DHPF_RESET = 0x00, - MPU6050_DHPF_5, - MPU6050_DHPF_2P5, - MPU6050_DHPF_1P25, - MPU6050_DHPF_0P63, - MPU6050_DHPF_HOLD = 0x07, - }; - - /***********************************FIFO_EN definitions*************************/ - - enum FIFO_EN_REG_BIT{ - MPU6050_SLV0_FIFO_EN_BIT = 0, - MPU6050_SLV1_FIFO_EN_BIT, - MPU6050_SLV2_FIFO_EN_BIT, - MPU6050_ACCEL_FIFO_EN_BIT, - MPU6050_ZG_FIFO_EN_BIT, - MPU6050_YG_FIFO_EN_BIT, - MPU6050_XG_FIFO_EN_BIT, - MPU6050_TEMP_FIFO_EN_BIT, - }; - - /**********************************I2C_MST_CTRL definitions***************************/ - - constexpr uint8_t MPU6050_I2C_MST_CLK_LENGTH = 4; - - enum I2C_MST_CTRL_REG_BIT{ - MPU6050_I2C_MST_CLK_BIT = 3, - MPU6050_I2C_MST_P_NSR_BIT, - MPU6050_SLV_3_FIFO_EN_BIT, - MPU6050_WAIT_FOR_ES_BIT, - MPU6050_MULT_MST_EN_BIT, - }; - - enum I2C_Prescaler{ - MPU6050_CLOCK_DIV_348 = 0x0, - MPU6050_CLOCK_DIV_333, - MPU6050_CLOCK_DIV_320, - MPU6050_CLOCK_DIV_308, - MPU6050_CLOCK_DIV_296, - MPU6050_CLOCK_DIV_286, - MPU6050_CLOCK_DIV_276, - MPU6050_CLOCK_DIV_267, - MPU6050_CLOCK_DIV_258, - MPU6050_CLOCK_DIV_500, - MPU6050_CLOCK_DIV_471 = 0xA, - MPU6050_CLOCK_DIV_444, - MPU6050_CLOCK_DIV_421, - MPU6050_CLOCK_DIV_400, - MPU6050_CLOCK_DIV_381, - MPU6050_CLOCK_DIV_364, - }; - - /*********************************I2C_SLVx_ADDR definitions*****************************/ - - constexpr uint8_t MPU6050_I2C_SLV_ADDR_LENGTH = 7; - constexpr uint8_t MPU6050_I2C_SLV_LEN_LENGTH = 4; - - enum I2C_SLVx_ADDR_REG_BIT{ - MPU6050_I2C_SLV_ADDR_BIT = 6, - MPU6050_I2C_SLV_RW_BIT, - }; - - - /****************************I2C_SLVx_CTRL definitions (x=0,1,2,3)***********************/ - - enum I2C_SLVx_CTRL_REG_BIT{ - MPU6050_I2C_SLV_LEN_BIT = 3, - MPU6050_I2C_SLV_GRP_BIT, - MPU6050_I2C_SLV_REG_DIS_BIT, - MPU6050_I2C_SLV_BYTE_SW_BIT, - MPU6050_I2C_SLV_EN_BIT - }; - - /******************************I2C_SLV4_ADDR definitions*************************/ - - constexpr uint8_t MPU6050_I2C_SLV4_ADDR_LENGTH = 7; - - enum I2C_SLV4_ADDR_REG_BIT{ - MPU6050_I2C_SLV4_ADDR_BIT = 6, - MPU6050_I2C_SLV4_RW_BIT, - }; - - /*********************************I2C_SLV4_CTRL definitions************************/ - - constexpr uint8_t MPU6050_I2C_SLV4_MST_DLY_LENGTH = 5; - - enum I2C_SLV4_CTRL_REG_BIT{ - MPU6050_I2C_SLV4_MST_DLY_BIT = 4, - MPU6050_I2C_SLV4_REG_DIS_BIT, - MPU6050_I2C_SLV4_INT_EN_BIT, - MPU6050_I2C_SLV4_EN_BIT, - }; - - /*******************************I2C_MST_STATUS definitions************************/ - - enum I2C_MST_STATUS_REG_BIT{ - MPU6050_MST_I2C_SLV0_NACK_BIT = 0, - MPU6050_MST_I2C_SLV1_NACK_BIT, - MPU6050_MST_I2C_SLV2_NACK_BIT, - MPU6050_MST_I2C_SLV3_NACK_BIT, - MPU6050_MST_I2C_SLV4_NACK_BIT, - MPU6050_MST_I2C_LOST_ARB_BIT, - MPU6050_MST_I2C_SLV4_DONE_BIT, - MPU6050_MST_PASS_THROUGH_BIT, - }; - - /***********************************INT_PIN_CFG definitions***************************/ - - constexpr uint8_t MPU6050_INTMODE_ACTIVEHIGH = 0x00; - constexpr uint8_t MPU6050_INTMODE_ACTIVELOW = 0x01; - - constexpr uint8_t MPU6050_INTDRV_PUSHPULL = 0x00; - constexpr uint8_t MPU6050_INTDRV_OPENDRAIN = 0x01; - - constexpr uint8_t MPU6050_INTLATCH_50USPULSE = 0x00; - constexpr uint8_t MPU6050_INTLATCH_WAITCLEAR = 0x01; - - constexpr uint8_t MPU6050_INTCLEAR_STATUSREAD = 0x00; - constexpr uint8_t MPU6050_INTCLEAR_ANYREAD = 0x01; - - enum INT_PIN_CFG_REG_BIT{ - MPU6050_INTCFG_CLKOUT_EN_BIT = 0, - MPU6050_INTCFG_I2C_BYPASS_EN_BIT, - MPU6050_INTCFG_FSYNC_INT_EN_BIT, - MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT, - MPU6050_INTCFG_INT_RD_CLEAR_BIT, - MPU6050_INTCFG_LATCH_INT_EN_BIT, - MPU6050_INTCFG_INT_OPEN_BIT, - MPU6050_INTCFG_INT_LEVEL_BIT, - }; - - /*********************************INT_STATUS definitions**************************/ - - enum INT_STATUS_REG_BIT{ - MPU6050_INTERRUPT_DATA_RDY_BIT = 0, - MPU6050_INTERRUPT_DMP_INT_BIT, - MPU6050_INTERRUPT_PLL_RDY_INT_BIT, - MPU6050_INTERRUPT_I2C_MST_INT_BIT, - MPU6050_INTERRUPT_FIFO_OFLOW_BIT, - MPU6050_INTERRUPT_ZMOT_BIT, - MPU6050_INTERRUPT_MOT_BIT, - MPU6050_INTERRUPT_FF_BIT, - }; - - // TODO: figure out what these actually do - // UMPL source code is not very obivous - - /***************************DMP_INT_STATUS definitions***************************/ - - enum DMP_INT_STATUS_REG_BIT{ - MPU6050_DMPINT_0_BIT = 0, - MPU6050_DMPINT_1_BIT, - MPU6050_DMPINT_2_BIT, - MPU6050_DMPINT_3_BIT, - MPU6050_DMPINT_4_BIT, - MPU6050_DMPINT_5_BIT, - }; - - /***************************MOT_DETECT_STATUS definitions*************************/ - - enum MOT_DETECT_STATUS_REG_BIT{ - MPU6050_MOTION_MOT_ZRMOT_BIT = 0, - MPU6050_MOTION_MOT_ZPOS_BIT = 2, - MPU6050_MOTION_MOT_ZNEG_BIT, - MPU6050_MOTION_MOT_YPOS_BIT, - MPU6050_MOTION_MOT_YNEG_BIT, - MPU6050_MOTION_MOT_XPOS_BIT, - MPU6050_MOTION_MOT_XNEG_BIT, - }; - - /*****************************I2C_MST_DELAY_CTRL definitions************************/ - - enum I2C_MST_DELAY_CTRL_REG_BIT{ - MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT = 0, - MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT, - MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT, - MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT, - MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT, - MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT = 7, - }; - - /*****************************SIGNAL_PATH_RESET definitions**************************/ - - enum SIGNAL_PATH_RESET_REG_BIT{ - MPU6050_PATHRESET_TEMP_RESET_BIT = 0, - MPU6050_PATHRESET_ACCEL_RESET_BIT, - MPU6050_PATHRESET_GYRO_RESET_BIT - }; - - /***************************MOT_DETECT_CTRL definitions*****************************/ - - constexpr uint8_t MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH = 2; - constexpr uint8_t MPU6050_DETECT_FF_COUNT_LENGTH = 2; - constexpr uint8_t MPU6050_DETECT_MOT_COUNT_LENGTH = 2; - - enum MOT_DETECT_CTRL_REG_BIT{ - MPU6050_DETECT_MOT_COUNT_BIT = 1, - MPU6050_DETECT_FF_COUNT_BIT = 3, - MPU6050_DETECT_ACCEL_ON_DELAY_BIT = 5, - }; - - /********************************USER_CTRL definitions******************************/ - - enum USER_CTRL_REG_BIT{ - MPU6050_USERCTRL_SIG_COND_RESET_BIT = 0, - MPU6050_USERCTRL_I2C_MST_RESET_BIT, - MPU6050_USERCTRL_FIFO_RESET_BIT, - MPU6050_USERCTRL_DMP_RESET_BIT, - MPU6050_USERCTRL_I2C_IF_DIS_BIT, - MPU6050_USERCTRL_I2C_MST_EN_BIT, - MPU6050_USERCTRL_FIFO_EN_BIT, - MPU6050_USERCTRL_DMP_EN_BIT - }; - - - /*********************************PWR_MGMT_1 definitions*******************************/ - - constexpr uint8_t MPU6050_PWR1_CLKSEL_LENGTH = 3; - - enum PWR_MGMT_1_REG_BIT{ - MPU6050_PWR1_CLKSEL_BIT = 2, - MPU6050_PWR1_TEMP_DIS_BIT, - MPU6050_PWR1_CYCLE_BIT = 5, - MPU6050_PWR1_SLEEP_BIT, - MPU6050_PWR1_DEVICE_RESET_BIT, - }; - - - enum CLK_SRC{ - MPU6050_CLOCK_INTERNAL = 0x00, - MPU6050_CLOCK_PLL_XGYRO, - MPU6050_CLOCK_PLL_YGYRO, - MPU6050_CLOCK_PLL_ZGYRO, - MPU6050_CLOCK_PLL_EXT32K, - MPU6050_CLOCK_PLL_EXT19M, - MPU6050_CLOCK_KEEP_RESET = 0x07, - }; - - /*****************************PWR_MGMT_2 definitions****************************/ - - constexpr uint8_t MPU6050_PWR2_LP_WAKE_CTRL_LENGTH = 2; - - enum PWR_MGMT_2_REG_BIT{ - MPU6050_PWR2_STBY_ZG_BIT = 0, - MPU6050_PWR2_STBY_YG_BIT, - MPU6050_PWR2_STBY_XG_BIT, - MPU6050_PWR2_STBY_ZA_BIT, - MPU6050_PWR2_STBY_YA_BIT, - MPU6050_PWR2_STBY_XA_BIT, - MPU6050_PWR2_LP_WAKE_CTRL_BIT = 7, - }; - - enum WAKE_FREQ{ - MPU6050_WAKE_FREQ_1P25 = 0x0, - MPU6050_WAKE_FREQ_2P5, - MPU6050_WAKE_FREQ_5, - MPU6050_WAKE_FREQ_10, - }; - - /*WHO_AM_I definitions*/ - constexpr uint8_t MPU6050_WHO_AM_I_BIT = 6; - constexpr uint8_t MPU6050_WHO_AM_I_LENGTH = 6; - - /*memory block definitions*/ - constexpr uint8_t MPU6050_DMP_MEMORY_BANKS = 8; - constexpr uint16_t MPU6050_DMP_MEMORY_BANK_SIZE = 256; - constexpr uint8_t MPU6050_DMP_MEMORY_CHUNK_SIZE = 16; -}; - - -// note: DMP code memory blocks defined at end of header file - -class MPU6050 { - public: - MPU6050(uint8_t address=(MPU6050_IMU::MPU6050_DEFAULT_ADDRESS)); - - void initialize(); - bool testConnection(); - - // AUX_VDDIO register - uint8_t getAuxVDDIOLevel(); - void setAuxVDDIOLevel(uint8_t level); - - // SMPLRT_DIV register - uint8_t getRate(); - void setRate(uint8_t rate); - - // CONFIG register - uint8_t getExternalFrameSync(); - void setExternalFrameSync(uint8_t sync); - uint8_t getDLPFMode(); - void setDLPFMode(uint8_t bandwidth); - - // GYRO_CONFIG register - uint8_t getFullScaleGyroRange(); - void setFullScaleGyroRange(uint8_t range); - - // SELF_TEST registers - uint8_t getAccelXSelfTestFactoryTrim(); - uint8_t getAccelYSelfTestFactoryTrim(); - uint8_t getAccelZSelfTestFactoryTrim(); - - uint8_t getGyroXSelfTestFactoryTrim(); - uint8_t getGyroYSelfTestFactoryTrim(); - uint8_t getGyroZSelfTestFactoryTrim(); - - // ACCEL_CONFIG register - bool getAccelXSelfTest(); - void setAccelXSelfTest(bool enabled); - bool getAccelYSelfTest(); - void setAccelYSelfTest(bool enabled); - bool getAccelZSelfTest(); - void setAccelZSelfTest(bool enabled); - uint8_t getFullScaleAccelRange(); - void setFullScaleAccelRange(uint8_t range); - uint8_t getDHPFMode(); - void setDHPFMode(uint8_t mode); - - // FF_THR register - uint8_t getFreefallDetectionThreshold(); - void setFreefallDetectionThreshold(uint8_t threshold); - - // FF_DUR register - uint8_t getFreefallDetectionDuration(); - void setFreefallDetectionDuration(uint8_t duration); - - // MOT_THR register - uint8_t getMotionDetectionThreshold(); - void setMotionDetectionThreshold(uint8_t threshold); - - // MOT_DUR register - uint8_t getMotionDetectionDuration(); - void setMotionDetectionDuration(uint8_t duration); - - // ZRMOT_THR register - uint8_t getZeroMotionDetectionThreshold(); - void setZeroMotionDetectionThreshold(uint8_t threshold); - - // ZRMOT_DUR register - uint8_t getZeroMotionDetectionDuration(); - void setZeroMotionDetectionDuration(uint8_t duration); - - // FIFO_EN register - bool getTempFIFOEnabled(); - void setTempFIFOEnabled(bool enabled); - bool getXGyroFIFOEnabled(); - void setXGyroFIFOEnabled(bool enabled); - bool getYGyroFIFOEnabled(); - void setYGyroFIFOEnabled(bool enabled); - bool getZGyroFIFOEnabled(); - void setZGyroFIFOEnabled(bool enabled); - bool getAccelFIFOEnabled(); - void setAccelFIFOEnabled(bool enabled); - bool getSlave2FIFOEnabled(); - void setSlave2FIFOEnabled(bool enabled); - bool getSlave1FIFOEnabled(); - void setSlave1FIFOEnabled(bool enabled); - bool getSlave0FIFOEnabled(); - void setSlave0FIFOEnabled(bool enabled); - - // I2C_MST_CTRL register - bool getMultiMasterEnabled(); - void setMultiMasterEnabled(bool enabled); - bool getWaitForExternalSensorEnabled(); - void setWaitForExternalSensorEnabled(bool enabled); - bool getSlave3FIFOEnabled(); - void setSlave3FIFOEnabled(bool enabled); - bool getSlaveReadWriteTransitionEnabled(); - void setSlaveReadWriteTransitionEnabled(bool enabled); - uint8_t getMasterClockSpeed(); - void setMasterClockSpeed(uint8_t speed); - - // I2C_SLV* registers (Slave 0-3) - uint8_t getSlaveAddress(uint8_t num); - void setSlaveAddress(uint8_t num, uint8_t address); - uint8_t getSlaveRegister(uint8_t num); - void setSlaveRegister(uint8_t num, uint8_t reg); - bool getSlaveEnabled(uint8_t num); - void setSlaveEnabled(uint8_t num, bool enabled); - bool getSlaveWordByteSwap(uint8_t num); - void setSlaveWordByteSwap(uint8_t num, bool enabled); - bool getSlaveWriteMode(uint8_t num); - void setSlaveWriteMode(uint8_t num, bool mode); - bool getSlaveWordGroupOffset(uint8_t num); - void setSlaveWordGroupOffset(uint8_t num, bool enabled); - uint8_t getSlaveDataLength(uint8_t num); - void setSlaveDataLength(uint8_t num, uint8_t length); - - // I2C_SLV* registers (Slave 4) - uint8_t getSlave4Address(); - void setSlave4Address(uint8_t address); - uint8_t getSlave4Register(); - void setSlave4Register(uint8_t reg); - void setSlave4OutputByte(uint8_t data); - bool getSlave4Enabled(); - void setSlave4Enabled(bool enabled); - bool getSlave4InterruptEnabled(); - void setSlave4InterruptEnabled(bool enabled); - bool getSlave4WriteMode(); - void setSlave4WriteMode(bool mode); - uint8_t getSlave4MasterDelay(); - void setSlave4MasterDelay(uint8_t delay); - uint8_t getSlate4InputByte(); - - // I2C_MST_STATUS register - bool getPassthroughStatus(); - bool getSlave4IsDone(); - bool getLostArbitration(); - bool getSlave4Nack(); - bool getSlave3Nack(); - bool getSlave2Nack(); - bool getSlave1Nack(); - bool getSlave0Nack(); - - // INT_PIN_CFG register - bool getInterruptMode(); - void setInterruptMode(bool mode); - bool getInterruptDrive(); - void setInterruptDrive(bool drive); - bool getInterruptLatch(); - void setInterruptLatch(bool latch); - bool getInterruptLatchClear(); - void setInterruptLatchClear(bool clear); - bool getFSyncInterruptLevel(); - void setFSyncInterruptLevel(bool level); - bool getFSyncInterruptEnabled(); - void setFSyncInterruptEnabled(bool enabled); - bool getI2CBypassEnabled(); - void setI2CBypassEnabled(bool enabled); - bool getClockOutputEnabled(); - void setClockOutputEnabled(bool enabled); - - // INT_ENABLE register - uint8_t getIntEnabled(); - void setIntEnabled(uint8_t enabled); - bool getIntFreefallEnabled(); - void setIntFreefallEnabled(bool enabled); - bool getIntMotionEnabled(); - void setIntMotionEnabled(bool enabled); - bool getIntZeroMotionEnabled(); - void setIntZeroMotionEnabled(bool enabled); - bool getIntFIFOBufferOverflowEnabled(); - void setIntFIFOBufferOverflowEnabled(bool enabled); - bool getIntI2CMasterEnabled(); - void setIntI2CMasterEnabled(bool enabled); - bool getIntDataReadyEnabled(); - void setIntDataReadyEnabled(bool enabled); - - // INT_STATUS register - uint8_t getIntStatus(); - bool getIntFreefallStatus(); - bool getIntMotionStatus(); - bool getIntZeroMotionStatus(); - bool getIntFIFOBufferOverflowStatus(); - bool getIntI2CMasterStatus(); - bool getIntDataReadyStatus(); - - // ACCEL_*OUT_* registers - void getMotion9(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz, int16_t* mx, int16_t* my, int16_t* mz); - void getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz); - void getAcceleration(int16_t* x, int16_t* y, int16_t* z); - int16_t getAccelerationX(); - int16_t getAccelerationY(); - int16_t getAccelerationZ(); - - // TEMP_OUT_* registers - int16_t getTemperature(); - - // GYRO_*OUT_* registers - void getRotation(int16_t* x, int16_t* y, int16_t* z); - int16_t getRotationX(); - int16_t getRotationY(); - int16_t getRotationZ(); - - // EXT_SENS_DATA_* registers - uint8_t getExternalSensorByte(int position); - uint16_t getExternalSensorWord(int position); - uint32_t getExternalSensorDWord(int position); - - // MOT_DETECT_STATUS register - uint8_t getMotionStatus(); - bool getXNegMotionDetected(); - bool getXPosMotionDetected(); - bool getYNegMotionDetected(); - bool getYPosMotionDetected(); - bool getZNegMotionDetected(); - bool getZPosMotionDetected(); - bool getZeroMotionDetected(); - - // I2C_SLV*_DO register - void setSlaveOutputByte(uint8_t num, uint8_t data); - - // I2C_MST_DELAY_CTRL register - bool getExternalShadowDelayEnabled(); - void setExternalShadowDelayEnabled(bool enabled); - bool getSlaveDelayEnabled(uint8_t num); - void setSlaveDelayEnabled(uint8_t num, bool enabled); - - // SIGNAL_PATH_RESET register - void resetGyroscopePath(); - void resetAccelerometerPath(); - void resetTemperaturePath(); - - // MOT_DETECT_CTRL register - uint8_t getAccelerometerPowerOnDelay(); - void setAccelerometerPowerOnDelay(uint8_t delay); - uint8_t getFreefallDetectionCounterDecrement(); - void setFreefallDetectionCounterDecrement(uint8_t decrement); - uint8_t getMotionDetectionCounterDecrement(); - void setMotionDetectionCounterDecrement(uint8_t decrement); - - // USER_CTRL register - bool getFIFOEnabled(); - void setFIFOEnabled(bool enabled); - bool getI2CMasterModeEnabled(); - void setI2CMasterModeEnabled(bool enabled); - void switchSPIEnabled(bool enabled); - void resetFIFO(); - void resetI2CMaster(); - void resetSensors(); - - // PWR_MGMT_1 register - void reset(); - bool getSleepEnabled(); - void setSleepEnabled(bool enabled); - bool getWakeCycleEnabled(); - void setWakeCycleEnabled(bool enabled); - bool getTempSensorEnabled(); - void setTempSensorEnabled(bool enabled); - uint8_t getClockSource(); - void setClockSource(uint8_t source); - - // PWR_MGMT_2 register - uint8_t getWakeFrequency(); - void setWakeFrequency(uint8_t frequency); - bool getStandbyXAccelEnabled(); - void setStandbyXAccelEnabled(bool enabled); - bool getStandbyYAccelEnabled(); - void setStandbyYAccelEnabled(bool enabled); - bool getStandbyZAccelEnabled(); - void setStandbyZAccelEnabled(bool enabled); - bool getStandbyXGyroEnabled(); - void setStandbyXGyroEnabled(bool enabled); - bool getStandbyYGyroEnabled(); - void setStandbyYGyroEnabled(bool enabled); - bool getStandbyZGyroEnabled(); - void setStandbyZGyroEnabled(bool enabled); - - // FIFO_COUNT_* registers - uint16_t getFIFOCount(); - - // FIFO_R_W register - uint8_t getFIFOByte(); - int8_t GetCurrentFIFOPacket(uint8_t *data, uint8_t length); - void setFIFOByte(uint8_t data); - void getFIFOBytes(uint8_t *data, uint8_t length); - - // WHO_AM_I register - uint8_t getDeviceID(); - void setDeviceID(uint8_t id); - - // ======== UNDOCUMENTED/DMP REGISTERS/METHODS ======== - - // XG_OFFS_TC register - uint8_t getOTPBankValid(); - void setOTPBankValid(bool enabled); - int8_t getXGyroOffsetTC(); - void setXGyroOffsetTC(int8_t offset); - - // YG_OFFS_TC register - int8_t getYGyroOffsetTC(); - void setYGyroOffsetTC(int8_t offset); - - // ZG_OFFS_TC register - int8_t getZGyroOffsetTC(); - void setZGyroOffsetTC(int8_t offset); - - // X_FINE_GAIN register - int8_t getXFineGain(); - void setXFineGain(int8_t gain); - - // Y_FINE_GAIN register - int8_t getYFineGain(); - void setYFineGain(int8_t gain); - - // Z_FINE_GAIN register - int8_t getZFineGain(); - void setZFineGain(int8_t gain); - - // XA_OFFS_* registers - int16_t getXAccelOffset(); - void setXAccelOffset(int16_t offset); - - // YA_OFFS_* register - int16_t getYAccelOffset(); - void setYAccelOffset(int16_t offset); - - // ZA_OFFS_* register - int16_t getZAccelOffset(); - void setZAccelOffset(int16_t offset); - - // XG_OFFS_USR* registers - int16_t getXGyroOffset(); - void setXGyroOffset(int16_t offset); - - // YG_OFFS_USR* register - int16_t getYGyroOffset(); - void setYGyroOffset(int16_t offset); - - // ZG_OFFS_USR* register - int16_t getZGyroOffset(); - void setZGyroOffset(int16_t offset); - - // INT_ENABLE register (DMP functions) - bool getIntPLLReadyEnabled(); - void setIntPLLReadyEnabled(bool enabled); - bool getIntDMPEnabled(); - void setIntDMPEnabled(bool enabled); - - // DMP_INT_STATUS - bool getDMPInt5Status(); - bool getDMPInt4Status(); - bool getDMPInt3Status(); - bool getDMPInt2Status(); - bool getDMPInt1Status(); - bool getDMPInt0Status(); - - // INT_STATUS register (DMP functions) - bool getIntPLLReadyStatus(); - bool getIntDMPStatus(); - - // USER_CTRL register (DMP functions) - bool getDMPEnabled(); - void setDMPEnabled(bool enabled); - void resetDMP(); - - // BANK_SEL register - void setMemoryBank(uint8_t bank, bool prefetchEnabled=false, bool userBank=false); - - // MEM_START_ADDR register - void setMemoryStartAddress(uint8_t address); - - // MEM_R_W register - uint8_t readMemoryByte(); - void writeMemoryByte(uint8_t data); - void readMemoryBlock(uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0); - bool writeMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0, bool verify=true, bool useProgMem=false); - bool writeProgMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0, bool verify=true); - - bool writeDMPConfigurationSet(const uint8_t *data, uint16_t dataSize, bool useProgMem=false); - bool writeProgDMPConfigurationSet(const uint8_t *data, uint16_t dataSize); - - // DMP_CFG_1 register - uint8_t getDMPConfig1(); - void setDMPConfig1(uint8_t config); - - // DMP_CFG_2 register - uint8_t getDMPConfig2(); - void setDMPConfig2(uint8_t config); - - // Calibration Routines - void CalibrateGyro(uint8_t Loops = 15); // Fine tune after setting offsets with less Loops. - void CalibrateAccel(uint8_t Loops = 15);// Fine tune after setting offsets with less Loops. - void PID(uint8_t ReadAddress, float kP,float kI, uint8_t Loops); // Does the math - void PrintActiveOffsets(); // See the results of the Calibration - - - - // special methods for MotionApps 2.0 implementation - #ifdef MPU6050_INCLUDE_DMP_MOTIONAPPS20 - - uint8_t dmpInitialize(); - bool dmpPacketAvailable(); - - uint8_t dmpSetFIFORate(uint8_t fifoRate); - uint8_t dmpGetFIFORate(); - uint8_t dmpGetSampleStepSizeMS(); - uint8_t dmpGetSampleFrequency(); - int32_t dmpDecodeTemperature(int8_t tempReg); - - // Register callbacks after a packet of FIFO data is processed - //uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); - //uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func); - uint8_t dmpRunFIFORateProcesses(); - - // Setup FIFO for various output - uint8_t dmpSendQuaternion(uint_fast16_t accuracy); - uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendPacketNumber(uint_fast16_t accuracy); - uint8_t dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); - - // Get Fixed Point data from FIFO - uint8_t dmpGetAccel(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetAccel(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetAccel(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetQuaternion(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetQuaternion(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetQuaternion(Quaternion *q, const uint8_t* packet=0); - uint8_t dmpGet6AxisQuaternion(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGet6AxisQuaternion(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGet6AxisQuaternion(Quaternion *q, const uint8_t* packet=0); - uint8_t dmpGetRelativeQuaternion(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetRelativeQuaternion(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetRelativeQuaternion(Quaternion *data, const uint8_t* packet=0); - uint8_t dmpGetGyro(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyro(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyro(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpSetLinearAccelFilterCoefficient(float coef); - uint8_t dmpGetLinearAccel(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetLinearAccel(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetLinearAccel(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity); - uint8_t dmpGetLinearAccelInWorld(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetLinearAccelInWorld(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q); - uint8_t dmpGetGyroAndAccelSensor(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyroAndAccelSensor(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyroAndAccelSensor(VectorInt16 *g, VectorInt16 *a, const uint8_t* packet=0); - uint8_t dmpGetGyroSensor(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyroSensor(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyroSensor(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetControlData(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetTemperature(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGravity(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGravity(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetGravity(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetGravity(VectorFloat *v, Quaternion *q); - uint8_t dmpGetUnquantizedAccel(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetUnquantizedAccel(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetUnquantizedAccel(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetQuantizedAccel(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetQuantizedAccel(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0); - uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0); - - uint8_t dmpGetEuler(float *data, Quaternion *q); - uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity); - - // Get Floating Point data from FIFO - uint8_t dmpGetAccelFloat(float *data, const uint8_t* packet=0); - uint8_t dmpGetQuaternionFloat(float *data, const uint8_t* packet=0); - - uint8_t dmpProcessFIFOPacket(const unsigned char *dmpData); - uint8_t dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed=NULL); - - uint8_t dmpSetFIFOProcessedCallback(void (*func) (void)); - - uint8_t dmpInitFIFOParam(); - uint8_t dmpCloseFIFO(); - uint8_t dmpSetGyroDataSource(uint8_t source); - uint8_t dmpDecodeQuantizedAccel(); - uint32_t dmpGetGyroSumOfSquare(); - uint32_t dmpGetAccelSumOfSquare(); - void dmpOverrideQuaternion(long *q); - uint16_t dmpGetFIFOPacketSize(); - uint8_t dmpGetCurrentFIFOPacket(uint8_t *data); // overflow proof - #endif - - // special methods for MotionApps 4.1 implementation - #ifdef MPU6050_INCLUDE_DMP_MOTIONAPPS41 - - uint8_t dmpInitialize(); - bool dmpPacketAvailable(); - - uint8_t dmpSetFIFORate(uint8_t fifoRate); - uint8_t dmpGetFIFORate(); - uint8_t dmpGetSampleStepSizeMS(); - uint8_t dmpGetSampleFrequency(); - int32_t dmpDecodeTemperature(int8_t tempReg); - - // Register callbacks after a packet of FIFO data is processed - //uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); - //uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func); - uint8_t dmpRunFIFORateProcesses(); - - // Setup FIFO for various output - uint8_t dmpSendQuaternion(uint_fast16_t accuracy); - uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendPacketNumber(uint_fast16_t accuracy); - uint8_t dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); - uint8_t dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); - - // Get Fixed Point data from FIFO - uint8_t dmpGetAccel(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetAccel(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetAccel(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetQuaternion(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetQuaternion(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetQuaternion(Quaternion *q, const uint8_t* packet=0); - uint8_t dmpGet6AxisQuaternion(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGet6AxisQuaternion(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGet6AxisQuaternion(Quaternion *q, const uint8_t* packet=0); - uint8_t dmpGetRelativeQuaternion(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetRelativeQuaternion(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetRelativeQuaternion(Quaternion *data, const uint8_t* packet=0); - uint8_t dmpGetGyro(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyro(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyro(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetMag(int16_t *data, const uint8_t* packet=0); - uint8_t dmpSetLinearAccelFilterCoefficient(float coef); - uint8_t dmpGetLinearAccel(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetLinearAccel(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetLinearAccel(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity); - uint8_t dmpGetLinearAccelInWorld(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetLinearAccelInWorld(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q); - uint8_t dmpGetGyroAndAccelSensor(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyroAndAccelSensor(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyroAndAccelSensor(VectorInt16 *g, VectorInt16 *a, const uint8_t* packet=0); - uint8_t dmpGetGyroSensor(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyroSensor(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetGyroSensor(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetControlData(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetTemperature(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGravity(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetGravity(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetGravity(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetGravity(VectorFloat *v, Quaternion *q); - uint8_t dmpGetUnquantizedAccel(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetUnquantizedAccel(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetUnquantizedAccel(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetQuantizedAccel(int32_t *data, const uint8_t* packet=0); - uint8_t dmpGetQuantizedAccel(int16_t *data, const uint8_t* packet=0); - uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0); - uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0); - uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0); - - uint8_t dmpGetEuler(float *data, Quaternion *q); - uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity); - - // Get Floating Point data from FIFO - uint8_t dmpGetAccelFloat(float *data, const uint8_t* packet=0); - uint8_t dmpGetQuaternionFloat(float *data, const uint8_t* packet=0); - - uint8_t dmpProcessFIFOPacket(const unsigned char *dmpData); - uint8_t dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed=NULL); - - uint8_t dmpSetFIFOProcessedCallback(void (*func) (void)); - - uint8_t dmpInitFIFOParam(); - uint8_t dmpCloseFIFO(); - uint8_t dmpSetGyroDataSource(uint8_t source); - uint8_t dmpDecodeQuantizedAccel(); - uint32_t dmpGetGyroSumOfSquare(); - uint32_t dmpGetAccelSumOfSquare(); - void dmpOverrideQuaternion(long *q); - uint16_t dmpGetFIFOPacketSize(); - #endif - - private: - uint8_t devAddr; - uint8_t buffer[14]; - #if defined(MPU6050_INCLUDE_DMP_MOTIONAPPS20) or defined(MPU6050_INCLUDE_DMP_MOTIONAPPS41) - uint8_t *dmpPacketBuffer; - uint16_t dmpPacketSize; - #endif -}; - -#endif /* _MPU6050_H_ */ diff --git a/mpu6050-master/src/MPU6050_6Axis_MotionApps20.h b/mpu6050-master/src/MPU6050_6Axis_MotionApps20.h deleted file mode 100644 index 5995b086d4a9a3f0cdc0cdc78c1085cb3ea9ebee..0000000000000000000000000000000000000000 --- a/mpu6050-master/src/MPU6050_6Axis_MotionApps20.h +++ /dev/null @@ -1,623 +0,0 @@ -// I2Cdev library collection - MPU6050 I2C device class, 6-axis MotionApps 2.0 implementation -// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) -// 5/20/2013 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2019/07/08 - merged all DMP Firmware configuration items into the dmpMemory array -// - Simplified dmpInitialize() to accomidate the dmpmemory array alterations -// ... - ongoing debug release - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -#ifndef _MPU6050_6AXIS_MOTIONAPPS20_H_ -#define _MPU6050_6AXIS_MOTIONAPPS20_H_ - -#include "I2Cdev.h" -#include "helper_3dmath.h" - -// MotionApps 2.0 DMP implementation, built using the MPU-6050EVB evaluation board -#define MPU6050_INCLUDE_DMP_MOTIONAPPS20 - -#include "MPU6050.h" - -// Tom Carpenter's conditional PROGMEM code -// http://forum.arduino.cc/index.php?topic=129407.0 -#ifdef __AVR__ - #include <avr/pgmspace.h> -#elif defined(ESP8266) || defined(ESP32) - #include <pgmspace.h> -#else - // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen - #ifndef __PGMSPACE_H_ - #define __PGMSPACE_H_ 1 - #include <inttypes.h> - - #define PROGMEM - #define PGM_P const char * - #define PSTR(str) (str) - #define F(x) x - - typedef void prog_void; - typedef char prog_char; - typedef unsigned char prog_uchar; - typedef int8_t prog_int8_t; - typedef uint8_t prog_uint8_t; - typedef int16_t prog_int16_t; - typedef uint16_t prog_uint16_t; - typedef int32_t prog_int32_t; - typedef uint32_t prog_uint32_t; - - #define strcpy_P(dest, src) strcpy((dest), (src)) - #define strcat_P(dest, src) strcat((dest), (src)) - #define strcmp_P(a, b) strcmp((a), (b)) - - #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) - #define pgm_read_word(addr) (*(const unsigned short *)(addr)) - #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) - #define pgm_read_float(addr) (*(const float *)(addr)) - - #define pgm_read_byte_near(addr) pgm_read_byte(addr) - #define pgm_read_word_near(addr) pgm_read_word(addr) - #define pgm_read_dword_near(addr) pgm_read_dword(addr) - #define pgm_read_float_near(addr) pgm_read_float(addr) - #define pgm_read_byte_far(addr) pgm_read_byte(addr) - #define pgm_read_word_far(addr) pgm_read_word(addr) - #define pgm_read_dword_far(addr) pgm_read_dword(addr) - #define pgm_read_float_far(addr) pgm_read_float(addr) - #endif -#endif - -/* Source is from the InvenSense MotionApps v2 demo code. Original source is - * unavailable, unless you happen to be amazing as decompiling binary by - * hand (in which case, please contact me, and I'm totally serious). - * - * Also, I'd like to offer many, many thanks to Noah Zerkin for all of the - * DMP reverse-engineering he did to help make this bit of wizardry - * possible. - */ - -// NOTE! Enabling DEBUG adds about 3.3kB to the flash program size. -// Debug output is now working even on ATMega328P MCUs (e.g. Arduino Uno) -// after moving string constants to flash memory storage using the F() -// compiler macro (Arduino IDE 1.0+ required). - -//#define DEBUG -#ifdef DEBUG - #define DEBUG_PRINT(x) Serial.print(x) - #define DEBUG_PRINTF(x, y) Serial.print(x, y) - #define DEBUG_PRINTLN(x) Serial.println(x) - #define DEBUG_PRINTLNF(x, y) Serial.println(x, y) -#else - #define DEBUG_PRINT(x) - #define DEBUG_PRINTF(x, y) - #define DEBUG_PRINTLN(x) - #define DEBUG_PRINTLNF(x, y) -#endif - -#define MPU6050_DMP_CODE_SIZE 1929 // dmpMemory[] -#define MPU6050_DMP_CONFIG_SIZE 192 // dmpConfig[] -#define MPU6050_DMP_UPDATES_SIZE 47 // dmpUpdates[] - -/* ================================================================================================ * - | Default MotionApps v2.0 42-byte FIFO packet structure: | - | | - | [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ][GYRO X][ ][GYRO Y][ ] | - | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - | | - | [GYRO Z][ ][ACC X ][ ][ACC Y ][ ][ACC Z ][ ][ ] | - | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | - * ================================================================================================ */ - -// this block of memory gets written to the MPU on start-up, and it seems -// to be volatile memory, so it has to be done each time (it only takes ~1 -// second though) - -// I Only Changed this by applying all the configuration data and capturing it before startup: -// *** this is a capture of the DMP Firmware after all the messy changes were made so we can just load it -const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = { - /* bank # 0 */ - 0xFB, 0x00, 0x00, 0x3E, 0x00, 0x0B, 0x00, 0x36, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0xFF, 0xFF, 0xFE, 0x80, 0x01, - 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCB, 0x47, 0xA2, 0x20, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x41, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x2A, 0x00, 0x00, 0x16, 0x55, 0x00, 0x00, 0x21, 0x82, - 0xFD, 0x87, 0x26, 0x50, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x05, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x00, 0x02, 0x65, 0x32, 0x00, 0x00, 0x5E, 0xC0, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFB, 0x8C, 0x6F, 0x5D, 0xFD, 0x5D, 0x08, 0xD9, 0x00, 0x7C, 0x73, 0x3B, 0x00, 0x6C, 0x12, 0xCC, - 0x32, 0x00, 0x13, 0x9D, 0x32, 0x00, 0xD0, 0xD6, 0x32, 0x00, 0x08, 0x00, 0x40, 0x00, 0x01, 0xF4, - 0xFF, 0xE6, 0x80, 0x79, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xD6, 0x00, 0x00, 0x27, 0x10, - /* bank # 1 */ - 0xFB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xFA, 0x36, 0xFF, 0xBC, 0x30, 0x8E, 0x00, 0x05, 0xFB, 0xF0, 0xFF, 0xD9, 0x5B, 0xC8, - 0xFF, 0xD0, 0x9A, 0xBE, 0x00, 0x00, 0x10, 0xA9, 0xFF, 0xF4, 0x1E, 0xB2, 0x00, 0xCE, 0xBB, 0xF7, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x0C, - 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xCF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x23, 0xA1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x3F, 0x68, 0xB6, 0x79, 0x35, 0x28, 0xBC, 0xC6, 0x7E, 0xD1, 0x6C, - 0x80, 0x00, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x0C, 0x02, 0xD0, - /* bank # 2 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x01, 0x00, 0x05, 0x8B, 0xC1, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xFF, 0xEF, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* bank # 3 */ - 0xD8, 0xDC, 0xBA, 0xA2, 0xF1, 0xDE, 0xB2, 0xB8, 0xB4, 0xA8, 0x81, 0x91, 0xF7, 0x4A, 0x90, 0x7F, - 0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA, 0xA0, 0x80, 0xF2, 0xCE, 0x81, 0xF3, 0xC2, - 0xF1, 0xC1, 0xF2, 0xC3, 0xF3, 0xCC, 0xA2, 0xB2, 0x80, 0xF1, 0xC6, 0xD8, 0x80, 0xBA, 0xA7, 0xDF, - 0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, 0xC5, 0xB6, 0xF0, 0x87, 0xA2, 0x94, 0x24, 0x48, 0x70, 0x3C, - 0x95, 0x40, 0x68, 0x34, 0x58, 0x9B, 0x78, 0xA2, 0xF1, 0x83, 0x92, 0x2D, 0x55, 0x7D, 0xD8, 0xB1, - 0xB4, 0xB8, 0xA1, 0xD0, 0x91, 0x80, 0xF2, 0x70, 0xF3, 0x70, 0xF2, 0x7C, 0x80, 0xA8, 0xF1, 0x01, - 0xB0, 0x98, 0x87, 0xD9, 0x43, 0xD8, 0x86, 0xC9, 0x88, 0xBA, 0xA1, 0xF2, 0x0E, 0xB8, 0x97, 0x80, - 0xF1, 0xA9, 0xDF, 0xDF, 0xDF, 0xAA, 0xDF, 0xDF, 0xDF, 0xF2, 0xAA, 0x4C, 0xCD, 0x6C, 0xA9, 0x0C, - 0xC9, 0x2C, 0x97, 0x97, 0x97, 0x97, 0xF1, 0xA9, 0x89, 0x26, 0x46, 0x66, 0xB0, 0xB4, 0xBA, 0x80, - 0xAC, 0xDE, 0xF2, 0xCA, 0xF1, 0xB2, 0x8C, 0x02, 0xA9, 0xB6, 0x98, 0x00, 0x89, 0x0E, 0x16, 0x1E, - 0xB8, 0xA9, 0xB4, 0x99, 0x2C, 0x54, 0x7C, 0xB0, 0x8A, 0xA8, 0x96, 0x36, 0x56, 0x76, 0xF1, 0xB9, - 0xAF, 0xB4, 0xB0, 0x83, 0xC0, 0xB8, 0xA8, 0x97, 0x11, 0xB1, 0x8F, 0x98, 0xB9, 0xAF, 0xF0, 0x24, - 0x08, 0x44, 0x10, 0x64, 0x18, 0xF1, 0xA3, 0x29, 0x55, 0x7D, 0xAF, 0x83, 0xB5, 0x93, 0xAF, 0xF0, - 0x00, 0x28, 0x50, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF, 0xD9, 0xFA, 0xA3, 0x86, - 0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5, 0xC7, 0xB2, 0x8C, 0xC1, - 0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xA8, 0xB2, 0x86, - /* bank # 4 */ - 0xB4, 0x98, 0x0D, 0x35, 0x5D, 0xB8, 0xAA, 0x98, 0xB0, 0x87, 0x2D, 0x35, 0x3D, 0xB2, 0xB6, 0xBA, - 0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, 0xB8, 0xAA, 0x87, 0x2C, - 0x54, 0x7C, 0xB9, 0xA3, 0xDE, 0xDF, 0xDF, 0xA3, 0xB1, 0x80, 0xF2, 0xC4, 0xCD, 0xC9, 0xF1, 0xB8, - 0xA9, 0xB4, 0x99, 0x83, 0x0D, 0x35, 0x5D, 0x89, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0xB5, 0x93, 0xA3, - 0x0E, 0x16, 0x1E, 0xA9, 0x2C, 0x54, 0x7C, 0xB8, 0xB4, 0xB0, 0xF1, 0x97, 0x83, 0xA8, 0x11, 0x84, - 0xA5, 0x09, 0x98, 0xA3, 0x83, 0xF0, 0xDA, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xD8, 0xF1, 0xA5, - 0x29, 0x55, 0x7D, 0xA5, 0x85, 0x95, 0x02, 0x1A, 0x2E, 0x3A, 0x56, 0x5A, 0x40, 0x48, 0xF9, 0xF3, - 0xA3, 0xD9, 0xF8, 0xF0, 0x98, 0x83, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0x97, 0x82, 0xA8, 0xF1, - 0x11, 0xF0, 0x98, 0xA2, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xDA, 0xF3, 0xDE, 0xD8, 0x83, 0xA5, - 0x94, 0x01, 0xD9, 0xA3, 0x02, 0xF1, 0xA2, 0xC3, 0xC5, 0xC7, 0xD8, 0xF1, 0x84, 0x92, 0xA2, 0x4D, - 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, - 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0x93, 0xA3, 0x4D, - 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, - 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0xA8, 0x8A, 0x9A, - 0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98, 0xA8, 0xD9, 0x08, 0xD8, - 0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1, 0xAF, 0xC8, 0x97, 0x87, - /* bank # 5 */ - 0x34, 0xB5, 0xB9, 0x94, 0xA4, 0x21, 0xF3, 0xD9, 0x22, 0xD8, 0xF2, 0x2D, 0xF3, 0xD9, 0x2A, 0xD8, - 0xF2, 0x35, 0xF3, 0xD9, 0x32, 0xD8, 0x81, 0xA4, 0x60, 0x60, 0x61, 0xD9, 0x61, 0xD8, 0x6C, 0x68, - 0x69, 0xD9, 0x69, 0xD8, 0x74, 0x70, 0x71, 0xD9, 0x71, 0xD8, 0xB1, 0xA3, 0x84, 0x19, 0x3D, 0x5D, - 0xA3, 0x83, 0x1A, 0x3E, 0x5E, 0x93, 0x10, 0x30, 0x81, 0x10, 0x11, 0xB8, 0xB0, 0xAF, 0x8F, 0x94, - 0xF2, 0xDA, 0x3E, 0xD8, 0xB4, 0x9A, 0xA8, 0x87, 0x29, 0xDA, 0xF8, 0xD8, 0x87, 0x9A, 0x35, 0xDA, - 0xF8, 0xD8, 0x87, 0x9A, 0x3D, 0xDA, 0xF8, 0xD8, 0xB1, 0xB9, 0xA4, 0x98, 0x85, 0x02, 0x2E, 0x56, - 0xA5, 0x81, 0x00, 0x0C, 0x14, 0xA3, 0x97, 0xB0, 0x8A, 0xF1, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, - 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x84, 0x0D, 0xDA, 0x0E, 0xD8, 0xA3, 0x29, 0x83, 0xDA, - 0x2C, 0x0E, 0xD8, 0xA3, 0x84, 0x49, 0x83, 0xDA, 0x2C, 0x4C, 0x0E, 0xD8, 0xB8, 0xB0, 0xA8, 0x8A, - 0x9A, 0xF5, 0x20, 0xAA, 0xDA, 0xDF, 0xD8, 0xA8, 0x40, 0xAA, 0xD0, 0xDA, 0xDE, 0xD8, 0xA8, 0x60, - 0xAA, 0xDA, 0xD0, 0xDF, 0xD8, 0xF1, 0x97, 0x86, 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97, - 0x28, 0x88, 0x9B, 0xF0, 0x0C, 0x20, 0x14, 0x40, 0xB8, 0xB0, 0xB4, 0xA8, 0x8C, 0x9C, 0xF0, 0x04, - 0x28, 0x51, 0x79, 0x1D, 0x30, 0x14, 0x38, 0xB2, 0x82, 0xAB, 0xD0, 0x98, 0x2C, 0x50, 0x50, 0x78, - 0x78, 0x9B, 0xF1, 0x1A, 0xB0, 0xF0, 0x8A, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x8B, 0x29, 0x51, 0x79, - 0x8A, 0x24, 0x70, 0x59, 0x8B, 0x20, 0x58, 0x71, 0x8A, 0x44, 0x69, 0x38, 0x8B, 0x39, 0x40, 0x68, - 0x8A, 0x64, 0x48, 0x31, 0x8B, 0x30, 0x49, 0x60, 0xA5, 0x88, 0x20, 0x09, 0x71, 0x58, 0x44, 0x68, - /* bank # 6 */ - 0x11, 0x39, 0x64, 0x49, 0x30, 0x19, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0x8C, 0xA8, 0x04, - 0x28, 0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, 0x26, 0x46, 0x66, - 0xF0, 0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, - 0xA9, 0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, 0x31, 0x48, 0x60, - 0x8C, 0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, 0xA8, 0x6E, 0x76, - 0x7E, 0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0x9E, 0xB9, 0xA3, 0x8A, 0x22, 0x8A, 0x6E, 0x8A, 0x56, - 0x8A, 0x5E, 0x9F, 0xB1, 0x83, 0x06, 0x26, 0x46, 0x66, 0x0E, 0x2E, 0x4E, 0x6E, 0x9D, 0xB8, 0xAD, - 0x00, 0x2C, 0x54, 0x7C, 0xF2, 0xB1, 0x8C, 0xB4, 0x99, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0x81, 0x91, - 0xAC, 0x38, 0xAD, 0x3A, 0xB5, 0x83, 0x91, 0xAC, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8, - 0x6D, 0xD9, 0x68, 0xD8, 0x8C, 0x9D, 0xAE, 0x29, 0xD9, 0x04, 0xAE, 0xD8, 0x51, 0xD9, 0x04, 0xAE, - 0xD8, 0x79, 0xD9, 0x04, 0xD8, 0x81, 0xF3, 0x9D, 0xAD, 0x00, 0x8D, 0xAE, 0x19, 0x81, 0xAD, 0xD9, - 0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7, 0xD9, 0xAD, 0xAD, 0xAD, - 0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E, 0x76, 0xF3, 0xAC, 0x2E, - 0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C, 0xAC, 0x30, 0x18, 0xA8, - 0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C, 0x24, 0xF2, 0xB0, 0x89, - 0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51, 0xD9, 0xD8, 0xD8, 0x79, - /* bank # 7 */ - 0xD9, 0xD8, 0xD8, 0xF1, 0x9E, 0x88, 0xA3, 0x31, 0xDA, 0xD8, 0xD8, 0x91, 0x2D, 0xD9, 0x28, 0xD8, - 0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x83, 0x93, 0x35, 0x3D, 0x80, 0x25, 0xDA, - 0xD8, 0xD8, 0x85, 0x69, 0xDA, 0xD8, 0xD8, 0xB4, 0x93, 0x81, 0xA3, 0x28, 0x34, 0x3C, 0xF3, 0xAB, - 0x8B, 0xF8, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xFA, 0xB0, 0x87, 0x9C, 0xB9, 0xA3, - 0xDD, 0xF1, 0x20, 0x28, 0x30, 0x38, 0x9A, 0xF1, 0x28, 0x30, 0x38, 0x9D, 0xF1, 0xA3, 0xA3, 0xA3, - 0xA3, 0xF2, 0xA3, 0xB4, 0x90, 0x80, 0xF2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, - 0xA3, 0xB2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB0, 0x87, 0xB5, 0x99, 0xF1, 0x28, 0x30, 0x38, - 0x98, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x97, 0xA3, 0xA3, 0xA3, 0xA3, 0xF3, 0x9B, 0xA3, 0x30, 0xDC, - 0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xFE, 0xD8, 0xFF, - -}; - -#ifndef MPU6050_DMP_FIFO_RATE_DIVISOR -#define MPU6050_DMP_FIFO_RATE_DIVISOR 0x01 // The New instance of the Firmware has this as the default -#endif - -// I Simplified this: -uint8_t MPU6050::dmpInitialize() { - // reset device - DEBUG_PRINTLN(F("\n\nResetting MPU6050...")); - reset(); - delay(30); // wait after reset - - // enable sleep mode and wake cycle - /*Serial.println(F("Enabling sleep mode...")); - setSleepEnabled(true); - Serial.println(F("Enabling wake cycle...")); - setWakeCycleEnabled(true);*/ - - // disable sleep mode - setSleepEnabled(false); - - // get MPU hardware revision - setMemoryBank(0x10, true, true); - setMemoryStartAddress(0x06); - DEBUG_PRINTLN(F("Checking hardware revision...")); - DEBUG_PRINT(F("Revision @ user[16][6] = ")); - DEBUG_PRINTLN(readMemoryByte()); - DEBUG_PRINTLN(F("Resetting memory bank selection to 0...")); - setMemoryBank(0, false, false); - - // check OTP bank valid - DEBUG_PRINTLN(F("Reading OTP bank valid flag...")); - DEBUG_PRINT(F("OTP bank is ")); - DEBUG_PRINTLN(getOTPBankValid() ? F("valid!") : F("invalid!")); - - // setup weird slave stuff (?) - DEBUG_PRINTLN(F("Setting slave 0 address to 0x7F...")); - setSlaveAddress(0, 0x7F); - DEBUG_PRINTLN(F("Disabling I2C Master mode...")); - setI2CMasterModeEnabled(false); - DEBUG_PRINTLN(F("Setting slave 0 address to 0x68 (self)...")); - setSlaveAddress(0, 0x68); - DEBUG_PRINTLN(F("Resetting I2C Master control...")); - resetI2CMaster(); - delay(20); - DEBUG_PRINTLN(F("Setting clock source to Z Gyro...")); - setClockSource(MPU6050_IMU::MPU6050_CLOCK_PLL_ZGYRO); - - DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled...")); - setIntEnabled((1<<(MPU6050_IMU::MPU6050_INTERRUPT_FIFO_OFLOW_BIT))|(1<<(MPU6050_IMU::MPU6050_INTERRUPT_DMP_INT_BIT))); - - DEBUG_PRINTLN(F("Setting sample rate to 200Hz...")); - setRate(4); // 1khz / (1 + 4) = 200 Hz - - DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]...")); - setExternalFrameSync(MPU6050_IMU::MPU6050_EXT_SYNC_TEMP_OUT_L); - - DEBUG_PRINTLN(F("Setting DLPF bandwidth to 42Hz...")); - setDLPFMode(MPU6050_IMU::MPU6050_DLPF_BW_42); - - DEBUG_PRINTLN(F("Setting gyro sensitivity to +/- 2000 deg/sec...")); - setFullScaleGyroRange(MPU6050_IMU::MPU6050_GYRO_FS_2000); - - // load DMP code into memory banks - DEBUG_PRINT(F("Writing DMP code to MPU memory banks (")); - DEBUG_PRINT(MPU6050_DMP_CODE_SIZE); - DEBUG_PRINTLN(F(" bytes)")); - if (!writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) return 1; // Failed - DEBUG_PRINTLN(F("Success! DMP code written and verified.")); - - // Set the FIFO Rate Divisor int the DMP Firmware Memory - unsigned char dmpUpdate[] = {0x00, MPU6050_DMP_FIFO_RATE_DIVISOR}; - writeMemoryBlock(dmpUpdate, 0x02, 0x02, 0x16); // Lets write the dmpUpdate data to the Firmware image, we have 2 bytes to write in bank 0x02 with the Offset 0x16 - - //write start address MSB into register - setDMPConfig1(0x03); - //write start address LSB into register - setDMPConfig2(0x00); - - DEBUG_PRINTLN(F("Clearing OTP Bank flag...")); - setOTPBankValid(false); - - DEBUG_PRINTLN(F("Setting motion detection threshold to 2...")); - setMotionDetectionThreshold(2); - - DEBUG_PRINTLN(F("Setting zero-motion detection threshold to 156...")); - setZeroMotionDetectionThreshold(156); - - DEBUG_PRINTLN(F("Setting motion detection duration to 80...")); - setMotionDetectionDuration(80); - - DEBUG_PRINTLN(F("Setting zero-motion detection duration to 0...")); - setZeroMotionDetectionDuration(0); - DEBUG_PRINTLN(F("Enabling FIFO...")); - setFIFOEnabled(true); - - DEBUG_PRINTLN(F("Resetting DMP...")); - resetDMP(); - - DEBUG_PRINTLN(F("DMP is good to go! Finally.")); - - DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)...")); - setDMPEnabled(false); - - DEBUG_PRINTLN(F("Setting up internal 42-byte (default) DMP packet buffer...")); - dmpPacketSize = 42; - - DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time...")); - resetFIFO(); - getIntStatus(); - - return 0; // success -} -// Nothing else changed - -bool MPU6050::dmpPacketAvailable() { - return getFIFOCount() >= dmpGetFIFOPacketSize(); -} - -// uint8_t MPU6050::dmpSetFIFORate(uint8_t fifoRate); -// uint8_t MPU6050::dmpGetFIFORate(); -// uint8_t MPU6050::dmpGetSampleStepSizeMS(); -// uint8_t MPU6050::dmpGetSampleFrequency(); -// int32_t MPU6050::dmpDecodeTemperature(int8_t tempReg); - -//uint8_t MPU6050::dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); -//uint8_t MPU6050::dmpUnregisterFIFORateProcess(inv_obj_func func); -//uint8_t MPU6050::dmpRunFIFORateProcesses(); - -// uint8_t MPU6050::dmpSendQuaternion(uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendPacketNumber(uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); - -uint8_t MPU6050::dmpGetAccel(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[28] << 24) | ((uint32_t)packet[29] << 16) | ((uint32_t)packet[30] << 8) | packet[31]); - data[1] = (((uint32_t)packet[32] << 24) | ((uint32_t)packet[33] << 16) | ((uint32_t)packet[34] << 8) | packet[35]); - data[2] = (((uint32_t)packet[36] << 24) | ((uint32_t)packet[37] << 16) | ((uint32_t)packet[38] << 8) | packet[39]); - return 0; -} -uint8_t MPU6050::dmpGetAccel(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (packet[28] << 8) | packet[29]; - data[1] = (packet[32] << 8) | packet[33]; - data[2] = (packet[36] << 8) | packet[37]; - return 0; -} -uint8_t MPU6050::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - v -> x = (packet[28] << 8) | packet[29]; - v -> y = (packet[32] << 8) | packet[33]; - v -> z = (packet[36] << 8) | packet[37]; - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[0] << 24) | ((uint32_t)packet[1] << 16) | ((uint32_t)packet[2] << 8) | packet[3]); - data[1] = (((uint32_t)packet[4] << 24) | ((uint32_t)packet[5] << 16) | ((uint32_t)packet[6] << 8) | packet[7]); - data[2] = (((uint32_t)packet[8] << 24) | ((uint32_t)packet[9] << 16) | ((uint32_t)packet[10] << 8) | packet[11]); - data[3] = (((uint32_t)packet[12] << 24) | ((uint32_t)packet[13] << 16) | ((uint32_t)packet[14] << 8) | packet[15]); - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = ((packet[0] << 8) | packet[1]); - data[1] = ((packet[4] << 8) | packet[5]); - data[2] = ((packet[8] << 8) | packet[9]); - data[3] = ((packet[12] << 8) | packet[13]); - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - int16_t qI[4]; - uint8_t status = dmpGetQuaternion(qI, packet); - if (status == 0) { - q -> w = (float)qI[0] / 16384.0f; - q -> x = (float)qI[1] / 16384.0f; - q -> y = (float)qI[2] / 16384.0f; - q -> z = (float)qI[3] / 16384.0f; - return 0; - } - return status; // int16 return value, indicates error if this line is reached -} -// uint8_t MPU6050::dmpGet6AxisQuaternion(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetRelativeQuaternion(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetGyro(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[16] << 24) | ((uint32_t)packet[17] << 16) | ((uint32_t)packet[18] << 8) | packet[19]); - data[1] = (((uint32_t)packet[20] << 24) | ((uint32_t)packet[21] << 16) | ((uint32_t)packet[22] << 8) | packet[23]); - data[2] = (((uint32_t)packet[24] << 24) | ((uint32_t)packet[25] << 16) | ((uint32_t)packet[26] << 8) | packet[27]); - return 0; -} -uint8_t MPU6050::dmpGetGyro(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (packet[16] << 8) | packet[17]; - data[1] = (packet[20] << 8) | packet[21]; - data[2] = (packet[24] << 8) | packet[25]; - return 0; -} -uint8_t MPU6050::dmpGetGyro(VectorInt16 *v, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - v -> x = (packet[16] << 8) | packet[17]; - v -> y = (packet[20] << 8) | packet[21]; - v -> z = (packet[24] << 8) | packet[25]; - return 0; -} -// uint8_t MPU6050::dmpSetLinearAccelFilterCoefficient(float coef); -// uint8_t MPU6050::dmpGetLinearAccel(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) { - // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g) - v -> x = vRaw -> x - gravity -> x*8192; - v -> y = vRaw -> y - gravity -> y*8192; - v -> z = vRaw -> z - gravity -> z*8192; - return 0; -} -// uint8_t MPU6050::dmpGetLinearAccelInWorld(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) { - // rotate measured 3D acceleration vector into original state - // frame of reference based on orientation quaternion - memcpy(v, vReal, sizeof(VectorInt16)); - v -> rotate(q); - return 0; -} -// uint8_t MPU6050::dmpGetGyroAndAccelSensor(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetGyroSensor(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetControlData(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetTemperature(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetGravity(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetGravity(int16_t *data, const uint8_t* packet) { - /* +1g corresponds to +8192, sensitivity is 2g. */ - int16_t qI[4]; - uint8_t status = dmpGetQuaternion(qI, packet); - data[0] = ((int32_t)qI[1] * qI[3] - (int32_t)qI[0] * qI[2]) / 16384; - data[1] = ((int32_t)qI[0] * qI[1] + (int32_t)qI[2] * qI[3]) / 16384; - data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1] - - (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (2 * 16384); - return status; -} - -uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q) { - v -> x = 2 * (q -> x*q -> z - q -> w*q -> y); - v -> y = 2 * (q -> w*q -> x + q -> y*q -> z); - v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z; - return 0; -} -// uint8_t MPU6050::dmpGetUnquantizedAccel(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetQuantizedAccel(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetExternalSensorData(long *data, int size, const uint8_t* packet); -// uint8_t MPU6050::dmpGetEIS(long *data, const uint8_t* packet); - -uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) { - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // psi - data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y); // theta - data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi - return 0; -} - -#ifdef USE_OLD_DMPGETYAWPITCHROLL -uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { - // yaw: (about Z axis) - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); - // pitch: (nose up/down, about Y axis) - data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); - // roll: (tilt left/right, about X axis) - data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z)); - return 0; -} -#else -uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { - // yaw: (about Z axis) - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); - // pitch: (nose up/down, about Y axis) - data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); - // roll: (tilt left/right, about X axis) - data[2] = atan2(gravity -> y , gravity -> z); - if (gravity -> z < 0) { - if(data[1] > 0) { - data[1] = PI - data[1]; - } else { - data[1] = -PI - data[1]; - } - } - return 0; -} -#endif - -// uint8_t MPU6050::dmpGetAccelFloat(float *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetQuaternionFloat(float *data, const uint8_t* packet); - -uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) { - /*for (uint8_t k = 0; k < dmpPacketSize; k++) { - if (dmpData[k] < 0x10) Serial.print("0"); - Serial.print(dmpData[k], HEX); - Serial.print(" "); - } - Serial.print("\n");*/ - //Serial.println((uint16_t)dmpPacketBuffer); - return 0; -} -uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) { - uint8_t status; - uint8_t buf[dmpPacketSize]; - for (uint8_t i = 0; i < numPackets; i++) { - // read packet from FIFO - getFIFOBytes(buf, dmpPacketSize); - - // process packet - if ((status = dmpProcessFIFOPacket(buf)) > 0) return status; - - // increment external process count variable, if supplied - if (processed != 0) (*processed)++; - } - return 0; -} - -// uint8_t MPU6050::dmpSetFIFOProcessedCallback(void (*func) (void)); - -// uint8_t MPU6050::dmpInitFIFOParam(); -// uint8_t MPU6050::dmpCloseFIFO(); -// uint8_t MPU6050::dmpSetGyroDataSource(uint_fast8_t source); -// uint8_t MPU6050::dmpDecodeQuantizedAccel(); -// uint32_t MPU6050::dmpGetGyroSumOfSquare(); -// uint32_t MPU6050::dmpGetAccelSumOfSquare(); -// void MPU6050::dmpOverrideQuaternion(long *q); -uint16_t MPU6050::dmpGetFIFOPacketSize() { - return dmpPacketSize; -} - - - -uint8_t MPU6050::dmpGetCurrentFIFOPacket(uint8_t *data) { // overflow proof - return(GetCurrentFIFOPacket(data, dmpPacketSize)); -} - -#endif /* _MPU6050_6AXIS_MOTIONAPPS20_H_ */ diff --git a/mpu6050-master/src/MPU6050_6Axis_MotionApps_V6_12.h b/mpu6050-master/src/MPU6050_6Axis_MotionApps_V6_12.h deleted file mode 100644 index f8c01441f2834c9ed8acc4cbc09553d1f236dbfd..0000000000000000000000000000000000000000 --- a/mpu6050-master/src/MPU6050_6Axis_MotionApps_V6_12.h +++ /dev/null @@ -1,623 +0,0 @@ -// I2Cdev library collection - MPU6050 I2C device class, 6-axis MotionApps 6.12 implementation -// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) -// 5/20/2013 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2019/7/10 - I incorporated DMP Firmware Version 6.12 Latest as of today with many features and bug fixes. -// - MPU6050 Registers have not changed just the DMP Image so that full backwards compatibility is present -// - Run-time calibration routine is enabled which calibrates after no motion state is detected -// - once no motion state is detected Calibration completes within 0.5 seconds -// - The Drawback is that the firmware image is larger. -// ... - ongoing debug release - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -#ifndef _MPU6050_6AXIS_MOTIONAPPS20_H_ -#define _MPU6050_6AXIS_MOTIONAPPS20_H_ - -#include "I2Cdev.h" -#include "helper_3dmath.h" - -// MotionApps 2.0 DMP implementation, built using the MPU-6050EVB evaluation board -#define MPU6050_INCLUDE_DMP_MOTIONAPPS20 // same definitions Should work with V6.12 - -#include "MPU6050.h" - -// Tom Carpenter's conditional PROGMEM code -// http://forum.arduino.cc/index.php?topic=129407.0 -#ifdef __AVR__ - #include <avr/pgmspace.h> -#elif defined(ESP8266) || defined(ESP32) - #include <pgmspace.h> -#else - // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen - #ifndef __PGMSPACE_H_ - #define __PGMSPACE_H_ 1 - #include <inttypes.h> - - #define PROGMEM - #define PGM_P const char * - #define PSTR(str) (str) - #define F(x) x - - typedef void prog_void; - typedef char prog_char; - typedef unsigned char prog_uchar; - typedef int8_t prog_int8_t; - typedef uint8_t prog_uint8_t; - typedef int16_t prog_int16_t; - typedef uint16_t prog_uint16_t; - typedef int32_t prog_int32_t; - typedef uint32_t prog_uint32_t; - - #define strcpy_P(dest, src) strcpy((dest), (src)) - #define strcat_P(dest, src) strcat((dest), (src)) - #define strcmp_P(a, b) strcmp((a), (b)) - - #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) - #define pgm_read_word(addr) (*(const unsigned short *)(addr)) - #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) - #define pgm_read_float(addr) (*(const float *)(addr)) - - #define pgm_read_byte_near(addr) pgm_read_byte(addr) - #define pgm_read_word_near(addr) pgm_read_word(addr) - #define pgm_read_dword_near(addr) pgm_read_dword(addr) - #define pgm_read_float_near(addr) pgm_read_float(addr) - #define pgm_read_byte_far(addr) pgm_read_byte(addr) - #define pgm_read_word_far(addr) pgm_read_word(addr) - #define pgm_read_dword_far(addr) pgm_read_dword(addr) - #define pgm_read_float_far(addr) pgm_read_float(addr) - #endif -#endif - -/* Source is from the InvenSense MotionApps v2 demo code. Original source is - * unavailable, unless you happen to be amazing as decompiling binary by - * hand (in which case, please contact me, and I'm totally serious). - * - * Also, I'd like to offer many, many thanks to Noah Zerkin for all of the - * DMP reverse-engineering he did to help make this bit of wizardry - * possible. - */ - -// NOTE! Enabling DEBUG adds about 3.3kB to the flash program size. -// Debug output is now working even on ATMega328P MCUs (e.g. Arduino Uno) -// after moving string constants to flash memory storage using the F() -// compiler macro (Arduino IDE 1.0+ required). - -//#define DEBUG -#ifdef DEBUG - #define DEBUG_PRINT(x) Serial.print(x) - #define DEBUG_PRINTF(x, y) Serial.print(x, y) - #define DEBUG_PRINTLN(x) Serial.println(x) - #define DEBUG_PRINTLNF(x, y) Serial.println(x, y) -#else - #define DEBUG_PRINT(x) - #define DEBUG_PRINTF(x, y) - #define DEBUG_PRINTLN(x) - #define DEBUG_PRINTLNF(x, y) -#endif - -#define MPU6050_DMP_CODE_SIZE 3062 // dmpMemory[] - -/* ================================================================ * - | Default MotionApps v6.12 28-byte FIFO packet structure: | - | | - | [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ] | - | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - | | - | [GYRO X][GYRO Y][GYRO Z][ACC X ][ACC Y ][ACC Z ] | - | 16 17 18 19 20 21 22 23 24 25 26 27 | - * ================================================================ */ - -// this block of memory gets written to the MPU on start-up, and it seems -// to be volatile memory, so it has to be done each time (it only takes ~1 -// second though) - -// *** this is a capture of the DMP Firmware V6.1.2 after all the messy changes were made so we can just load it -const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = { -/* bank # 0 */ -0x00, 0xF8, 0xF6, 0x2A, 0x3F, 0x68, 0xF5, 0x7A, 0x00, 0x06, 0xFF, 0xFE, 0x00, 0x03, 0x00, 0x00, -0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01, -0x03, 0x0C, 0x30, 0xC3, 0x0A, 0x74, 0x56, 0x2D, 0x0D, 0x62, 0xDB, 0xC7, 0x16, 0xF4, 0xBA, 0x02, -0x38, 0x83, 0xF8, 0x83, 0x30, 0x00, 0xF8, 0x83, 0x25, 0x8E, 0xF8, 0x83, 0x30, 0x00, 0xF8, 0x83, -0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0xBD, 0xD8, 0x11, 0x24, 0x00, 0x04, 0x00, 0x1A, 0x82, 0x79, 0xA1, -0x00, 0x36, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x83, 0x6F, 0xA2, -0x00, 0x3E, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCA, 0xE3, 0x09, 0x3E, 0x80, 0x00, 0x00, -0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, -0x1F, 0xA4, 0xE8, 0xE4, 0xFF, 0xF5, 0xDC, 0xB9, 0x00, 0x5B, 0x79, 0xCF, 0x1F, 0x3F, 0x78, 0x76, -0x00, 0x86, 0x7C, 0x5A, 0x00, 0x86, 0x23, 0x47, 0xFA, 0xB9, 0x86, 0x31, 0x00, 0x74, 0x87, 0x8A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x05, 0xFF, 0xFF, 0xE9, 0xA8, 0x00, 0x00, 0x21, 0x82, -0xFA, 0xB8, 0x4D, 0x46, 0xFF, 0xFA, 0xDF, 0x3D, 0xFF, 0xFF, 0xB2, 0xB3, 0x00, 0x00, 0x00, 0x00, -0x3F, 0xFF, 0xBA, 0x98, 0x00, 0x5D, 0xAC, 0x08, 0x00, 0x0A, 0x63, 0x78, 0x00, 0x01, 0x46, 0x21, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x42, 0xB5, 0x00, 0x06, 0x00, 0x64, 0x00, 0x64, 0x00, 0x06, -0x14, 0x06, 0x02, 0x9F, 0x0F, 0x47, 0x91, 0x32, 0xD9, 0x0E, 0x9F, 0xC9, 0x1D, 0xCF, 0x4C, 0x34, -0x3B, 0xB6, 0x7A, 0xE8, 0x00, 0x64, 0x00, 0x06, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, -/* bank # 1 */ -0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x07, 0x00, 0x00, 0xFF, 0xF1, 0x00, 0x00, 0xFA, 0x46, 0x00, 0x00, 0xA2, 0xB8, 0x00, 0x00, -0x10, 0x00, 0x00, 0x00, 0x04, 0xD6, 0x00, 0x00, 0x04, 0xCC, 0x00, 0x00, 0x04, 0xCC, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x05, 0x00, 0x64, 0x00, 0x20, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, -0x00, 0x00, 0x00, 0x32, 0xF8, 0x98, 0x00, 0x00, 0xFF, 0x65, 0x00, 0x00, 0x83, 0x0F, 0x00, 0x00, -0x00, 0x06, 0x00, 0x00, 0xFF, 0xF1, 0x00, 0x00, 0xFA, 0x46, 0x00, 0x00, 0xA2, 0xB8, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x02, 0x00, 0x00, -0x00, 0x01, 0xFB, 0x83, 0x00, 0x7C, 0x00, 0x00, 0xFB, 0x15, 0xFC, 0x00, 0x1F, 0xB4, 0xFF, 0x83, -0x00, 0x00, 0x00, 0x01, 0x00, 0x65, 0x00, 0x07, 0x00, 0x64, 0x03, 0xE8, 0x00, 0x64, 0x00, 0x28, -0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x16, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4, 0x00, 0x00, 0x10, 0x00, -/* bank # 2 */ -0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x01, 0x00, 0x05, 0xBA, 0xC6, 0x00, 0x47, 0x78, 0xA2, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, -0x00, 0x00, 0x23, 0xBB, 0x00, 0x2E, 0xA2, 0x5B, 0x00, 0x00, 0x05, 0x68, 0x00, 0x0B, 0xCF, 0x49, -0x00, 0x04, 0xFF, 0xFD, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x64, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x06, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x2E, 0xA2, 0x5B, 0x00, 0x00, 0x05, 0x68, 0x00, 0x0B, 0xCF, 0x49, 0x00, 0x00, 0x00, 0x00, -0x00, 0xF8, 0xF6, 0x2A, 0x3F, 0x68, 0xF5, 0x7A, 0x00, 0x04, 0xFF, 0xFD, 0x00, 0x02, 0x00, 0x00, -0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, -0xFF, 0xFF, 0xFF, 0xCF, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xFF, 0xFF, 0xFF, 0x9C, -0x00, 0x00, 0x43, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, -0xFF, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* bank # 3 */ -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x24, 0x26, 0xD3, -0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x96, 0x00, 0x3C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x9E, 0x65, 0x5D, -0x0C, 0x0A, 0x4E, 0x68, 0xCD, 0xCF, 0x77, 0x09, 0x50, 0x16, 0x67, 0x59, 0xC6, 0x19, 0xCE, 0x82, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x71, 0x1C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xD7, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00, -0x00, 0x11, 0xDC, 0x47, 0x03, 0x00, 0x00, 0x00, 0xC7, 0x93, 0x8F, 0x9D, 0x1E, 0x1B, 0x1C, 0x19, -0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xDF, 0xA4, 0x38, 0x1F, 0x9E, 0x65, 0x5D, -0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x71, 0x1C, 0x02, 0x03, 0x18, 0x85, 0x00, 0x00, 0x40, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x3F, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF4, 0xC9, 0xFF, 0xFF, 0xBC, 0xF0, 0x00, 0x01, 0x0C, 0x0F, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xF5, 0xB7, 0xBA, 0xB3, 0x67, 0x7D, 0xDF, 0x7E, 0x72, 0x90, 0x2E, 0x55, 0x4C, 0xF6, 0xE6, 0x88, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* bank # 4 */ -0xD8, 0xDC, 0xB4, 0xB8, 0xB0, 0xD8, 0xB9, 0xAB, 0xF3, 0xF8, 0xFA, 0xB3, 0xB7, 0xBB, 0x8E, 0x9E, -0xAE, 0xF1, 0x32, 0xF5, 0x1B, 0xF1, 0xB4, 0xB8, 0xB0, 0x80, 0x97, 0xF1, 0xA9, 0xDF, 0xDF, 0xDF, -0xAA, 0xDF, 0xDF, 0xDF, 0xF2, 0xAA, 0x4C, 0xCD, 0x6C, 0xA9, 0x0C, 0xC9, 0x2C, 0x97, 0xF1, 0xA9, -0x89, 0x26, 0x46, 0x66, 0xB2, 0x89, 0x99, 0xA9, 0x2D, 0x55, 0x7D, 0xB0, 0xB0, 0x8A, 0xA8, 0x96, -0x36, 0x56, 0x76, 0xF1, 0xBA, 0xA3, 0xB4, 0xB2, 0x80, 0xC0, 0xB8, 0xA8, 0x97, 0x11, 0xB2, 0x83, -0x98, 0xBA, 0xA3, 0xF0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xB2, 0xB9, 0xB4, 0x98, 0x83, 0xF1, -0xA3, 0x29, 0x55, 0x7D, 0xBA, 0xB5, 0xB1, 0xA3, 0x83, 0x93, 0xF0, 0x00, 0x28, 0x50, 0xF5, 0xB2, -0xB6, 0xAA, 0x83, 0x93, 0x28, 0x54, 0x7C, 0xF1, 0xB9, 0xA3, 0x82, 0x93, 0x61, 0xBA, 0xA2, 0xDA, -0xDE, 0xDF, 0xDB, 0x81, 0x9A, 0xB9, 0xAE, 0xF5, 0x60, 0x68, 0x70, 0xF1, 0xDA, 0xBA, 0xA2, 0xDF, -0xD9, 0xBA, 0xA2, 0xFA, 0xB9, 0xA3, 0x82, 0x92, 0xDB, 0x31, 0xBA, 0xA2, 0xD9, 0xBA, 0xA2, 0xF8, -0xDF, 0x85, 0xA4, 0xD0, 0xC1, 0xBB, 0xAD, 0x83, 0xC2, 0xC5, 0xC7, 0xB8, 0xA2, 0xDF, 0xDF, 0xDF, -0xBA, 0xA0, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xAA, 0xB3, 0x8D, 0xB4, 0x98, 0x0D, 0x35, -0x5D, 0xB2, 0xB6, 0xBA, 0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, -0xB8, 0xAA, 0x87, 0x2C, 0x54, 0x7C, 0xBA, 0xA4, 0xB0, 0x8A, 0xB6, 0x91, 0x32, 0x56, 0x76, 0xB2, -0x84, 0x94, 0xA4, 0xC8, 0x08, 0xCD, 0xD8, 0xB8, 0xB4, 0xB0, 0xF1, 0x99, 0x82, 0xA8, 0x2D, 0x55, -0x7D, 0x98, 0xA8, 0x0E, 0x16, 0x1E, 0xA2, 0x2C, 0x54, 0x7C, 0x92, 0xA4, 0xF0, 0x2C, 0x50, 0x78, -/* bank # 5 */ -0xF1, 0x84, 0xA8, 0x98, 0xC4, 0xCD, 0xFC, 0xD8, 0x0D, 0xDB, 0xA8, 0xFC, 0x2D, 0xF3, 0xD9, 0xBA, -0xA6, 0xF8, 0xDA, 0xBA, 0xA6, 0xDE, 0xD8, 0xBA, 0xB2, 0xB6, 0x86, 0x96, 0xA6, 0xD0, 0xF3, 0xC8, -0x41, 0xDA, 0xA6, 0xC8, 0xF8, 0xD8, 0xB0, 0xB4, 0xB8, 0x82, 0xA8, 0x92, 0xF5, 0x2C, 0x54, 0x88, -0x98, 0xF1, 0x35, 0xD9, 0xF4, 0x18, 0xD8, 0xF1, 0xA2, 0xD0, 0xF8, 0xF9, 0xA8, 0x84, 0xD9, 0xC7, -0xDF, 0xF8, 0xF8, 0x83, 0xC5, 0xDA, 0xDF, 0x69, 0xDF, 0x83, 0xC1, 0xD8, 0xF4, 0x01, 0x14, 0xF1, -0xA8, 0x82, 0x4E, 0xA8, 0x84, 0xF3, 0x11, 0xD1, 0x82, 0xF5, 0xD9, 0x92, 0x28, 0x97, 0x88, 0xF1, -0x09, 0xF4, 0x1C, 0x1C, 0xD8, 0x84, 0xA8, 0xF3, 0xC0, 0xF9, 0xD1, 0xD9, 0x97, 0x82, 0xF1, 0x29, -0xF4, 0x0D, 0xD8, 0xF3, 0xF9, 0xF9, 0xD1, 0xD9, 0x82, 0xF4, 0xC2, 0x03, 0xD8, 0xDE, 0xDF, 0x1A, -0xD8, 0xF1, 0xA2, 0xFA, 0xF9, 0xA8, 0x84, 0x98, 0xD9, 0xC7, 0xDF, 0xF8, 0xF8, 0xF8, 0x83, 0xC7, -0xDA, 0xDF, 0x69, 0xDF, 0xF8, 0x83, 0xC3, 0xD8, 0xF4, 0x01, 0x14, 0xF1, 0x98, 0xA8, 0x82, 0x2E, -0xA8, 0x84, 0xF3, 0x11, 0xD1, 0x82, 0xF5, 0xD9, 0x92, 0x50, 0x97, 0x88, 0xF1, 0x09, 0xF4, 0x1C, -0xD8, 0x84, 0xA8, 0xF3, 0xC0, 0xF8, 0xF9, 0xD1, 0xD9, 0x97, 0x82, 0xF1, 0x49, 0xF4, 0x0D, 0xD8, -0xF3, 0xF9, 0xF9, 0xD1, 0xD9, 0x82, 0xF4, 0xC4, 0x03, 0xD8, 0xDE, 0xDF, 0xD8, 0xF1, 0xAD, 0x88, -0x98, 0xCC, 0xA8, 0x09, 0xF9, 0xD9, 0x82, 0x92, 0xA8, 0xF5, 0x7C, 0xF1, 0x88, 0x3A, 0xCF, 0x94, -0x4A, 0x6E, 0x98, 0xDB, 0x69, 0x31, 0xDA, 0xAD, 0xF2, 0xDE, 0xF9, 0xD8, 0x87, 0x95, 0xA8, 0xF2, -0x21, 0xD1, 0xDA, 0xA5, 0xF9, 0xF4, 0x17, 0xD9, 0xF1, 0xAE, 0x8E, 0xD0, 0xC0, 0xC3, 0xAE, 0x82, -/* bank # 6 */ -0xC6, 0x84, 0xC3, 0xA8, 0x85, 0x95, 0xC8, 0xA5, 0x88, 0xF2, 0xC0, 0xF1, 0xF4, 0x01, 0x0E, 0xF1, -0x8E, 0x9E, 0xA8, 0xC6, 0x3E, 0x56, 0xF5, 0x54, 0xF1, 0x88, 0x72, 0xF4, 0x01, 0x15, 0xF1, 0x98, -0x45, 0x85, 0x6E, 0xF5, 0x8E, 0x9E, 0x04, 0x88, 0xF1, 0x42, 0x98, 0x5A, 0x8E, 0x9E, 0x06, 0x88, -0x69, 0xF4, 0x01, 0x1C, 0xF1, 0x98, 0x1E, 0x11, 0x08, 0xD0, 0xF5, 0x04, 0xF1, 0x1E, 0x97, 0x02, -0x02, 0x98, 0x36, 0x25, 0xDB, 0xF9, 0xD9, 0x85, 0xA5, 0xF3, 0xC1, 0xDA, 0x85, 0xA5, 0xF3, 0xDF, -0xD8, 0x85, 0x95, 0xA8, 0xF3, 0x09, 0xDA, 0xA5, 0xFA, 0xD8, 0x82, 0x92, 0xA8, 0xF5, 0x78, 0xF1, -0x88, 0x1A, 0x84, 0x9F, 0x26, 0x88, 0x98, 0x21, 0xDA, 0xF4, 0x1D, 0xF3, 0xD8, 0x87, 0x9F, 0x39, -0xD1, 0xAF, 0xD9, 0xDF, 0xDF, 0xFB, 0xF9, 0xF4, 0x0C, 0xF3, 0xD8, 0xFA, 0xD0, 0xF8, 0xDA, 0xF9, -0xF9, 0xD0, 0xDF, 0xD9, 0xF9, 0xD8, 0xF4, 0x0B, 0xD8, 0xF3, 0x87, 0x9F, 0x39, 0xD1, 0xAF, 0xD9, -0xDF, 0xDF, 0xF4, 0x1D, 0xF3, 0xD8, 0xFA, 0xFC, 0xA8, 0x69, 0xF9, 0xF9, 0xAF, 0xD0, 0xDA, 0xDE, -0xFA, 0xD9, 0xF8, 0x8F, 0x9F, 0xA8, 0xF1, 0xCC, 0xF3, 0x98, 0xDB, 0x45, 0xD9, 0xAF, 0xDF, 0xD0, -0xF8, 0xD8, 0xF1, 0x8F, 0x9F, 0xA8, 0xCA, 0xF3, 0x88, 0x09, 0xDA, 0xAF, 0x8F, 0xCB, 0xF8, 0xD8, -0xF2, 0xAD, 0x97, 0x8D, 0x0C, 0xD9, 0xA5, 0xDF, 0xF9, 0xBA, 0xA6, 0xF3, 0xFA, 0xF4, 0x12, 0xF2, -0xD8, 0x95, 0x0D, 0xD1, 0xD9, 0xBA, 0xA6, 0xF3, 0xFA, 0xDA, 0xA5, 0xF2, 0xC1, 0xBA, 0xA6, 0xF3, -0xDF, 0xD8, 0xF1, 0xBA, 0xB2, 0xB6, 0x86, 0x96, 0xA6, 0xD0, 0xCA, 0xF3, 0x49, 0xDA, 0xA6, 0xCB, -0xF8, 0xD8, 0xB0, 0xB4, 0xB8, 0xD8, 0xAD, 0x84, 0xF2, 0xC0, 0xDF, 0xF1, 0x8F, 0xCB, 0xC3, 0xA8, -/* bank # 7 */ -0xB2, 0xB6, 0x86, 0x96, 0xC8, 0xC1, 0xCB, 0xC3, 0xF3, 0xB0, 0xB4, 0x88, 0x98, 0xA8, 0x21, 0xDB, -0x71, 0x8D, 0x9D, 0x71, 0x85, 0x95, 0x21, 0xD9, 0xAD, 0xF2, 0xFA, 0xD8, 0x85, 0x97, 0xA8, 0x28, -0xD9, 0xF4, 0x08, 0xD8, 0xF2, 0x8D, 0x29, 0xDA, 0xF4, 0x05, 0xD9, 0xF2, 0x85, 0xA4, 0xC2, 0xF2, -0xD8, 0xA8, 0x8D, 0x94, 0x01, 0xD1, 0xD9, 0xF4, 0x11, 0xF2, 0xD8, 0x87, 0x21, 0xD8, 0xF4, 0x0A, -0xD8, 0xF2, 0x84, 0x98, 0xA8, 0xC8, 0x01, 0xD1, 0xD9, 0xF4, 0x11, 0xD8, 0xF3, 0xA4, 0xC8, 0xBB, -0xAF, 0xD0, 0xF2, 0xDE, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xD8, 0xF1, 0xB8, 0xF6, -0xB5, 0xB9, 0xB0, 0x8A, 0x95, 0xA3, 0xDE, 0x3C, 0xA3, 0xD9, 0xF8, 0xD8, 0x5C, 0xA3, 0xD9, 0xF8, -0xD8, 0x7C, 0xA3, 0xD9, 0xF8, 0xD8, 0xF8, 0xF9, 0xD1, 0xA5, 0xD9, 0xDF, 0xDA, 0xFA, 0xD8, 0xB1, -0x85, 0x30, 0xF7, 0xD9, 0xDE, 0xD8, 0xF8, 0x30, 0xAD, 0xDA, 0xDE, 0xD8, 0xF2, 0xB4, 0x8C, 0x99, -0xA3, 0x2D, 0x55, 0x7D, 0xA0, 0x83, 0xDF, 0xDF, 0xDF, 0xB5, 0x91, 0xA0, 0xF6, 0x29, 0xD9, 0xFB, -0xD8, 0xA0, 0xFC, 0x29, 0xD9, 0xFA, 0xD8, 0xA0, 0xD0, 0x51, 0xD9, 0xF8, 0xD8, 0xFC, 0x51, 0xD9, -0xF9, 0xD8, 0x79, 0xD9, 0xFB, 0xD8, 0xA0, 0xD0, 0xFC, 0x79, 0xD9, 0xFA, 0xD8, 0xA1, 0xF9, 0xF9, -0xF9, 0xF9, 0xF9, 0xA0, 0xDA, 0xDF, 0xDF, 0xDF, 0xD8, 0xA1, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xAC, -0xDE, 0xF8, 0xAD, 0xDE, 0x83, 0x93, 0xAC, 0x2C, 0x54, 0x7C, 0xF1, 0xA8, 0xDF, 0xDF, 0xDF, 0xF6, -0x9D, 0x2C, 0xDA, 0xA0, 0xDF, 0xD9, 0xFA, 0xDB, 0x2D, 0xF8, 0xD8, 0xA8, 0x50, 0xDA, 0xA0, 0xD0, -0xDE, 0xD9, 0xD0, 0xF8, 0xF8, 0xF8, 0xDB, 0x55, 0xF8, 0xD8, 0xA8, 0x78, 0xDA, 0xA0, 0xD0, 0xDF, -/* bank # 8 */ -0xD9, 0xD0, 0xFA, 0xF8, 0xF8, 0xF8, 0xF8, 0xDB, 0x7D, 0xF8, 0xD8, 0x9C, 0xA8, 0x8C, 0xF5, 0x30, -0xDB, 0x38, 0xD9, 0xD0, 0xDE, 0xDF, 0xA0, 0xD0, 0xDE, 0xDF, 0xD8, 0xA8, 0x48, 0xDB, 0x58, 0xD9, -0xDF, 0xD0, 0xDE, 0xA0, 0xDF, 0xD0, 0xDE, 0xD8, 0xA8, 0x68, 0xDB, 0x70, 0xD9, 0xDF, 0xDF, 0xA0, -0xDF, 0xDF, 0xD8, 0xF1, 0xA8, 0x88, 0x90, 0x2C, 0x54, 0x7C, 0x98, 0xA8, 0xD0, 0x5C, 0x38, 0xD1, -0xDA, 0xF2, 0xAE, 0x8C, 0xDF, 0xF9, 0xD8, 0xB0, 0x87, 0xA8, 0xC1, 0xC1, 0xB1, 0x88, 0xA8, 0xC6, -0xF9, 0xF9, 0xDA, 0x36, 0xD8, 0xA8, 0xF9, 0xDA, 0x36, 0xD8, 0xA8, 0xF9, 0xDA, 0x36, 0xD8, 0xA8, -0xF9, 0xDA, 0x36, 0xD8, 0xA8, 0xF9, 0xDA, 0x36, 0xD8, 0xF7, 0x8D, 0x9D, 0xAD, 0xF8, 0x18, 0xDA, -0xF2, 0xAE, 0xDF, 0xD8, 0xF7, 0xAD, 0xFA, 0x30, 0xD9, 0xA4, 0xDE, 0xF9, 0xD8, 0xF2, 0xAE, 0xDE, -0xFA, 0xF9, 0x83, 0xA7, 0xD9, 0xC3, 0xC5, 0xC7, 0xF1, 0x88, 0x9B, 0xA7, 0x7A, 0xAD, 0xF7, 0xDE, -0xDF, 0xA4, 0xF8, 0x84, 0x94, 0x08, 0xA7, 0x97, 0xF3, 0x00, 0xAE, 0xF2, 0x98, 0x19, 0xA4, 0x88, -0xC6, 0xA3, 0x94, 0x88, 0xF6, 0x32, 0xDF, 0xF2, 0x83, 0x93, 0xDB, 0x09, 0xD9, 0xF2, 0xAA, 0xDF, -0xD8, 0xD8, 0xAE, 0xF8, 0xF9, 0xD1, 0xDA, 0xF3, 0xA4, 0xDE, 0xA7, 0xF1, 0x88, 0x9B, 0x7A, 0xD8, -0xF3, 0x84, 0x94, 0xAE, 0x19, 0xF9, 0xDA, 0xAA, 0xF1, 0xDF, 0xD8, 0xA8, 0x81, 0xC0, 0xC3, 0xC5, -0xC7, 0xA3, 0x92, 0x83, 0xF6, 0x28, 0xAD, 0xDE, 0xD9, 0xF8, 0xD8, 0xA3, 0x50, 0xAD, 0xD9, 0xF8, -0xD8, 0xA3, 0x78, 0xAD, 0xD9, 0xF8, 0xD8, 0xF8, 0xF9, 0xD1, 0xA1, 0xDA, 0xDE, 0xC3, 0xC5, 0xC7, -0xD8, 0xA1, 0x81, 0x94, 0xF8, 0x18, 0xF2, 0xB0, 0x89, 0xAC, 0xC3, 0xC5, 0xC7, 0xF1, 0xD8, 0xB8, -/* bank # 9 */ -0xB4, 0xB0, 0x97, 0x86, 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97, 0x28, 0x88, 0x9B, 0xF0, -0x0C, 0x20, 0x14, 0x40, 0xB0, 0xB4, 0xB8, 0xF0, 0xA8, 0x8A, 0x9A, 0x28, 0x50, 0x78, 0xB7, 0x9B, -0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xF1, 0xBB, 0xAB, -0x88, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0xB3, 0x8B, 0xB8, 0xA8, 0x04, 0x28, 0x50, 0x78, 0xF1, 0xB0, -0x88, 0xB4, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xBB, 0xAB, 0xB3, 0x8B, 0x02, 0x26, 0x46, 0x66, 0xB0, -0xB8, 0xF0, 0x8A, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x8B, 0x29, 0x51, 0x79, 0x8A, 0x24, 0x70, 0x59, -0x8B, 0x20, 0x58, 0x71, 0x8A, 0x44, 0x69, 0x38, 0x8B, 0x39, 0x40, 0x68, 0x8A, 0x64, 0x48, 0x31, -0x8B, 0x30, 0x49, 0x60, 0x88, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0x8C, 0xA8, 0x04, 0x28, -0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, 0x26, 0x46, 0x66, 0xF0, -0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xA9, -0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, 0x31, 0x48, 0x60, 0x8C, -0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, 0xA8, 0x6E, 0x76, 0x7E, -0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0xD8, 0xB1, 0xB5, 0xB9, 0xA3, 0xDF, 0xDF, 0xDF, 0xAE, 0xD0, -0xDF, 0xAA, 0xD0, 0xDE, 0xF2, 0xAB, 0xF8, 0xF9, 0xD9, 0xB0, 0x87, 0xC4, 0xAA, 0xF1, 0xDF, 0xDF, -0xBB, 0xAF, 0xDF, 0xDF, 0xB9, 0xD8, 0xB1, 0xF1, 0xA3, 0x97, 0x8E, 0x60, 0xDF, 0xB0, 0x84, 0xF2, -0xC8, 0xF8, 0xF9, 0xD9, 0xDE, 0xD8, 0x93, 0x85, 0xF1, 0x4A, 0xB1, 0x83, 0xA3, 0x08, 0xB5, 0x83, -/* bank # 10 */ -0x9A, 0x08, 0x10, 0xB7, 0x9F, 0x10, 0xD8, 0xF1, 0xB0, 0xBA, 0xAE, 0xB0, 0x8A, 0xC2, 0xB2, 0xB6, -0x8E, 0x9E, 0xF1, 0xFB, 0xD9, 0xF4, 0x1D, 0xD8, 0xF9, 0xD9, 0x0C, 0xF1, 0xD8, 0xF8, 0xF8, 0xAD, -0x61, 0xD9, 0xAE, 0xFB, 0xD8, 0xF4, 0x0C, 0xF1, 0xD8, 0xF8, 0xF8, 0xAD, 0x19, 0xD9, 0xAE, 0xFB, -0xDF, 0xD8, 0xF4, 0x16, 0xF1, 0xD8, 0xF8, 0xAD, 0x8D, 0x61, 0xD9, 0xF4, 0xF4, 0xAC, 0xF5, 0x9C, -0x9C, 0x8D, 0xDF, 0x2B, 0xBA, 0xB6, 0xAE, 0xFA, 0xF8, 0xF4, 0x0B, 0xD8, 0xF1, 0xAE, 0xD0, 0xF8, -0xAD, 0x51, 0xDA, 0xAE, 0xFA, 0xF8, 0xF1, 0xD8, 0xB9, 0xB1, 0xB6, 0xA3, 0x83, 0x9C, 0x08, 0xB9, -0xB1, 0x83, 0x9A, 0xB5, 0xAA, 0xC0, 0xFD, 0x30, 0x83, 0xB7, 0x9F, 0x10, 0xB5, 0x8B, 0x93, 0xF2, -0x02, 0x02, 0xD1, 0xAB, 0xDA, 0xDE, 0xD8, 0xF1, 0xB0, 0x80, 0xBA, 0xAB, 0xC0, 0xC3, 0xB2, 0x84, -0xC1, 0xC3, 0xD8, 0xB1, 0xB9, 0xF3, 0x8B, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xB0, -0x87, 0x9C, 0xB9, 0xA3, 0xDD, 0xF1, 0xB3, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0xB0, 0x87, 0x20, 0x28, -0x30, 0x38, 0xB2, 0x8B, 0xB6, 0x9B, 0xF2, 0xA3, 0xC0, 0xC8, 0xC2, 0xC4, 0xCC, 0xC6, 0xA3, 0xA3, -0xA3, 0xF1, 0xB0, 0x87, 0xB5, 0x9A, 0xD8, 0xF3, 0x9B, 0xA3, 0xA3, 0xDC, 0xBA, 0xAC, 0xDF, 0xB9, -0xA3, 0xFE, 0xF2, 0xAB, 0xC4, 0xAA, 0xF1, 0xDF, 0xDF, 0xBB, 0xAF, 0xDF, 0xDF, 0xA3, 0xA3, 0xA3, -0xD8, 0xD8, 0xD8, 0xBB, 0xB3, 0xB7, 0xF1, 0xAA, 0xF9, 0xDA, 0xFF, 0xD9, 0x80, 0x9A, 0xAA, 0x28, -0xB4, 0x80, 0x98, 0xA7, 0x20, 0xB7, 0x97, 0x87, 0xA8, 0x66, 0x88, 0xF0, 0x79, 0x51, 0xF1, 0x90, -0x2C, 0x87, 0x0C, 0xA7, 0x81, 0x97, 0x62, 0x93, 0xF0, 0x71, 0x71, 0x60, 0x85, 0x94, 0x01, 0x29, -/* bank # 11 */ -0x51, 0x79, 0x90, 0xA5, 0xF1, 0x28, 0x4C, 0x6C, 0x87, 0x0C, 0x95, 0x18, 0x85, 0x78, 0xA3, 0x83, -0x90, 0x28, 0x4C, 0x6C, 0x88, 0x6C, 0xD8, 0xF3, 0xA2, 0x82, 0x00, 0xF2, 0x10, 0xA8, 0x92, 0x19, -0x80, 0xA2, 0xF2, 0xD9, 0x26, 0xD8, 0xF1, 0x88, 0xA8, 0x4D, 0xD9, 0x48, 0xD8, 0x96, 0xA8, 0x39, -0x80, 0xD9, 0x3C, 0xD8, 0x95, 0x80, 0xA8, 0x39, 0xA6, 0x86, 0x98, 0xD9, 0x2C, 0xDA, 0x87, 0xA7, -0x2C, 0xD8, 0xA8, 0x89, 0x95, 0x19, 0xA9, 0x80, 0xD9, 0x38, 0xD8, 0xA8, 0x89, 0x39, 0xA9, 0x80, -0xDA, 0x3C, 0xD8, 0xA8, 0x2E, 0xA8, 0x39, 0x90, 0xD9, 0x0C, 0xD8, 0xA8, 0x95, 0x31, 0x98, 0xD9, -0x0C, 0xD8, 0xA8, 0x09, 0xD9, 0xFF, 0xD8, 0x01, 0xDA, 0xFF, 0xD8, 0x95, 0x39, 0xA9, 0xDA, 0x26, -0xFF, 0xD8, 0x90, 0xA8, 0x0D, 0x89, 0x99, 0xA8, 0x10, 0x80, 0x98, 0x21, 0xDA, 0x2E, 0xD8, 0x89, -0x99, 0xA8, 0x31, 0x80, 0xDA, 0x2E, 0xD8, 0xA8, 0x86, 0x96, 0x31, 0x80, 0xDA, 0x2E, 0xD8, 0xA8, -0x87, 0x31, 0x80, 0xDA, 0x2E, 0xD8, 0xA8, 0x82, 0x92, 0xF3, 0x41, 0x80, 0xF1, 0xD9, 0x2E, 0xD8, -0xA8, 0x82, 0xF3, 0x19, 0x80, 0xF1, 0xD9, 0x2E, 0xD8, 0x82, 0xAC, 0xF3, 0xC0, 0xA2, 0x80, 0x22, -0xF1, 0xA6, 0x2E, 0xA7, 0x2E, 0xA9, 0x22, 0x98, 0xA8, 0x29, 0xDA, 0xAC, 0xDE, 0xFF, 0xD8, 0xA2, -0xF2, 0x2A, 0xF1, 0xA9, 0x2E, 0x82, 0x92, 0xA8, 0xF2, 0x31, 0x80, 0xA6, 0x96, 0xF1, 0xD9, 0x00, -0xAC, 0x8C, 0x9C, 0x0C, 0x30, 0xAC, 0xDE, 0xD0, 0xDE, 0xFF, 0xD8, 0x8C, 0x9C, 0xAC, 0xD0, 0x10, -0xAC, 0xDE, 0x80, 0x92, 0xA2, 0xF2, 0x4C, 0x82, 0xA8, 0xF1, 0xCA, 0xF2, 0x35, 0xF1, 0x96, 0x88, -0xA6, 0xD9, 0x00, 0xD8, 0xF1, 0xFF, -}; - -// this divisor is pre configured into the above image and can't be modified at this time. -#ifndef MPU6050_DMP_FIFO_RATE_DIVISOR -#define MPU6050_DMP_FIFO_RATE_DIVISOR 0x01 // The New instance of the Firmware has this as the default -#endif - -// this is the most basic initialization I can create. with the intent that we access the register bytes as few times as needed to get the job done. -// for detailed descriptins of all registers and there purpose google "MPU-6000/MPU-6050 Register Map and Descriptions" -uint8_t MPU6050::dmpInitialize() { // Lets get it over with fast Write everything once and set it up necely - uint8_t val; - uint16_t ival; - // Reset procedure per instructions in the "MPU-6000/MPU-6050 Register Map and Descriptions" page 41 - I2Cdev::writeBit(devAddr,0x6B, 7, (val = 1)); //PWR_MGMT_1: reset with 100ms delay - delay(100); - I2Cdev::writeBits(devAddr,0x6A, 2, 3, (val = 0b111)); // full SIGNAL_PATH_RESET: with another 100ms delay - delay(100); - I2Cdev::writeBytes(devAddr,0x6B, 1, &(val = 0x01)); // 1000 0001 PWR_MGMT_1:Clock Source Select PLL_X_gyro - I2Cdev::writeBytes(devAddr,0x38, 1, &(val = 0x00)); // 0000 0000 INT_ENABLE: no Interrupt - I2Cdev::writeBytes(devAddr,0x23, 1, &(val = 0x00)); // 0000 0000 MPU FIFO_EN: (all off) Using DMP's FIFO instead - I2Cdev::writeBytes(devAddr,0x1C, 1, &(val = 0x00)); // 0000 0000 ACCEL_CONFIG: 0 = Accel Full Scale Select: 2g - I2Cdev::writeBytes(devAddr,0x37, 1, &(val = 0x80)); // 1001 0000 INT_PIN_CFG: ACTL The logic level for int pin is active low. and interrupt status bits are cleared on any read - I2Cdev::writeBytes(devAddr,0x6B, 1, &(val = 0x01)); // 0000 0001 PWR_MGMT_1: Clock Source Select PLL_X_gyro - I2Cdev::writeBytes(devAddr,0x19, 1, &(val = 0x04)); // 0000 0100 SMPLRT_DIV: Divides the internal sample rate 400Hz ( Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV)) - I2Cdev::writeBytes(devAddr,0x1A, 1, &(val = 0x01)); // 0000 0001 CONFIG: Digital Low Pass Filter (DLPF) Configuration 188HZ //Im betting this will be the beat - if (!writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) return 1; // Loads the DMP image into the MPU6050 Memory // Should Never Fail - I2Cdev::writeWords(devAddr, 0x70, 1, &(ival = 0x0400)); // DMP Program Start Address - I2Cdev::writeBytes(devAddr,0x1B, 1, &(val = 0x18)); // 0001 1000 GYRO_CONFIG: 3 = +2000 Deg/sec - I2Cdev::writeBytes(devAddr,0x6A, 1, &(val = 0xC0)); // 1100 1100 USER_CTRL: Enable Fifo and Reset Fifo - I2Cdev::writeBytes(devAddr,0x38, 1, &(val = 0x02)); // 0000 0010 INT_ENABLE: RAW_DMP_INT_EN on - I2Cdev::writeBit(devAddr,0x6A, 2, 1); // Reset FIFO one last time just for kicks. (MPUi2cWrite reads 0x6A first and only alters 1 bit and then saves the byte) - - setDMPEnabled(false); // disable DMP for compatibility with the MPU6050 library -/* - dmpPacketSize += 16;//DMP_FEATURE_6X_LP_QUAT - dmpPacketSize += 6;//DMP_FEATURE_SEND_RAW_ACCEL - dmpPacketSize += 6;//DMP_FEATURE_SEND_RAW_GYRO -*/ - dmpPacketSize = 28; - return 0; -} - -bool MPU6050::dmpPacketAvailable() { - return getFIFOCount() >= dmpGetFIFOPacketSize(); -} - -// uint8_t MPU6050::dmpSetFIFORate(uint8_t fifoRate); -// uint8_t MPU6050::dmpGetFIFORate(); -// uint8_t MPU6050::dmpGetSampleStepSizeMS(); -// uint8_t MPU6050::dmpGetSampleFrequency(); -// int32_t MPU6050::dmpDecodeTemperature(int8_t tempReg); - -//uint8_t MPU6050::dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); -//uint8_t MPU6050::dmpUnregisterFIFORateProcess(inv_obj_func func); -//uint8_t MPU6050::dmpRunFIFORateProcesses(); - -// uint8_t MPU6050::dmpSendQuaternion(uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendPacketNumber(uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); - -uint8_t MPU6050::dmpGetAccel(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[16] << 8) | packet[17]); - data[1] = (((uint32_t)packet[18] << 8) | packet[19]); - data[2] = (((uint32_t)packet[20] << 8) | packet[21]); - return 0; -} -uint8_t MPU6050::dmpGetAccel(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (packet[16] << 8) | packet[17]; - data[1] = (packet[18] << 8) | packet[19]; - data[2] = (packet[20] << 8) | packet[21]; - return 0; -} -uint8_t MPU6050::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - v -> x = (packet[16] << 8) | packet[17]; - v -> y = (packet[18] << 8) | packet[19]; - v -> z = (packet[20] << 8) | packet[21]; - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[0] << 24) | ((uint32_t)packet[1] << 16) | ((uint32_t)packet[2] << 8) | packet[3]); - data[1] = (((uint32_t)packet[4] << 24) | ((uint32_t)packet[5] << 16) | ((uint32_t)packet[6] << 8) | packet[7]); - data[2] = (((uint32_t)packet[8] << 24) | ((uint32_t)packet[9] << 16) | ((uint32_t)packet[10] << 8) | packet[11]); - data[3] = (((uint32_t)packet[12] << 24) | ((uint32_t)packet[13] << 16) | ((uint32_t)packet[14] << 8) | packet[15]); - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = ((packet[0] << 8) | packet[1]); - data[1] = ((packet[4] << 8) | packet[5]); - data[2] = ((packet[8] << 8) | packet[9]); - data[3] = ((packet[12] << 8) | packet[13]); - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - int16_t qI[4]; - uint8_t status = dmpGetQuaternion(qI, packet); - if (status == 0) { - q -> w = (float)qI[0] / 16384.0f; - q -> x = (float)qI[1] / 16384.0f; - q -> y = (float)qI[2] / 16384.0f; - q -> z = (float)qI[3] / 16384.0f; - return 0; - } - return status; // int16 return value, indicates error if this line is reached -} -// uint8_t MPU6050::dmpGet6AxisQuaternion(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetRelativeQuaternion(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetGyro(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[22] << 8) | packet[23]); - data[1] = (((uint32_t)packet[24] << 8) | packet[25]); - data[2] = (((uint32_t)packet[26] << 8) | packet[27]); - return 0; -} -uint8_t MPU6050::dmpGetGyro(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (packet[22] << 8) | packet[23]; - data[1] = (packet[24] << 8) | packet[25]; - data[2] = (packet[26] << 8) | packet[27]; - return 0; -} -uint8_t MPU6050::dmpGetGyro(VectorInt16 *v, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - v -> x = (packet[22] << 8) | packet[23]; - v -> y = (packet[24] << 8) | packet[25]; - v -> z = (packet[26] << 8) | packet[27]; - return 0; -} -// uint8_t MPU6050::dmpSetLinearAccelFilterCoefficient(float coef); -// uint8_t MPU6050::dmpGetLinearAccel(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) { - // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g) - v -> x = vRaw -> x - gravity -> x*8192; - v -> y = vRaw -> y - gravity -> y*8192; - v -> z = vRaw -> z - gravity -> z*8192; - return 0; -} -// uint8_t MPU6050::dmpGetLinearAccelInWorld(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) { - // rotate measured 3D acceleration vector into original state - // frame of reference based on orientation quaternion - memcpy(v, vReal, sizeof(VectorInt16)); - v -> rotate(q); - return 0; -} -// uint8_t MPU6050::dmpGetGyroAndAccelSensor(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetGyroSensor(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetControlData(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetTemperature(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetGravity(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetGravity(int16_t *data, const uint8_t* packet) { - /* +1g corresponds to +8192, sensitivity is 2g. */ - int16_t qI[4]; - uint8_t status = dmpGetQuaternion(qI, packet); - data[0] = ((int32_t)qI[1] * qI[3] - (int32_t)qI[0] * qI[2]) / 16384; - data[1] = ((int32_t)qI[0] * qI[1] + (int32_t)qI[2] * qI[3]) / 16384; - data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1] - - (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (2 * 16384); - return status; -} - -uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q) { - v -> x = 2 * (q -> x*q -> z - q -> w*q -> y); - v -> y = 2 * (q -> w*q -> x + q -> y*q -> z); - v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z; - return 0; -} -// uint8_t MPU6050::dmpGetUnquantizedAccel(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetQuantizedAccel(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetExternalSensorData(long *data, int size, const uint8_t* packet); -// uint8_t MPU6050::dmpGetEIS(long *data, const uint8_t* packet); - -uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) { - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // psi - data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y); // theta - data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi - return 0; -} - -#ifdef USE_OLD_DMPGETYAWPITCHROLL -uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { - // yaw: (about Z axis) - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); - // pitch: (nose up/down, about Y axis) - data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); - // roll: (tilt left/right, about X axis) - data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z)); - return 0; -} -#else -uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { - // yaw: (about Z axis) - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); - // pitch: (nose up/down, about Y axis) - data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); - // roll: (tilt left/right, about X axis) - data[2] = atan2(gravity -> y , gravity -> z); - if (gravity -> z < 0) { - if(data[1] > 0) { - data[1] = PI - data[1]; - } else { - data[1] = -PI - data[1]; - } - } - return 0; -} -#endif - -// uint8_t MPU6050::dmpGetAccelFloat(float *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetQuaternionFloat(float *data, const uint8_t* packet); - -uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) { - /*for (uint8_t k = 0; k < dmpPacketSize; k++) { - if (dmpData[k] < 0x10) Serial.print("0"); - Serial.print(dmpData[k], HEX); - Serial.print(" "); - } - Serial.print("\n");*/ - //Serial.println((uint16_t)dmpPacketBuffer); - return 0; -} -uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) { - uint8_t status; - uint8_t buf[dmpPacketSize]; - for (uint8_t i = 0; i < numPackets; i++) { - // read packet from FIFO - getFIFOBytes(buf, dmpPacketSize); - - // process packet - if ((status = dmpProcessFIFOPacket(buf)) > 0) return status; - - // increment external process count variable, if supplied - if (processed != 0) (*processed)++; - } - return 0; -} - -// uint8_t MPU6050::dmpSetFIFOProcessedCallback(void (*func) (void)); - -// uint8_t MPU6050::dmpInitFIFOParam(); -// uint8_t MPU6050::dmpCloseFIFO(); -// uint8_t MPU6050::dmpSetGyroDataSource(uint_fast8_t source); -// uint8_t MPU6050::dmpDecodeQuantizedAccel(); -// uint32_t MPU6050::dmpGetGyroSumOfSquare(); -// uint32_t MPU6050::dmpGetAccelSumOfSquare(); -// void MPU6050::dmpOverrideQuaternion(long *q); -uint16_t MPU6050::dmpGetFIFOPacketSize() { - return dmpPacketSize; -} - - - -uint8_t MPU6050::dmpGetCurrentFIFOPacket(uint8_t *data) { // overflow proof - return(GetCurrentFIFOPacket(data, dmpPacketSize)); -} - -#endif /* _MPU6050_6AXIS_MOTIONAPPS20_H_ */ diff --git a/mpu6050-master/src/MPU6050_9Axis_MotionApps41.h b/mpu6050-master/src/MPU6050_9Axis_MotionApps41.h deleted file mode 100644 index 3e2608b776a6b8e4a4608a41efc55e61a98c0167..0000000000000000000000000000000000000000 --- a/mpu6050-master/src/MPU6050_9Axis_MotionApps41.h +++ /dev/null @@ -1,889 +0,0 @@ -// I2Cdev library collection - MPU6050 I2C device class, 9-axis MotionApps 4.1 implementation -// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) -// 6/18/2012 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// ... - ongoing debug release - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -#ifndef _MPU6050_9AXIS_MOTIONAPPS41_H_ -#define _MPU6050_9AXIS_MOTIONAPPS41_H_ - -#include "I2Cdev.h" -#include "helper_3dmath.h" - -// MotionApps 4.1 DMP implementation, built using the MPU-9150 "MotionFit" board -#define MPU6050_INCLUDE_DMP_MOTIONAPPS41 - -#include "MPU6050.h" - -// Tom Carpenter's conditional PROGMEM code -// http://forum.arduino.cc/index.php?topic=129407.0 -#ifdef __AVR__ - #include <avr/pgmspace.h> -#elif defined(ESP32) - #include <pgmspace.h> -#else - // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen - #ifndef __PGMSPACE_H_ - #define __PGMSPACE_H_ 1 - #include <inttypes.h> - - #define PROGMEM - #define PGM_P const char * - #define PSTR(str) (str) - #define F(x) x - - typedef void prog_void; - typedef char prog_char; - //typedef unsigned char prog_uchar; - typedef int8_t prog_int8_t; - typedef uint8_t prog_uint8_t; - typedef int16_t prog_int16_t; - typedef uint16_t prog_uint16_t; - typedef int32_t prog_int32_t; - typedef uint32_t prog_uint32_t; - - #define strcpy_P(dest, src) strcpy((dest), (src)) - #define strcat_P(dest, src) strcat((dest), (src)) - #define strcmp_P(a, b) strcmp((a), (b)) - - #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) - #define pgm_read_word(addr) (*(const unsigned short *)(addr)) - #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) - #define pgm_read_float(addr) (*(const float *)(addr)) - - #define pgm_read_byte_near(addr) pgm_read_byte(addr) - #define pgm_read_word_near(addr) pgm_read_word(addr) - #define pgm_read_dword_near(addr) pgm_read_dword(addr) - #define pgm_read_float_near(addr) pgm_read_float(addr) - #define pgm_read_byte_far(addr) pgm_read_byte(addr) - #define pgm_read_word_far(addr) pgm_read_word(addr) - #define pgm_read_dword_far(addr) pgm_read_dword(addr) - #define pgm_read_float_far(addr) pgm_read_float(addr) - #endif -#endif - -// NOTE! Enabling DEBUG adds about 3.3kB to the flash program size. -// Debug output is now working even on ATMega328P MCUs (e.g. Arduino Uno) -// after moving string constants to flash memory storage using the F() -// compiler macro (Arduino IDE 1.0+ required). - -//#define DEBUG -#ifdef DEBUG - #define DEBUG_PRINT(x) Serial.print(x) - #define DEBUG_PRINTF(x, y) Serial.print(x, y) - #define DEBUG_PRINTLN(x) Serial.println(x) - #define DEBUG_PRINTLNF(x, y) Serial.println(x, y) -#else - #define DEBUG_PRINT(x) - #define DEBUG_PRINTF(x, y) - #define DEBUG_PRINTLN(x) - #define DEBUG_PRINTLNF(x, y) -#endif - -#define MPU6050_DMP_CODE_SIZE 1962 // dmpMemory[] -#define MPU6050_DMP_CONFIG_SIZE 232 // dmpConfig[] -#define MPU6050_DMP_UPDATES_SIZE 140 // dmpUpdates[] - -/* ================================================================================================ * - | Default MotionApps v4.1 48-byte FIFO packet structure: | - | | - | [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ][GYRO X][ ][GYRO Y][ ] | - | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - | | - | [GYRO Z][ ][MAG X ][MAG Y ][MAG Z ][ACC X ][ ][ACC Y ][ ][ACC Z ][ ][ ] | - | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | - * ================================================================================================ */ - -// this block of memory gets written to the MPU on start-up, and it seems -// to be volatile memory, so it has to be done each time (it only takes ~1 -// second though) -const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = { - // bank 0, 256 bytes - 0xFB, 0x00, 0x00, 0x3E, 0x00, 0x0B, 0x00, 0x36, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0xFF, 0xFF, 0xFE, 0x80, 0x01, - 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3E, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCA, 0xE3, 0x09, 0x3E, 0x80, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x41, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x2A, 0x00, 0x00, 0x16, 0x55, 0x00, 0x00, 0x21, 0x82, - 0xFD, 0x87, 0x26, 0x50, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x05, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x00, 0x02, 0x65, 0x32, 0x00, 0x00, 0x5E, 0xC0, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFB, 0x8C, 0x6F, 0x5D, 0xFD, 0x5D, 0x08, 0xD9, 0x00, 0x7C, 0x73, 0x3B, 0x00, 0x6C, 0x12, 0xCC, - 0x32, 0x00, 0x13, 0x9D, 0x32, 0x00, 0xD0, 0xD6, 0x32, 0x00, 0x08, 0x00, 0x40, 0x00, 0x01, 0xF4, - 0xFF, 0xE6, 0x80, 0x79, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xD6, 0x00, 0x00, 0x27, 0x10, - - // bank 1, 256 bytes - 0xFB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xFA, 0x36, 0xFF, 0xBC, 0x30, 0x8E, 0x00, 0x05, 0xFB, 0xF0, 0xFF, 0xD9, 0x5B, 0xC8, - 0xFF, 0xD0, 0x9A, 0xBE, 0x00, 0x00, 0x10, 0xA9, 0xFF, 0xF4, 0x1E, 0xB2, 0x00, 0xCE, 0xBB, 0xF7, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x0C, - 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xCF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x3F, 0x68, 0xB6, 0x79, 0x35, 0x28, 0xBC, 0xC6, 0x7E, 0xD1, 0x6C, - 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x0C, 0x02, 0xD0, - - // bank 2, 256 bytes - 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xFF, 0xEF, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x78, 0xA2, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - // bank 3, 256 bytes - 0xD8, 0xDC, 0xF4, 0xD8, 0xB9, 0xAB, 0xF3, 0xF8, 0xFA, 0xF1, 0xBA, 0xA2, 0xDE, 0xB2, 0xB8, 0xB4, - 0xA8, 0x81, 0x98, 0xF7, 0x4A, 0x90, 0x7F, 0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA, - 0xA0, 0x80, 0xF2, 0xCE, 0x81, 0xF3, 0xC2, 0xF1, 0xC1, 0xF2, 0xC3, 0xF3, 0xCC, 0xA2, 0xB2, 0x80, - 0xF1, 0xC6, 0xD8, 0x80, 0xBA, 0xA7, 0xDF, 0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, 0xC5, 0xB6, 0xF0, - 0x87, 0xA2, 0x94, 0x24, 0x48, 0x70, 0x3C, 0x95, 0x40, 0x68, 0x34, 0x58, 0x9B, 0x78, 0xA2, 0xF1, - 0x83, 0x92, 0x2D, 0x55, 0x7D, 0xD8, 0xB1, 0xB4, 0xB8, 0xA1, 0xD0, 0x91, 0x80, 0xF2, 0x70, 0xF3, - 0x70, 0xF2, 0x7C, 0x80, 0xA8, 0xF1, 0x01, 0xB0, 0x98, 0x87, 0xD9, 0x43, 0xD8, 0x86, 0xC9, 0x88, - 0xBA, 0xA1, 0xF2, 0x0E, 0xB8, 0x97, 0x80, 0xF1, 0xA9, 0xDF, 0xDF, 0xDF, 0xAA, 0xDF, 0xDF, 0xDF, - 0xF2, 0xAA, 0xC5, 0xCD, 0xC7, 0xA9, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, 0x97, 0xF1, 0xA9, 0x89, - 0x26, 0x46, 0x66, 0xB0, 0xB4, 0xBA, 0x80, 0xAC, 0xDE, 0xF2, 0xCA, 0xF1, 0xB2, 0x8C, 0x02, 0xA9, - 0xB6, 0x98, 0x00, 0x89, 0x0E, 0x16, 0x1E, 0xB8, 0xA9, 0xB4, 0x99, 0x2C, 0x54, 0x7C, 0xB0, 0x8A, - 0xA8, 0x96, 0x36, 0x56, 0x76, 0xF1, 0xB9, 0xAF, 0xB4, 0xB0, 0x83, 0xC0, 0xB8, 0xA8, 0x97, 0x11, - 0xB1, 0x8F, 0x98, 0xB9, 0xAF, 0xF0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xF1, 0xA3, 0x29, 0x55, - 0x7D, 0xAF, 0x83, 0xB5, 0x93, 0xF0, 0x00, 0x28, 0x50, 0xF5, 0xBA, 0xAD, 0x8F, 0x9F, 0x28, 0x54, - 0x7C, 0xB9, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF, 0xDB, 0xB2, 0xB6, 0x8E, 0x9D, - 0xAE, 0xF5, 0x60, 0x68, 0x70, 0xB1, 0xB5, 0xF1, 0xDA, 0xA6, 0xDF, 0xD9, 0xA6, 0xFA, 0xA3, 0x86, - - // bank 4, 256 bytes - 0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5, 0xC7, 0xB2, 0x8C, 0xC1, - 0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xA8, 0xB2, 0x86, - 0xB4, 0x98, 0x0D, 0x35, 0x5D, 0xB8, 0xAA, 0x98, 0xB0, 0x87, 0x2D, 0x35, 0x3D, 0xB2, 0xB6, 0xBA, - 0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, 0xB8, 0xAA, 0x87, 0x2C, - 0x54, 0x7C, 0xB9, 0xA3, 0xDE, 0xDF, 0xDF, 0xA3, 0xB1, 0x80, 0xF2, 0xC4, 0xCD, 0xC9, 0xF1, 0xB8, - 0xA9, 0xB4, 0x99, 0x83, 0x0D, 0x35, 0x5D, 0x89, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0xB5, 0x93, 0xA3, - 0x0E, 0x16, 0x1E, 0xA9, 0x2C, 0x54, 0x7C, 0xB8, 0xB4, 0xB0, 0xF1, 0x97, 0x83, 0xA8, 0x11, 0x84, - 0xA5, 0x09, 0x98, 0xA3, 0x83, 0xF0, 0xDA, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xD8, 0xF1, 0xA5, - 0x29, 0x55, 0x7D, 0xA5, 0x85, 0x95, 0x02, 0x1A, 0x2E, 0x3A, 0x56, 0x5A, 0x40, 0x48, 0xF9, 0xF3, - 0xA3, 0xD9, 0xF8, 0xF0, 0x98, 0x83, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0x97, 0x82, 0xA8, 0xF1, - 0x11, 0xF0, 0x98, 0xA2, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xDA, 0xF3, 0xDE, 0xD8, 0x83, 0xA5, - 0x94, 0x01, 0xD9, 0xA3, 0x02, 0xF1, 0xA2, 0xC3, 0xC5, 0xC7, 0xD8, 0xF1, 0x84, 0x92, 0xA2, 0x4D, - 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, - 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0x93, 0xA3, 0x4D, - 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, - 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0xA8, 0x8A, 0x9A, - - // bank 5, 256 bytes - 0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98, 0xA8, 0xD9, 0x08, 0xD8, - 0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1, 0xAF, 0xC8, 0x97, 0x87, - 0x34, 0xB5, 0xB9, 0x94, 0xA4, 0x21, 0xF3, 0xD9, 0x22, 0xD8, 0xF2, 0x2D, 0xF3, 0xD9, 0x2A, 0xD8, - 0xF2, 0x35, 0xF3, 0xD9, 0x32, 0xD8, 0x81, 0xA4, 0x60, 0x60, 0x61, 0xD9, 0x61, 0xD8, 0x6C, 0x68, - 0x69, 0xD9, 0x69, 0xD8, 0x74, 0x70, 0x71, 0xD9, 0x71, 0xD8, 0xB1, 0xA3, 0x84, 0x19, 0x3D, 0x5D, - 0xA3, 0x83, 0x1A, 0x3E, 0x5E, 0x93, 0x10, 0x30, 0x81, 0x10, 0x11, 0xB8, 0xB0, 0xAF, 0x8F, 0x94, - 0xF2, 0xDA, 0x3E, 0xD8, 0xB4, 0x9A, 0xA8, 0x87, 0x29, 0xDA, 0xF8, 0xD8, 0x87, 0x9A, 0x35, 0xDA, - 0xF8, 0xD8, 0x87, 0x9A, 0x3D, 0xDA, 0xF8, 0xD8, 0xB1, 0xB9, 0xA4, 0x98, 0x85, 0x02, 0x2E, 0x56, - 0xA5, 0x81, 0x00, 0x0C, 0x14, 0xA3, 0x97, 0xB0, 0x8A, 0xF1, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, - 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x84, 0x0D, 0xDA, 0x0E, 0xD8, 0xA3, 0x29, 0x83, 0xDA, - 0x2C, 0x0E, 0xD8, 0xA3, 0x84, 0x49, 0x83, 0xDA, 0x2C, 0x4C, 0x0E, 0xD8, 0xB8, 0xB0, 0x97, 0x86, - 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97, 0x28, 0x88, 0x9B, 0xF0, 0x0C, 0x20, 0x14, 0x40, - 0xB9, 0xA3, 0x8A, 0xC3, 0xC5, 0xC7, 0x9A, 0xA3, 0x28, 0x50, 0x78, 0xF1, 0xB5, 0x93, 0x01, 0xD9, - 0xDF, 0xDF, 0xDF, 0xD8, 0xB8, 0xB4, 0xA8, 0x8C, 0x9C, 0xF0, 0x04, 0x28, 0x51, 0x79, 0x1D, 0x30, - 0x14, 0x38, 0xB2, 0x82, 0xAB, 0xD0, 0x98, 0x2C, 0x50, 0x50, 0x78, 0x78, 0x9B, 0xF1, 0x1A, 0xB0, - 0xF0, 0xB1, 0x83, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0xB0, 0x8B, 0x29, 0x51, 0x79, 0xB1, 0x83, 0x24, - - // bank 6, 256 bytes - 0x70, 0x59, 0xB0, 0x8B, 0x20, 0x58, 0x71, 0xB1, 0x83, 0x44, 0x69, 0x38, 0xB0, 0x8B, 0x39, 0x40, - 0x68, 0xB1, 0x83, 0x64, 0x48, 0x31, 0xB0, 0x8B, 0x30, 0x49, 0x60, 0xA5, 0x88, 0x20, 0x09, 0x71, - 0x58, 0x44, 0x68, 0x11, 0x39, 0x64, 0x49, 0x30, 0x19, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, - 0x8C, 0xA8, 0x04, 0x28, 0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, - 0x26, 0x46, 0x66, 0xF0, 0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, - 0x64, 0x48, 0x31, 0xA9, 0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, - 0x31, 0x48, 0x60, 0x8C, 0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, - 0xA8, 0x6E, 0x76, 0x7E, 0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0x9E, 0xB9, 0xA3, 0x8A, 0x22, 0x8A, - 0x6E, 0x8A, 0x56, 0x8A, 0x5E, 0x9F, 0xB1, 0x83, 0x06, 0x26, 0x46, 0x66, 0x0E, 0x2E, 0x4E, 0x6E, - 0x9D, 0xB8, 0xAD, 0x00, 0x2C, 0x54, 0x7C, 0xF2, 0xB1, 0x8C, 0xB4, 0x99, 0xB9, 0xA3, 0x2D, 0x55, - 0x7D, 0x81, 0x91, 0xAC, 0x38, 0xAD, 0x3A, 0xB5, 0x83, 0x91, 0xAC, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, - 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0x8C, 0x9D, 0xAE, 0x29, 0xD9, 0x04, 0xAE, 0xD8, 0x51, - 0xD9, 0x04, 0xAE, 0xD8, 0x79, 0xD9, 0x04, 0xD8, 0x81, 0xF3, 0x9D, 0xAD, 0x00, 0x8D, 0xAE, 0x19, - 0x81, 0xAD, 0xD9, 0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7, 0xD9, - 0xAD, 0xAD, 0xAD, 0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E, 0x76, - 0xF3, 0xAC, 0x2E, 0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C, 0xAC, - - // bank 7, 170 bytes (remainder) - 0x30, 0x18, 0xA8, 0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C, 0x24, - 0xF2, 0xB0, 0x89, 0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51, 0xD9, - 0xD8, 0xD8, 0x79, 0xD9, 0xD8, 0xD8, 0xF1, 0x9E, 0x88, 0xA3, 0x31, 0xDA, 0xD8, 0xD8, 0x91, 0x2D, - 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x83, 0x93, 0x35, 0x3D, - 0x80, 0x25, 0xDA, 0xD8, 0xD8, 0x85, 0x69, 0xDA, 0xD8, 0xD8, 0xB4, 0x93, 0x81, 0xA3, 0x28, 0x34, - 0x3C, 0xF3, 0xAB, 0x8B, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xB0, 0x87, 0x9C, 0xB9, - 0xA3, 0xDD, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x95, 0xF1, 0xA3, 0xA3, 0xA3, 0x9D, 0xF1, 0xA3, 0xA3, - 0xA3, 0xA3, 0xF2, 0xA3, 0xB4, 0x90, 0x80, 0xF2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, - 0xA3, 0xA3, 0xB2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB0, 0x87, 0xB5, 0x99, 0xF1, 0xA3, 0xA3, - 0xA3, 0x98, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x97, 0xA3, 0xA3, 0xA3, 0xA3, 0xF3, 0x9B, 0xA3, 0xA3, - 0xDC, 0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xD8, 0xD8, 0xFF -}; - -#ifndef MPU6050_DMP_FIFO_RATE_DIVISOR -#define MPU6050_DMP_FIFO_RATE_DIVISOR 0x03 -#endif - -const unsigned char dmpConfig[MPU6050_DMP_CONFIG_SIZE] PROGMEM = { -// BANK OFFSET LENGTH [DATA] - 0x02, 0xEC, 0x04, 0x00, 0x47, 0x7D, 0x1A, // ? - 0x03, 0x82, 0x03, 0x4C, 0xCD, 0x6C, // FCFG_1 inv_set_gyro_calibration - 0x03, 0xB2, 0x03, 0x36, 0x56, 0x76, // FCFG_3 inv_set_gyro_calibration - 0x00, 0x68, 0x04, 0x02, 0xCA, 0xE3, 0x09, // D_0_104 inv_set_gyro_calibration - 0x01, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, // D_1_152 inv_set_accel_calibration - 0x03, 0x86, 0x03, 0x0C, 0xC9, 0x2C, // FCFG_2 inv_set_accel_calibration - 0x03, 0x90, 0x03, 0x26, 0x46, 0x66, // (continued)...FCFG_2 inv_set_accel_calibration - 0x00, 0x6C, 0x02, 0x40, 0x00, // D_0_108 inv_set_accel_calibration - - 0x02, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_00 inv_set_compass_calibration - 0x02, 0x44, 0x04, 0x40, 0x00, 0x00, 0x00, // CPASS_MTX_01 - 0x02, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_02 - 0x02, 0x4C, 0x04, 0x40, 0x00, 0x00, 0x00, // CPASS_MTX_10 - 0x02, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_11 - 0x02, 0x54, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_12 - 0x02, 0x58, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_20 - 0x02, 0x5C, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_21 - 0x02, 0xBC, 0x04, 0xC0, 0x00, 0x00, 0x00, // CPASS_MTX_22 - - 0x01, 0xEC, 0x04, 0x00, 0x00, 0x40, 0x00, // D_1_236 inv_apply_endian_accel - 0x03, 0x86, 0x06, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, // FCFG_2 inv_set_mpu_sensors - 0x04, 0x22, 0x03, 0x0D, 0x35, 0x5D, // CFG_MOTION_BIAS inv_turn_on_bias_from_no_motion - 0x00, 0xA3, 0x01, 0x00, // ? - 0x04, 0x29, 0x04, 0x87, 0x2D, 0x35, 0x3D, // FCFG_5 inv_set_bias_update - 0x07, 0x62, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38, // CFG_8 inv_send_quaternion - 0x07, 0x9F, 0x01, 0x30, // CFG_16 inv_set_footer - 0x07, 0x67, 0x01, 0x9A, // CFG_GYRO_SOURCE inv_send_gyro - 0x07, 0x68, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_9 inv_send_gyro -> inv_construct3_fifo - 0x07, 0x62, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38, // ? - 0x02, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, // ? - 0x07, 0x83, 0x06, 0xC2, 0xCA, 0xC4, 0xA3, 0xA3, 0xA3, // ? - // SPECIAL 0x01 = enable interrupts - 0x00, 0x00, 0x00, 0x01, // SET INT_ENABLE, SPECIAL INSTRUCTION - 0x07, 0xA7, 0x01, 0xFE, // ? - 0x07, 0x62, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38, // ? - 0x07, 0x67, 0x01, 0x9A, // ? - 0x07, 0x68, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_12 inv_send_accel -> inv_construct3_fifo - 0x07, 0x8D, 0x04, 0xF1, 0x28, 0x30, 0x38, // ??? CFG_12 inv_send_mag -> inv_construct3_fifo - 0x02, 0x16, 0x02, 0x00, MPU6050_DMP_FIFO_RATE_DIVISOR // D_0_22 inv_set_fifo_rate - - // This very last 0x03 WAS a 0x09, which drops the FIFO rate down to 20 Hz. 0x07 is 25 Hz, - // 0x01 is 100Hz. Going faster than 100Hz (0x00=200Hz) tends to result in very noisy data. - // DMP output frequency is calculated easily using this equation: (200Hz / (1 + value)) - - // It is important to make sure the host processor can keep up with reading and processing - // the FIFO output at the desired rate. Handling FIFO overflow cleanly is also a good idea. -}; - -const unsigned char dmpUpdates[MPU6050_DMP_UPDATES_SIZE] PROGMEM = { - 0x01, 0xB2, 0x02, 0xFF, 0xF5, - 0x01, 0x90, 0x04, 0x0A, 0x0D, 0x97, 0xC0, - 0x00, 0xA3, 0x01, 0x00, - 0x04, 0x29, 0x04, 0x87, 0x2D, 0x35, 0x3D, - 0x01, 0x6A, 0x02, 0x06, 0x00, - 0x01, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00, - 0x02, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x08, 0x02, 0x01, 0x20, - 0x01, 0x0A, 0x02, 0x00, 0x4E, - 0x01, 0x02, 0x02, 0xFE, 0xB3, - 0x02, 0x6C, 0x04, 0x00, 0x00, 0x00, 0x00, // READ - 0x02, 0x6C, 0x04, 0xFA, 0xFE, 0x00, 0x00, - 0x02, 0x60, 0x0C, 0xFF, 0xFF, 0xCB, 0x4D, 0x00, 0x01, 0x08, 0xC1, 0xFF, 0xFF, 0xBC, 0x2C, - 0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x02, 0xF8, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x02, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x04, 0x00, 0x40, 0x00, 0x00 -}; - -uint8_t MPU6050::dmpInitialize() { - // reset device - DEBUG_PRINTLN(F("\n\nResetting MPU6050...")); - reset(); - delay(30); // wait after reset - - // disable sleep mode - DEBUG_PRINTLN(F("Disabling sleep mode...")); - setSleepEnabled(false); - - // get MPU product ID - DEBUG_PRINTLN(F("Getting product ID...")); - //uint8_t productID = 0; //getProductID(); - DEBUG_PRINT(F("Product ID = ")); - DEBUG_PRINT(productID); - - // get MPU hardware revision - DEBUG_PRINTLN(F("Selecting user bank 16...")); - setMemoryBank(0x10, true, true); - DEBUG_PRINTLN(F("Selecting memory byte 6...")); - setMemoryStartAddress(0x06); - DEBUG_PRINTLN(F("Checking hardware revision...")); - uint8_t hwRevision = readMemoryByte(); - DEBUG_PRINT(F("Revision @ user[16][6] = ")); - DEBUG_PRINTLNF(hwRevision, HEX); - DEBUG_PRINTLN(F("Resetting memory bank selection to 0...")); - setMemoryBank(0, false, false); - - // check OTP bank valid - DEBUG_PRINTLN(F("Reading OTP bank valid flag...")); - uint8_t otpValid = getOTPBankValid(); - DEBUG_PRINT(F("OTP bank is ")); - DEBUG_PRINTLN(otpValid ? F("valid!") : F("invalid!")); - - // get X/Y/Z gyro offsets - DEBUG_PRINTLN(F("Reading gyro offset values...")); - int8_t xgOffset = getXGyroOffset(); - int8_t ygOffset = getYGyroOffset(); - int8_t zgOffset = getZGyroOffset(); - DEBUG_PRINT(F("X gyro offset = ")); - DEBUG_PRINTLN(xgOffset); - DEBUG_PRINT(F("Y gyro offset = ")); - DEBUG_PRINTLN(ygOffset); - DEBUG_PRINT(F("Z gyro offset = ")); - DEBUG_PRINTLN(zgOffset); - - I2Cdev::readByte(devAddr, MPU6050_RA_USER_CTRL, buffer); // ? - - DEBUG_PRINTLN(F("Enabling interrupt latch, clear on any read, AUX bypass enabled")); - I2Cdev::writeByte(devAddr, MPU6050_RA_INT_PIN_CFG, 0x32); - - // enable MPU AUX I2C bypass mode - //DEBUG_PRINTLN(F("Enabling AUX I2C bypass mode...")); - //setI2CBypassEnabled(true); - - DEBUG_PRINTLN(F("Setting magnetometer mode to power-down...")); - //mag -> setMode(0); - I2Cdev::writeByte(0x0E, 0x0A, 0x00); - - DEBUG_PRINTLN(F("Setting magnetometer mode to fuse access...")); - //mag -> setMode(0x0F); - I2Cdev::writeByte(0x0E, 0x0A, 0x0F); - - DEBUG_PRINTLN(F("Reading mag magnetometer factory calibration...")); - int8_t asax, asay, asaz; - //mag -> getAdjustment(&asax, &asay, &asaz); - I2Cdev::readBytes(0x0E, 0x10, 3, buffer); - asax = (int8_t)buffer[0]; - asay = (int8_t)buffer[1]; - asaz = (int8_t)buffer[2]; - DEBUG_PRINT(F("Adjustment X/Y/Z = ")); - DEBUG_PRINT(asax); - DEBUG_PRINT(F(" / ")); - DEBUG_PRINT(asay); - DEBUG_PRINT(F(" / ")); - DEBUG_PRINTLN(asaz); - - DEBUG_PRINTLN(F("Setting magnetometer mode to power-down...")); - //mag -> setMode(0); - I2Cdev::writeByte(0x0E, 0x0A, 0x00); - - // load DMP code into memory banks - DEBUG_PRINT(F("Writing DMP code to MPU memory banks (")); - DEBUG_PRINT(MPU6050_DMP_CODE_SIZE); - DEBUG_PRINTLN(F(" bytes)")); - if (writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) { - DEBUG_PRINTLN(F("Success! DMP code written and verified.")); - - DEBUG_PRINTLN(F("Configuring DMP and related settings...")); - - // write DMP configuration - DEBUG_PRINT(F("Writing DMP configuration to MPU memory banks (")); - DEBUG_PRINT(MPU6050_DMP_CONFIG_SIZE); - DEBUG_PRINTLN(F(" bytes in config def)")); - if (writeProgDMPConfigurationSet(dmpConfig, MPU6050_DMP_CONFIG_SIZE)) { - DEBUG_PRINTLN(F("Success! DMP configuration written and verified.")); - - DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled...")); - setIntEnabled(1<<MPU6050_INTERRUPT_FIFO_OFLOW_BIT|1<<MPU6050_INTERRUPT_DMP_INT_BIT); - - DEBUG_PRINTLN(F("Setting sample rate to 200Hz...")); - setRate(4); // 1khz / (1 + 4) = 200 Hz - - DEBUG_PRINTLN(F("Setting clock source to Z Gyro...")); - setClockSource(MPU6050_CLOCK_PLL_ZGYRO); - - DEBUG_PRINTLN(F("Setting DLPF bandwidth to 42Hz...")); - setDLPFMode(MPU6050_DLPF_BW_42); - - DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]...")); - setExternalFrameSync(MPU6050_EXT_SYNC_TEMP_OUT_L); - - DEBUG_PRINTLN(F("Setting gyro sensitivity to +/- 2000 deg/sec...")); - setFullScaleGyroRange(MPU6050_GYRO_FS_2000); - - DEBUG_PRINTLN(F("Setting DMP configuration bytes (function unknown)...")); - setDMPConfig1(0x03); - setDMPConfig2(0x00); - - DEBUG_PRINTLN(F("Clearing OTP Bank flag...")); - setOTPBankValid(false); - - DEBUG_PRINTLN(F("Setting X/Y/Z gyro offsets to previous values...")); - setXGyroOffsetTC(xgOffset); - setYGyroOffsetTC(ygOffset); - setZGyroOffsetTC(zgOffset); - - //DEBUG_PRINTLN(F("Setting X/Y/Z gyro user offsets to zero...")); - //setXGyroOffset(0); - //setYGyroOffset(0); - //setZGyroOffset(0); - - DEBUG_PRINTLN(F("Writing final memory update 1/19 (function unknown)...")); - uint8_t dmpUpdate[16], j; - uint16_t pos = 0; - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - - DEBUG_PRINTLN(F("Writing final memory update 2/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - - DEBUG_PRINTLN(F("Resetting FIFO...")); - resetFIFO(); - - DEBUG_PRINTLN(F("Reading FIFO count...")); - uint8_t fifoCount = getFIFOCount(); - - DEBUG_PRINT(F("Current FIFO count=")); - DEBUG_PRINTLN(fifoCount); - uint8_t fifoBuffer[128]; - //getFIFOBytes(fifoBuffer, fifoCount); - - DEBUG_PRINTLN(F("Writing final memory update 3/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - - DEBUG_PRINTLN(F("Writing final memory update 4/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - - DEBUG_PRINTLN(F("Disabling all standby flags...")); - I2Cdev::writeByte(0x68, MPU6050_RA_PWR_MGMT_2, 0x00); - - DEBUG_PRINTLN(F("Setting accelerometer sensitivity to +/- 2g...")); - I2Cdev::writeByte(0x68, MPU6050_RA_ACCEL_CONFIG, 0x00); - - DEBUG_PRINTLN(F("Setting motion detection threshold to 2...")); - setMotionDetectionThreshold(2); - - DEBUG_PRINTLN(F("Setting zero-motion detection threshold to 156...")); - setZeroMotionDetectionThreshold(156); - - DEBUG_PRINTLN(F("Setting motion detection duration to 80...")); - setMotionDetectionDuration(80); - - DEBUG_PRINTLN(F("Setting zero-motion detection duration to 0...")); - setZeroMotionDetectionDuration(0); - - DEBUG_PRINTLN(F("Setting AK8975 to single measurement mode...")); - //mag -> setMode(1); - I2Cdev::writeByte(0x0E, 0x0A, 0x01); - - // setup AK8975 (0x0E) as Slave 0 in read mode - DEBUG_PRINTLN(F("Setting up AK8975 read slave 0...")); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV0_ADDR, 0x8E); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV0_REG, 0x01); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV0_CTRL, 0xDA); - - // setup AK8975 (0x0E) as Slave 2 in write mode - DEBUG_PRINTLN(F("Setting up AK8975 write slave 2...")); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV2_ADDR, 0x0E); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV2_REG, 0x0A); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV2_CTRL, 0x81); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV2_DO, 0x01); - - // setup I2C timing/delay control - DEBUG_PRINTLN(F("Setting up slave access delay...")); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV4_CTRL, 0x18); - I2Cdev::writeByte(0x68, MPU6050_RA_I2C_MST_DELAY_CTRL, 0x05); - - // enable interrupts - DEBUG_PRINTLN(F("Enabling default interrupt behavior/no bypass...")); - I2Cdev::writeByte(0x68, MPU6050_RA_INT_PIN_CFG, 0x00); - - // enable I2C master mode and reset DMP/FIFO - DEBUG_PRINTLN(F("Enabling I2C master mode...")); - I2Cdev::writeByte(0x68, MPU6050_RA_USER_CTRL, 0x20); - DEBUG_PRINTLN(F("Resetting FIFO...")); - I2Cdev::writeByte(0x68, MPU6050_RA_USER_CTRL, 0x24); - DEBUG_PRINTLN(F("Rewriting I2C master mode enabled because...I don't know")); - I2Cdev::writeByte(0x68, MPU6050_RA_USER_CTRL, 0x20); - DEBUG_PRINTLN(F("Enabling and resetting DMP/FIFO...")); - I2Cdev::writeByte(0x68, MPU6050_RA_USER_CTRL, 0xE8); - - DEBUG_PRINTLN(F("Writing final memory update 5/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 6/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 7/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 8/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 9/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 10/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 11/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - - DEBUG_PRINTLN(F("Reading final memory update 12/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - readMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - #ifdef DEBUG - DEBUG_PRINT(F("Read bytes: ")); - for (j = 0; j < 4; j++) { - DEBUG_PRINTF(dmpUpdate[3 + j], HEX); - DEBUG_PRINT(" "); - } - DEBUG_PRINTLN(""); - #endif - - DEBUG_PRINTLN(F("Writing final memory update 13/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 14/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 15/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 16/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - DEBUG_PRINTLN(F("Writing final memory update 17/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - - DEBUG_PRINTLN(F("Waiting for FIRO count >= 46...")); - while ((fifoCount = getFIFOCount()) < 46); - DEBUG_PRINTLN(F("Reading FIFO...")); - getFIFOBytes(fifoBuffer, min(fifoCount, 128)); // safeguard only 128 bytes - DEBUG_PRINTLN(F("Reading interrupt status...")); - getIntStatus(); - - DEBUG_PRINTLN(F("Writing final memory update 18/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - - DEBUG_PRINTLN(F("Waiting for FIRO count >= 48...")); - while ((fifoCount = getFIFOCount()) < 48); - DEBUG_PRINTLN(F("Reading FIFO...")); - getFIFOBytes(fifoBuffer, min(fifoCount, 128)); // safeguard only 128 bytes - DEBUG_PRINTLN(F("Reading interrupt status...")); - getIntStatus(); - DEBUG_PRINTLN(F("Waiting for FIRO count >= 48...")); - while ((fifoCount = getFIFOCount()) < 48); - DEBUG_PRINTLN(F("Reading FIFO...")); - getFIFOBytes(fifoBuffer, min(fifoCount, 128)); // safeguard only 128 bytes - DEBUG_PRINTLN(F("Reading interrupt status...")); - getIntStatus(); - - DEBUG_PRINTLN(F("Writing final memory update 19/19 (function unknown)...")); - for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); - writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); - - DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)...")); - setDMPEnabled(false); - - DEBUG_PRINTLN(F("Setting up internal 48-byte (default) DMP packet buffer...")); - dmpPacketSize = 48; - /*if ((dmpPacketBuffer = (uint8_t *)malloc(42)) == 0) { - return 3; // TODO: proper error code for no memory - }*/ - - DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time...")); - resetFIFO(); - getIntStatus(); - } else { - DEBUG_PRINTLN(F("ERROR! DMP configuration verification failed.")); - return 2; // configuration block loading failed - } - } else { - DEBUG_PRINTLN(F("ERROR! DMP code verification failed.")); - return 1; // main binary block loading failed - } - return 0; // success -} - -bool MPU6050::dmpPacketAvailable() { - return getFIFOCount() >= dmpGetFIFOPacketSize(); -} - -// uint8_t MPU6050::dmpSetFIFORate(uint8_t fifoRate); -// uint8_t MPU6050::dmpGetFIFORate(); -// uint8_t MPU6050::dmpGetSampleStepSizeMS(); -// uint8_t MPU6050::dmpGetSampleFrequency(); -// int32_t MPU6050::dmpDecodeTemperature(int8_t tempReg); - -//uint8_t MPU6050::dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); -//uint8_t MPU6050::dmpUnregisterFIFORateProcess(inv_obj_func func); -//uint8_t MPU6050::dmpRunFIFORateProcesses(); - -// uint8_t MPU6050::dmpSendQuaternion(uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendPacketNumber(uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); -// uint8_t MPU6050::dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); - -uint8_t MPU6050::dmpGetAccel(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[34] << 24) | ((uint32_t)packet[35] << 16) | ((uint32_t)packet[36] << 8) | packet[37]); - data[1] = (((uint32_t)packet[38] << 24) | ((uint32_t)packet[39] << 16) | ((uint32_t)packet[40] << 8) | packet[41]); - data[2] = (((uint32_t)packet[42] << 24) | ((uint32_t)packet[43] << 16) | ((uint32_t)packet[44] << 8) | packet[45]); - return 0; -} -uint8_t MPU6050::dmpGetAccel(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (packet[34] << 8) | packet[35]; - data[1] = (packet[38] << 8) | packet[39]; - data[2] = (packet[42] << 8) | packet[43]; - return 0; -} -uint8_t MPU6050::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - v -> x = (packet[34] << 8) | packet[35]; - v -> y = (packet[38] << 8) | packet[39]; - v -> z = (packet[42] << 8) | packet[43]; - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[0] << 24) | ((uint32_t)packet[1] << 16) | ((uint32_t)packet[2] << 8) | packet[3]); - data[1] = (((uint32_t)packet[4] << 24) | ((uint32_t)packet[5] << 16) | ((uint32_t)packet[6] << 8) | packet[7]); - data[2] = (((uint32_t)packet[8] << 24) | ((uint32_t)packet[9] << 16) | ((uint32_t)packet[10] << 8) | packet[11]); - data[3] = (((uint32_t)packet[12] << 24) | ((uint32_t)packet[13] << 16) | ((uint32_t)packet[14] << 8) | packet[15]); - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = ((packet[0] << 8) | packet[1]); - data[1] = ((packet[4] << 8) | packet[5]); - data[2] = ((packet[8] << 8) | packet[9]); - data[3] = ((packet[12] << 8) | packet[13]); - return 0; -} -uint8_t MPU6050::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - int16_t qI[4]; - uint8_t status = dmpGetQuaternion(qI, packet); - if (status == 0) { - q -> w = (float)qI[0] / 16384.0f; - q -> x = (float)qI[1] / 16384.0f; - q -> y = (float)qI[2] / 16384.0f; - q -> z = (float)qI[3] / 16384.0f; - return 0; - } - return status; // int16 return value, indicates error if this line is reached -} -// uint8_t MPU6050::dmpGet6AxisQuaternion(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetRelativeQuaternion(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetGyro(int32_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (((uint32_t)packet[16] << 24) | ((uint32_t)packet[17] << 16) | ((uint32_t)packet[18] << 8) | packet[19]); - data[1] = (((uint32_t)packet[20] << 24) | ((uint32_t)packet[21] << 16) | ((uint32_t)packet[22] << 8) | packet[23]); - data[2] = (((uint32_t)packet[24] << 24) | ((uint32_t)packet[25] << 16) | ((uint32_t)packet[26] << 8) | packet[27]); - return 0; -} -uint8_t MPU6050::dmpGetGyro(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (packet[16] << 8) | packet[17]; - data[1] = (packet[20] << 8) | packet[21]; - data[2] = (packet[24] << 8) | packet[25]; - return 0; -} -uint8_t MPU6050::dmpGetMag(int16_t *data, const uint8_t* packet) { - // TODO: accommodate different arrangements of sent data (ONLY default supported now) - if (packet == 0) packet = dmpPacketBuffer; - data[0] = (packet[28] << 8) | packet[29]; - data[1] = (packet[30] << 8) | packet[31]; - data[2] = (packet[32] << 8) | packet[33]; - return 0; -} -// uint8_t MPU6050::dmpSetLinearAccelFilterCoefficient(float coef); -// uint8_t MPU6050::dmpGetLinearAccel(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) { - // get rid of the gravity component (+1g = +4096 in standard DMP FIFO packet) - v -> x = vRaw -> x - gravity -> x*4096; - v -> y = vRaw -> y - gravity -> y*4096; - v -> z = vRaw -> z - gravity -> z*4096; - return 0; -} -// uint8_t MPU6050::dmpGetLinearAccelInWorld(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) { - // rotate measured 3D acceleration vector into original state - // frame of reference based on orientation quaternion - memcpy(v, vReal, sizeof(VectorInt16)); - v -> rotate(q); - return 0; -} -// uint8_t MPU6050::dmpGetGyroAndAccelSensor(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetGyroSensor(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetControlData(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetTemperature(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetGravity(long *data, const uint8_t* packet); -uint8_t MPU6050::dmpGetGravity(int16_t *data, const uint8_t* packet) { - /* +1g corresponds to +8192, sensitivity is 2g. */ - int16_t qI[4]; - uint8_t status = dmpGetQuaternion(qI, packet); - data[0] = ((int32_t)qI[1] * qI[3] - (int32_t)qI[0] * qI[2]) / 16384; - data[1] = ((int32_t)qI[0] * qI[1] + (int32_t)qI[2] * qI[3]) / 16384; - data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1] - - (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (2 * 16384); - return status; -} - -uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q) { - v -> x = 2 * (q -> x*q -> z - q -> w*q -> y); - v -> y = 2 * (q -> w*q -> x + q -> y*q -> z); - v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z; - return 0; -} -// uint8_t MPU6050::dmpGetUnquantizedAccel(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetQuantizedAccel(long *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetExternalSensorData(long *data, int size, const uint8_t* packet); -// uint8_t MPU6050::dmpGetEIS(long *data, const uint8_t* packet); - -uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) { - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // psi - data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y); // theta - data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi - return 0; -} - -#ifdef USE_OLD_DMPGETYAWPITCHROLL -uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { - // yaw: (about Z axis) - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); - // pitch: (nose up/down, about Y axis) - data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); - // roll: (tilt left/right, about X axis) - data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z)); - return 0; -} -#else -uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { - // yaw: (about Z axis) - data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); - // pitch: (nose up/down, about Y axis) - data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); - // roll: (tilt left/right, about X axis) - data[2] = atan2(gravity -> y , gravity -> z); - if(gravity->z<0) { - if(data[1]>0) { - data[1] = PI - data[1]; - } else { - data[1] = -PI - data[1]; - } - } - return 0; -} -#endif - -// uint8_t MPU6050::dmpGetAccelFloat(float *data, const uint8_t* packet); -// uint8_t MPU6050::dmpGetQuaternionFloat(float *data, const uint8_t* packet); - -uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) { - /*for (uint8_t k = 0; k < dmpPacketSize; k++) { - if (dmpData[k] < 0x10) Serial.print("0"); - Serial.print(dmpData[k], HEX); - Serial.print(" "); - } - Serial.print("\n");*/ - //Serial.println((uint16_t)dmpPacketBuffer); - return 0; -} -uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) { - uint8_t status; - uint8_t buf[dmpPacketSize]; - for (uint8_t i = 0; i < numPackets; i++) { - // read packet from FIFO - getFIFOBytes(buf, dmpPacketSize); - - // process packet - if ((status = dmpProcessFIFOPacket(buf)) > 0) return status; - - // increment external process count variable, if supplied - if (processed != 0) *processed++; - } - return 0; -} - -// uint8_t MPU6050::dmpSetFIFOProcessedCallback(void (*func) (void)); - -// uint8_t MPU6050::dmpInitFIFOParam(); -// uint8_t MPU6050::dmpCloseFIFO(); -// uint8_t MPU6050::dmpSetGyroDataSource(uint_fast8_t source); -// uint8_t MPU6050::dmpDecodeQuantizedAccel(); -// uint32_t MPU6050::dmpGetGyroSumOfSquare(); -// uint32_t MPU6050::dmpGetAccelSumOfSquare(); -// void MPU6050::dmpOverrideQuaternion(long *q); -uint16_t MPU6050::dmpGetFIFOPacketSize() { - return dmpPacketSize; -} - -#endif /* _MPU6050_9AXIS_MOTIONAPPS41_H_ */ diff --git a/mpu6050-master/src/helper_3dmath.h b/mpu6050-master/src/helper_3dmath.h deleted file mode 100644 index 9f431a2bdb87b9911f7f78b31465f0a9f7f8e7ff..0000000000000000000000000000000000000000 --- a/mpu6050-master/src/helper_3dmath.h +++ /dev/null @@ -1,216 +0,0 @@ -// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class, 3D math helper -// 6/5/2012 by Jeff Rowberg <jeff@rowberg.net> -// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib -// -// Changelog: -// 2012-06-05 - add 3D math helper file to DMP6 example sketch - -/* ============================================ -I2Cdev device library code is placed under the MIT license -Copyright (c) 2012 Jeff Rowberg - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -=============================================== -*/ - -#ifndef _HELPER_3DMATH_H_ -#define _HELPER_3DMATH_H_ - -class Quaternion { - public: - float w; - float x; - float y; - float z; - - Quaternion() { - w = 1.0f; - x = 0.0f; - y = 0.0f; - z = 0.0f; - } - - Quaternion(float nw, float nx, float ny, float nz) { - w = nw; - x = nx; - y = ny; - z = nz; - } - - Quaternion getProduct(Quaternion q) { - // Quaternion multiplication is defined by: - // (Q1 * Q2).w = (w1w2 - x1x2 - y1y2 - z1z2) - // (Q1 * Q2).x = (w1x2 + x1w2 + y1z2 - z1y2) - // (Q1 * Q2).y = (w1y2 - x1z2 + y1w2 + z1x2) - // (Q1 * Q2).z = (w1z2 + x1y2 - y1x2 + z1w2 - return Quaternion( - w*q.w - x*q.x - y*q.y - z*q.z, // new w - w*q.x + x*q.w + y*q.z - z*q.y, // new x - w*q.y - x*q.z + y*q.w + z*q.x, // new y - w*q.z + x*q.y - y*q.x + z*q.w); // new z - } - - Quaternion getConjugate() { - return Quaternion(w, -x, -y, -z); - } - - float getMagnitude() { - return sqrt(w*w + x*x + y*y + z*z); - } - - void normalize() { - const float im = 1.0f / getMagnitude(); - w *= im; - x *= im; - y *= im; - z *= im; - } - - Quaternion getNormalized() { - Quaternion r(w, x, y, z); - r.normalize(); - return r; - } -}; - -class VectorInt16 { - public: - int16_t x; - int16_t y; - int16_t z; - - VectorInt16() { - x = 0; - y = 0; - z = 0; - } - - VectorInt16(int16_t nx, int16_t ny, int16_t nz) { - x = nx; - y = ny; - z = nz; - } - - float getMagnitude() { - return sqrt(x*x + y*y + z*z); - } - - void normalize() { - const float im = 1.0f / getMagnitude(); - x *= im; - y *= im; - z *= im; - } - - VectorInt16 getNormalized() { - VectorInt16 r(x, y, z); - r.normalize(); - return r; - } - - void rotate(Quaternion *q) { - // http://www.cprogramming.com/tutorial/3d/quaternions.html - // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm - // http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation - // ^ or: http://webcache.googleusercontent.com/search?q=cache:xgJAp3bDNhQJ:content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation&hl=en&gl=us&strip=1 - - // P_out = q * P_in * conj(q) - // - P_out is the output vector - // - q is the orientation quaternion - // - P_in is the input vector (a*aReal) - // - conj(q) is the conjugate of the orientation quaternion (q=[w,x,y,z], q*=[w,-x,-y,-z]) - Quaternion p(0, x, y, z); - - // quaternion multiplication: q * p, stored back in p - p = q -> getProduct(p); - - // quaternion multiplication: p * conj(q), stored back in p - p = p.getProduct(q -> getConjugate()); - - // p quaternion is now [0, x', y', z'] - x = p.x; - y = p.y; - z = p.z; - } - - VectorInt16 getRotated(Quaternion *q) { - VectorInt16 r(x, y, z); - r.rotate(q); - return r; - } -}; - -class VectorFloat { - public: - float x; - float y; - float z; - - VectorFloat() { - x = 0; - y = 0; - z = 0; - } - - VectorFloat(float nx, float ny, float nz) { - x = nx; - y = ny; - z = nz; - } - - float getMagnitude() { - return sqrt(x*x + y*y + z*z); - } - - void normalize() { - const float m = 1.0f / getMagnitude(); - x *= m; - y *= m; - z *= m; - } - - VectorFloat getNormalized() { - VectorFloat r(x, y, z); - r.normalize(); - return r; - } - - void rotate(Quaternion *q) { - Quaternion p(0, x, y, z); - - // quaternion multiplication: q * p, stored back in p - p = q -> getProduct(p); - - // quaternion multiplication: p * conj(q), stored back in p - p = p.getProduct(q -> getConjugate()); - - // p quaternion is now [0, x', y', z'] - x = p.x; - y = p.y; - z = p.z; - } - - VectorFloat getRotated(Quaternion *q) { - VectorFloat r(x, y, z); - r.rotate(q); - return r; - } -}; - -#endif /* _HELPER_3DMATH_H_ */ \ No newline at end of file diff --git a/thk-led-strip-controller b/thk-led-strip-controller deleted file mode 160000 index 1ceca3a0b54399819f723c0fcf9292cce566cb81..0000000000000000000000000000000000000000 --- a/thk-led-strip-controller +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1ceca3a0b54399819f723c0fcf9292cce566cb81 diff --git a/thk-motor-driver b/thk-motor-driver deleted file mode 160000 index 2ed3164c181a829741307e828b0f004ebce1ba75..0000000000000000000000000000000000000000 --- a/thk-motor-driver +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2ed3164c181a829741307e828b0f004ebce1ba75 diff --git a/thk-motor-driver-v2.0/.gitkeep b/thk-motor-driver-v2.0/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/thk-motor-driver-v2.0/README.md b/thk-motor-driver-v2.0/README.md deleted file mode 100644 index 7f1916040e6b806c297710cbde64c11f035925f9..0000000000000000000000000000000000000000 --- a/thk-motor-driver-v2.0/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# **DC-Motor Driver** - -Eine Klasse zur Ansteuerung von Gleichstrommotoren für unterschiedliche Motortreiber. - -Getestet mit: - -- Arduino Mega Pro + TB6612FNG<br /> -<br /> - -## **Installation:** - -Um diese Klassen verwenden zu können, muss dieses Repository geklont und in das Library-Verzeichnis der Arduino-IDE kopiert werden.<br /> -<br /> - -## **Anwendung:** - -Zur Verwendung siehe zunächst das Beispiel `drive.ino`<br /> -<br /> - -**Erläuterung zur Klasse** - -Es wird für jeden Motortreiber nur ein Objekt benötigt, dem beim instanziieren alle benötigten Informationen übergeben wird.<br /> -<br /> - -**Einbinden der Libraries:** - -```arduino -#include <thk_motor_driver_tb6612fng.h> -``` - -**Instanziieren eines Motortreiber-Objektes:** - -```arduino -thk_MotorDriverTB6612FNG motorExample(MOTOR_COUNT, MOTOR_STBY, MOTOR_PWM_A, MOTOR_IN1, MOTOR_IN2, MOTOR_PWM_B, MOTOR_IN3, MOTOR_IN4) -``` - - Die Parameter des Motortreiber-Objektes: - -- `MOTOR_COUNT`: Anzahl der anzusteuernden Gleichstrommotoren -- `MOTOR_STBY`: Pin für die Steuerung des Motortreiber Chips. -- `MOTOR_PWM_A`: PWM Pin für die Steuerung der Motorgeschwindigkeit vom Gleichstrommotor A. -- `MOTOR_IN1`: Input Pin 1 vom Gleichstrommotor A. -- `MOTOR_IN2`: Input Pin 2 vom Gleichstrommotor A. -- `MOTOR_PWM_B`: PWM Pin für die Steuerung der Motorgeschwindigkeit vom Gleichstrommotor B. -- `MOTOR_IN3`: Input Pin 3 vom Gleichstrommotor B. -- `MOTOR_IN4`: Input Pin 4 vom Gleichstrommotor B. - -**Funktionen:** - -```arduino -motorExample.drive(velocity, direction); // Fahren mit definierter Geschwindigkeit (0-255) und mit Angabe der Richtung. 1 = Vorwärts, 0 = Rückwärts -motorExample.drive_forward(velocity); // Vorwärtsfahren mit definierter Geschwindigkeit (0-255) -motorExample.drive_backward(velocity); // Rückwärtsfahren mit definierter Geschwindigkeit (0-255) -motorExample.stop(); // Stoppen des Motors -``` diff --git a/thk-motor-driver-v2.0/examples/.gitkeep b/thk-motor-driver-v2.0/examples/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/thk-motor-driver-v2.0/examples/drive/drive.ino b/thk-motor-driver-v2.0/examples/drive/drive.ino deleted file mode 100644 index 538f8893d1fc7f7cec6b3d6bc93daff400214ae1..0000000000000000000000000000000000000000 --- a/thk-motor-driver-v2.0/examples/drive/drive.ino +++ /dev/null @@ -1,46 +0,0 @@ -#include <thk_motor_driver_tb6612fng.h> - -uint8_t velocity = 255; - -const int MOTOR_COUNT = 1; -const int MOTOR_STBY = 38; -const int MOTOR_PWM_A = 6; -const int MOTOR_IN1 = 40; -const int MOTOR_IN2 = 42; -const int MOTOR_PWM_B = 0; -const int MOTOR_IN3 = 0; -const int MOTOR_IN4 = 0; -thk_MotorDriverTB6612FNG motor(MOTOR_COUNT, MOTOR_STBY, MOTOR_PWM_A, MOTOR_IN1, MOTOR_IN2, MOTOR_PWM_B, MOTOR_IN3, MOTOR_IN4); - -void setup() -{ - Serial.begin(115200); - motor.init(); -} - -void loop() -{ - motor.drive_forward(velocity); - delay(2000); - - motor.stop(); - delay(1000); - - motor.drive_backward(velocity); - delay(2000); - - motor.stop(); - delay(1000); - - motor.drive(velocity, 1); - delay(2000); - - motor.stop(); - delay(1000); - - motor.drive(velocity, 0); - delay(2000); - - motor.stop(); - delay(1000); -} \ No newline at end of file diff --git a/thk-motor-driver-v2.0/keywords.txt b/thk-motor-driver-v2.0/keywords.txt deleted file mode 100644 index 8db0bdd2a7ee16d6447488cff2a6a5fdba40fc5b..0000000000000000000000000000000000000000 --- a/thk-motor-driver-v2.0/keywords.txt +++ /dev/null @@ -1,16 +0,0 @@ -####################################### -# Datatypes (KEYWORD1) -####################################### - -thk_MotorDriverTB6612FNG KEYWORD1 - - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -forward KEYWORD2 -backward KEYWORD2 -stop KEYWORD2 -drive KEYWORD2 -init KEYWORD2 \ No newline at end of file diff --git a/thk-motor-driver-v2.0/thk_motor_driver.cpp b/thk-motor-driver-v2.0/thk_motor_driver.cpp deleted file mode 100644 index d67a107d2f213346f2294ebfc2b58d47bbcf0708..0000000000000000000000000000000000000000 --- a/thk-motor-driver-v2.0/thk_motor_driver.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "thk_motor_driver.h" - -void thk_MotorDriver::drive_forward(uint8_t speed) { - this->drive(speed, true); -} - -void thk_MotorDriver::drive_backward(uint8_t speed) { - this->drive(speed, false); -} \ No newline at end of file diff --git a/thk-motor-driver-v2.0/thk_motor_driver.h b/thk-motor-driver-v2.0/thk_motor_driver.h deleted file mode 100644 index e7f97c0998943df470f38e371ff0b83a89f2a9ea..0000000000000000000000000000000000000000 --- a/thk-motor-driver-v2.0/thk_motor_driver.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* Interface: thk_Motortreiber -* -* Enthält alle notwendigen Standardfunktionen eines Motortreibers -* -* S.Landwein, April 2022 -* -*/ - - -#ifndef MOTORDRIVER_H -#define MOTORDRIVER_H - -#include <Arduino.h> - -class thk_MotorDriver { - public: - enum Driving_state { stoped, forward, backward}; - void drive_forward(uint8_t speed); - void drive_backward(uint8_t speed); - virtual void stop() = 0; - virtual void drive(uint8_t speed, bool is_forward) = 0; - - protected: - Driving_state driving_state = stoped; - uint8_t speed = 0; - bool is_setup_correct = false; -}; - -#endif \ No newline at end of file diff --git a/thk-motor-driver-v2.0/thk_motor_driver_tb6612fng.cpp b/thk-motor-driver-v2.0/thk_motor_driver_tb6612fng.cpp deleted file mode 100644 index 930461de8b6de33d16be8e84084233ab348c34b4..0000000000000000000000000000000000000000 --- a/thk-motor-driver-v2.0/thk_motor_driver_tb6612fng.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "thk_motor_driver_tb6612fng.h" - -thk_MotorDriverTB6612FNG::thk_MotorDriverTB6612FNG(uint8_t motor_count, uint8_t pin_stby, uint8_t pin_pwm_a, uint8_t pin_in_1, uint8_t pin_in_2, uint8_t pin_pwm_b, uint8_t pin_in_3, uint8_t pin_in_4) : motor_count(motor_count), pin_stby(pin_stby), pin_pwm_a(pin_pwm_a), pin_in_1(pin_in_1), pin_in_2(pin_in_2), pin_pwm_b(pin_pwm_b), pin_in_3(pin_in_3), pin_in_4(pin_in_4){} - -void thk_MotorDriverTB6612FNG::init() -{ - if(this->motor_count < 1 || this->motor_count > 2) - { - this->is_setup_correct = false; - Serial.println("Ungültige Anzahl an Motoren:"); - Serial.println(this->motor_count); - return; - } - - pinMode(this->pin_stby, OUTPUT); - pinMode(this->pin_pwm_a, OUTPUT); - pinMode(this->pin_in_1, OUTPUT); - pinMode(this->pin_in_2, OUTPUT); - digitalWrite(this->pin_in_1, LOW); - digitalWrite(this->pin_in_2, LOW); - - if (this->motor_count == 2) - { - if ((pin_in_3 == 0) || (pin_in_4 == 0) || (pin_pwm_b == 0)){ - this->is_setup_correct = false; - Serial.println("Ungültige Pinbelegung"); - return; - } - - pinMode(this->pin_pwm_b, OUTPUT); - pinMode(this->pin_in_3, OUTPUT); - pinMode(this->pin_in_4, OUTPUT); - digitalWrite(this->pin_in_3, LOW); - digitalWrite(this->pin_in_4, LOW); - } - - this->is_setup_correct = true; -} - -void thk_MotorDriverTB6612FNG::drive(byte speed, bool is_forward) { - if(this->is_setup_correct == false) - { - Serial.println("Motoren werden nicht angesteuert, da keine gültige Initialisierung durchgeführt worden ist!"); - return; - } - - if (is_forward && driving_state == backward) { - stop(); - delay(500); - driving_state = forward; - } - else if (!is_forward && driving_state == forward) - { - stop(); - delay(500); - driving_state = backward; - } - - digitalWrite(this->pin_stby, HIGH); - analogWrite(this->pin_pwm_a, speed); - - if (is_forward) { - digitalWrite(this->pin_in_1, LOW); - digitalWrite(this->pin_in_2, HIGH); - } - else - { - digitalWrite(this->pin_in_1, HIGH); - digitalWrite(this->pin_in_2, LOW); - } - - if (this->motor_count == 2) - { - analogWrite(this->pin_pwm_b, speed); - - if (is_forward) { - digitalWrite(this->pin_in_3, LOW); - digitalWrite(this->pin_in_4, HIGH); - } - else - { - digitalWrite(this->pin_in_3, HIGH); - digitalWrite(this->pin_in_4, LOW); - } - } -} - -void thk_MotorDriverTB6612FNG::stop() { - if(this->is_setup_correct == false) - { - Serial.println("Motoren werden nicht angesteuert, da keine gültige Initialisierung durchgeführt worden ist!"); - return; - } - - digitalWrite(this->pin_stby, HIGH); - digitalWrite(this->pin_in_1, HIGH); - digitalWrite(this->pin_in_2, HIGH); - - if(this->motor_count == 2) { - digitalWrite(this->pin_in_3, HIGH); - digitalWrite(this->pin_in_4, HIGH); - } - driving_state = stoped; -} \ No newline at end of file diff --git a/thk-motor-driver-v2.0/thk_motor_driver_tb6612fng.h b/thk-motor-driver-v2.0/thk_motor_driver_tb6612fng.h deleted file mode 100644 index 2c88d1e328203725f6fe353d2ee0c3d1360f104f..0000000000000000000000000000000000000000 --- a/thk-motor-driver-v2.0/thk_motor_driver_tb6612fng.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Klasse: thk_MotorDriverTB6612FNG - * - * Zur Ansteuerung von Gleichstrommotoren mit dem Motortreiber TB6612FNG - * - * S. Landwein, Januar 2022 - * - */ - -#ifndef MOTOR_DRIVER_TB6612FNG_H -#define MOTOR_DRIVER_TB6612FNG_H - -#include <Arduino.h> -#include "thk_motor_driver.h" - -class thk_MotorDriverTB6612FNG : public thk_MotorDriver -{ - public: - thk_MotorDriverTB6612FNG(uint8_t motor_count, uint8_t pin_stby, uint8_t pin_pwm_a, uint8_t pin_in_1, uint8_t pin_in_2, uint8_t pin_pwm_b, uint8_t pin_in_3, uint8_t pin_in_4); - void stop() override; - void drive(uint8_t speed, bool is_forward) override; - void init(); - - private: - uint8_t motor_count; - uint8_t pin_stby; - uint8_t pin_pwm_a; - uint8_t pin_in_1; - uint8_t pin_in_2; - uint8_t pin_pwm_b; - uint8_t pin_in_3; - uint8_t pin_in_4; -}; - -#endif \ No newline at end of file diff --git a/thk-pid-controller b/thk-pid-controller deleted file mode 160000 index 254a35486fa8d8b9195b885bb8e07f4cd6da2777..0000000000000000000000000000000000000000 --- a/thk-pid-controller +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 254a35486fa8d8b9195b885bb8e07f4cd6da2777 diff --git a/thk_imu b/thk_imu deleted file mode 160000 index 6310439b55f6bcf9c396a558e66128dd71081e55..0000000000000000000000000000000000000000 --- a/thk_imu +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6310439b55f6bcf9c396a558e66128dd71081e55 diff --git a/thk_imu-v2.0/.gitignore b/thk_imu-v2.0/.gitignore deleted file mode 100644 index 6a8bc10aebbefffec65195982b7cbf18c870b3ae..0000000000000000000000000000000000000000 --- a/thk_imu-v2.0/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.vscode -build \ No newline at end of file diff --git a/thk_imu-v2.0/README.md b/thk_imu-v2.0/README.md deleted file mode 100644 index af3166b7b3ba3b23b95494a3f3e8ea7a71e980de..0000000000000000000000000000000000000000 --- a/thk_imu-v2.0/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# **IMU** - -Eine Klasse für die leichte Initializierung und Ansteuerung des Beschleunigungssensors MPU6050. - -Getestet mit: - -- Arduino Mega Pro + IMU (GY-521) MPU6050<br /> -<br /> - -## **Voraussetzung** -- [MPU6050](https://github.com/electroniccats/mpu6050) von ElectronicCats<br /> -<br /> - -## **Installation:** - -Um diese Klassen verwenden zu können, muss dieses Repository geklont und in das Libraries-Verzeichnis der Arduino-IDE kopiert werden.<br /> -<br /> - -## **Anwendung:** - -Zur Verwendung siehe zunächst das Beispiel `read_values.ino`<br /> -<br /> - -**Einbinden der Bibliothek:** - -```arduino -#include <thk_imu.h> -``` - -**Instanziieren:** - -```arduino -const int INTERRUPT_PIN = 0; // Wenn kein Interrupt Pin angeschlossen ist, dann Interrupt Pin gleich 0 setzen. -thk_IMU imu(INTERRUPT_PIN); -``` - -**Funktionen:** - -Um die IMU zu initialisieren wird folgende Methode im setup ausgeführt: -```arduino -imu.init() -``` - -Um die sogenannten Yaw, Pitch und Roll Winkel seperat zu erhalten werden folgende Methoden ausgeführt (Je nach Einbau-Orientierung des Sensors, können Yaw, Pitch und Roll vertauscht sein): -```arduino -yaw = imu.get_z_rot(); -pitch = imu.get_y_rot(); -roll = imu.get_x_rot(); -``` - -Möchte man sich die Yaw, Pitch und Roll Winkel gemeinsam zurück geben lassen, wird folgende Methode benutzt: -```arduino -yaw, pitch, roll = imu.get_orientation() -``` - -Um die sogenannten Quarternionen zu erhalten werden folgende Methoden ausgeführt: -```arduino -quat_w = imu.get_quat_w(); -quat_x = imu.get_quat_x(); -quat_y = imu.get_quat_y(); -quat_z = imu.get_quat_z(); -``` - -Um die Ausrichtung der IMU zu aktualisieren führt man folgende Methode aus: -```arduino -imu.reset() -``` diff --git a/thk_imu-v2.0/examples/get_angle/get_angle.ino b/thk_imu-v2.0/examples/get_angle/get_angle.ino deleted file mode 100644 index 5aaa8b9153befccbd6c9ecc4c3a588dbe601bb06..0000000000000000000000000000000000000000 --- a/thk_imu-v2.0/examples/get_angle/get_angle.ino +++ /dev/null @@ -1,53 +0,0 @@ -//#define DEBUG_IMU -#include <thk_imu.h> - -long start; -float z_rot, x_rot, y_rot; -float quat_w, quat_x, quat_y, quat_z; - -const int INTERRUPT_PIN = 0; // Wenn kein Interrupt Pin angeschlossen ist, dann Interrupt Pin gleich 0 setzen. -thk_IMU imu(INTERRUPT_PIN); - -void setup(){ - Serial.begin(115200); - Wire.begin(); - imu.init(); - start = millis(); -} - -void loop(){ - // Auslesen der Yaw, Pitch und Roll Winkel einzeln - z_rot = imu.get_z_rot(); - x_rot = imu.get_x_rot(); - y_rot = imu.get_y_rot(); - // z_rot, x_rot, y_rot = imu.get_orientation(); // Alternative Methode zum auslesen der Yaw, Pitch und Roll Winkel gemeinsam - - Serial.print(z_rot); - Serial.print("\t"); - Serial.print(x_rot); - Serial.print("\t"); - Serial.print(y_rot); - Serial.print("\t"); - - // Auslesen der Quarternionen - quat_w = imu.get_quat_w(); - quat_x = imu.get_quat_x(); - quat_y = imu.get_quat_y(); - quat_z = imu.get_quat_z(); - Serial.print(quat_w); - Serial.print("\t"); - Serial.print(quat_x); - Serial.print("\t"); - Serial.print(quat_y); - Serial.print("\t"); - Serial.print(quat_z); - Serial.println("\t"); - - // Nach 10 Sekunden einen Reset der IMU durchführen - if ((millis()-start) > 10000){ - imu.reset(); - Serial.println("###############"); - Serial.println("Imu reset done!"); - start = millis(); - } -} \ No newline at end of file diff --git a/thk_imu-v2.0/keywords.txt b/thk_imu-v2.0/keywords.txt deleted file mode 100644 index 35fbe489e927aa928d04ddfea9bd406197817262..0000000000000000000000000000000000000000 --- a/thk_imu-v2.0/keywords.txt +++ /dev/null @@ -1,21 +0,0 @@ -####################################### -# Datatypes (KEYWORD1) -####################################### - -IMU KEYWORD1 - - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -init KEYWORD2 -reset KEYWORD2 -get_quat_w KEYWORD2 -get_quat_x KEYWORD2 -get_quat_y KEYWORD2 -get_quat_z KEYWORD2 -get_yaw KEYWORD2 -get_pitch KEYWORD2 -get_roll KEYWORD2 -get_orientation KEYWORD2 \ No newline at end of file diff --git a/thk_imu-v2.0/thk_imu.h b/thk_imu-v2.0/thk_imu.h deleted file mode 100644 index f714147aad13044740284b8a2180644f5eaaa490..0000000000000000000000000000000000000000 --- a/thk_imu-v2.0/thk_imu.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Klasse: IMU - * - * Eine Klasse für die leichte Initializierung und Ansteuerung des Beschleunigungssensors MPU6050. - * - * O.-T. Altan, Januar 2022 - * - */ - -#ifndef thk_IMU_H -#define thk_IMU_H - -/* -* Debugging Mode -*/ -#ifdef DEBUG_IMU -#define _println_imu_(x) Serial.println(x) -#define _print_imu_(x) Serial.print(x) -#else -#define _println_imu_(x) -#define _print_imu_(x) -#endif - -#include <Arduino.h> -#include "I2Cdev.h" -#include "MPU6050_6Axis_MotionApps20.h" -#include "Wire.h" - -/* *************************** * - * Interrupt Detection Routine * - * *************************** */ -volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high -void dmpDataReady() { - mpuInterrupt = true; -} - -class thk_IMU -{ - public: - thk_IMU(const int INTERRUPT_PIN) : INTERRUPT_PIN(INTERRUPT_PIN){} - - void init() - { - // initialize device - _println_imu_(F("Initializing I2C devices...")); - mpu.initialize(); - - if(INTERRUPT_PIN != 0){ - pinMode(INTERRUPT_PIN, INPUT); - } - - // verify connection - _println_imu_(F("Testing device connections...")); - _println_imu_(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); - - // load and configure the DMP - _println_imu_(F("Initializing DMP...")); - devStatus = mpu.dmpInitialize(); - - // supply your own gyro offsets here, scaled for min sensitivity - mpu.setXGyroOffset(88); - mpu.setYGyroOffset(-5); - mpu.setZGyroOffset(3); - mpu.setZAccelOffset(1528); - - // make sure it worked (returns 0 if so) - if (devStatus == 0) - { - // Calibration Time: generate offsets and calibrate our MPU6050 - mpu.CalibrateAccel(6); - mpu.CalibrateGyro(6); - mpu.PrintActiveOffsets(); - // turn on the DMP, now that it's ready - _println_imu_(F("Enabling DMP...")); - mpu.setDMPEnabled(true); - - if(INTERRUPT_PIN != 0){ - // enable Arduino interrupt detection - _print_imu_(F("Enabling interrupt detection (Arduino external interrupt ")); - _print_imu_(digitalPinToInterrupt(INTERRUPT_PIN)); - _println_imu_(F(")...")); - attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); - mpuIntStatus = mpu.getIntStatus(); - } - // set our DMP Ready flag so the main loop() function knows it's okay to use it - _println_imu_(F("DMP/IMU ready! Waiting for first interrupt...")); - dmpReady = true; - - // get expected DMP packet size for later comparison - packetSize = mpu.dmpGetFIFOPacketSize(); - } - else - { - // ERROR! - // 1 = initial memory load failed - // 2 = DMP configuration updates failed - // (if it's going to break, usually the code will be 1) - _print_imu_(F("DMP Initialization failed (code ")); - _print_imu_(devStatus); - _println_imu_(F(")")); - } - }; - - void reset() - { - mpu.initialize(); - - // load and configure the DMP - _println_imu_(F("Initializing DMP...")); - devStatus = mpu.dmpInitialize(); - - // make sure it worked (returns 0 if so) - if (devStatus == 0) - { - // Calibration Time: generate offsets and calibrate our MPU6050 - mpu.CalibrateAccel(6); - mpu.CalibrateGyro(6); - // turn on the DMP, now that it's ready - _println_imu_(F("Enabling DMP...")); - mpu.setDMPEnabled(true); - - // set our DMP Ready flag so the main loop() function knows it's okay to use it - _println_imu_(F("DMP/IMU ready! Waiting for first interrupt...")); - dmpReady = true; - - // get expected DMP packet size for later comparison - packetSize = mpu.dmpGetFIFOPacketSize(); - } - else - { - // ERROR! - // 1 = initial memory load failed - // 2 = DMP configuration updates failed - // (if it's going to break, usually the code will be 1) - _print_imu_(F("DMP Initialization failed (code ")); - _print_imu_(devStatus); - _println_imu_(F(")")); - } - }; - - void update_values() - { - if (!dmpReady) - return; - if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) - { // Get the Latest packet - mpu.dmpGetQuaternion(&quat, fifoBuffer); - mpu.dmpGetGravity(&gravity, &quat); - mpu.dmpGetYawPitchRoll(ypr, &quat, &gravity); - } - }; - - float get_quat_w() - { - update_values(); - return quat.w; - }; - - float get_quat_x() - { - update_values(); - return quat.x; - }; - - float get_quat_y() - { - update_values(); - return quat.y; - }; - - float get_quat_z() - { - update_values(); - return quat.z; - }; - - float get_z_rot() - { - update_values(); - return ypr[0] * 180 / M_PI; - }; - - float get_x_rot() - { - update_values(); - return ypr[1] * 180 / M_PI; - }; - - float get_y_rot() - { - update_values(); - return ypr[2] * 180 / M_PI; - }; - - float get_orientation() - { - update_values(); - return (ypr[0] * 180 / M_PI), (ypr[1] * 180 / M_PI), (ypr[2] * 180 / M_PI); - } - - private: - MPU6050 mpu; - const int INTERRUPT_PIN; - // MPU control/status vars - bool dmpReady = false; // set true if DMP init was successful - uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU - uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) - uint16_t packetSize; // expected DMP packet size (default is 42 bytes) - uint16_t fifoCount; // count of all bytes currently in FIFO - uint8_t fifoBuffer[64]; // FIFO storage buffer - - // orientation/motion vars - Quaternion quat; // [w, x, y, z] quaternion container - VectorInt16 aa; // [x, y, z] accel sensor measurements - VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements - VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements - VectorFloat gravity; // [x, y, z] gravity vector - float euler[3]; // [psi, theta, phi] Euler angle container - float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector -}; - -#endif diff --git a/thk_ir_receiver b/thk_ir_receiver deleted file mode 160000 index ac3d9baf29bcc05462b90aff4099b8ca4bc1ffbb..0000000000000000000000000000000000000000 --- a/thk_ir_receiver +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ac3d9baf29bcc05462b90aff4099b8ca4bc1ffbb diff --git a/thk_servo b/thk_servo deleted file mode 160000 index 2184a5b744571cc5ce2efbb2f48d180b576a0cea..0000000000000000000000000000000000000000 --- a/thk_servo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2184a5b744571cc5ce2efbb2f48d180b576a0cea