* Fix semaphores in IDF & std::string assert
Fixes the problem of giving a mutex from a callback with the latest IDF. Also addresses an occasional assert that happens when the btc_task callback gives the semaphore and causes an assert due to both cores potentially writing m_owner concurrently.
* Restored m_owner position in wait() as requested
* Reapply assert fix and move setting m_owner in ::give()
Revert previous revert commit and move setting of m_owner in ::give to before giving the semaphore to prevent race condition possibility.
Implemented the ability to change the ESP32s BLE device address as
according the the BLE specification. This address is used when
advertising the ESP32 over BLE.
* Converted EEPROM library to use nvs instead of partition. Removed eeprom partition from all partition table CSV files.
* Changed variable names, added some comments, formatting as per me-no-dev's requests
* Checks for memory on malloc
* Moved include nvs.h from header to code
* Reworked the extra example to make it more clear how to actually use the library and persist data
* Replaced ARDUINO_VARIANT with const char
* Fixed missing return value
* Added quotes around defined value in macro (Issue #2193)
* Change logging from Error to Verbose when not found and default available
* Move Enter and Exit logging to Verbose Level
* Refactored LOG_X() into log_x()
* Properly allocate string and remove warning
The former way generates the following warning:
ISO C++ forbids converting a string constant to 'char*'
This change makes a character array the size of the string with null ending. It's clearer and gets rid of the warning.
* Better way
Since this is technically immutable, the type should reflect this too.
* add opportunity for more than one retry to _uploadReadByte
* an alternative timeout-based method to making _uploadReadByte more resilient
* move timing variables in the correct scope
* implement and use client.getTimeout instead of hard-coded timeout in _uploadReadByte
* add missing return
* some refactoring to address respecting the timeout in a potentially deadlocked connection
* fix spelling in comment
* address review comments; move impl to cpp file for getTimeout, and remove local variable for currentMillis
* remove redundant cast
* need to check for timeout outside the inner while as well
* update WebUpdate example to print something in unexpected callback condition
* update log_e messages per review comments
If _handler is set, pbuf_free is not called. ~AsyncUDPPacket() calls pbuf_free once but only after calling pbuf_ref in it's constructor. The refcount never reaches zero and the memory allocated for pbuf is never released.
* overload Preferences.getBytes similar to nvs so you can get size of the array.
* Cleaner implentation, with a separate function to get length. Added an example
Currently WiFiClient::write is unable to send messages over 25Kb, because of the hard-coded retry limit of 10, that is getting decremented on every successful send. Since we cannot send more than 2*MTU bytes in one go, and have only 10 retries, write() is limited to approximately 25Kb. Technically it is not a bug, as it correctly returns the number of sent bytes and the caller can set up futher retries. But not all libs are aware of this behavior, for example, WebServer is not.
I suggest improving current behavior by resetting retry counter every time we had a successful write, so the limit of 10 retries will apply to Failed writes only, and will not apply to Successful writes. This will allow to write() blobs of arbitrary sizes.
* Update boards.txt
Add menu items for ffat on mhetesp32minikit board.
* Add partition table.
* Added ffat partition for 4MB ESP32 Dev Module.
* Added comment about partitioning schemes.
* add missing EEPROM lib to CMakeLists.txt, moved the EEPROM files to proper directory
* add missing EEPROM lib to CMakeLists.txt, moved the EEPROM files to proper directory
* Webserver fix logging (#1)
* Change logging to use esp32-hal-log.h
fixes#2355
* adjust log parameter output positions, reduce lines
The DEBUG_ESP method used less lines than I originally set `log_v` to use when displaying the details of the received params ("@" and "=" indexes, and File info on a single line)
* I2C debugging and Log Dump Explaination
Create a help file for I2C debugging and interpretation of log dumps
* Update i2c_debugging.md
version
* add formatting, file locations
* Add APB change callbacks and move cpu code to own file
* Properly set esp_timer and FreeRTOS tick dividers
* Improve updated devisors
* No need to update REF_TICK yet
* Add initial handling for UART baud change
* fix uartWriteBuf and uartDetectBaudrate
* trigger callbacks even when APB did not change
* toggle UART ISR on CPU change
* add XTAL freq getter and add cpu freq validation
* Support CPU frequency changes in I2C (#2287)
**esp32-hal-i2c.c**
* add callback for cpu frequency changes
* adjust fifo thresholds based on cpu frequency and i2c bus frequency
* reduce i2c bus frequency if differential is too small
**Wire.h**
* version to 1.1.0
* Implement clock change for the other peripherals
* remove bad CPU clock values from the menu
* Add note to CPU freqs that support WiFi and BT
The default SPI bus is VSPI (see libraries/SPI/src/SPI.cpp). This change corrects a misleading comment in a code example which was stating wrongly that HSPI would be the default one.
* Shows only free internal heap on logs
Since Mbedtls is running only on internal heap, show internal + PSRAM available memory on logs can confuse the users
* Clarify logs
* Fix error in PR #2048: if ::available() is called before ::connect() _rxBuffer is not initialised
* Fixed flash size check and added SPIFFS size check
* Rewriting ESP.getFreeSketchSpace(), moving code from HTTPUpdate.cpp
* Don't Return I2C_ERROR_CONTINUE on ReSTART
ReSTART operations on the ESP32 have to be handled differently than on AVR chips, so ReSTART operations(`Wire.endTransmission(false), Wire.requestFrom(id,size,false);` are queued until a STOP is send (`Wire.endTransmission(TRUE), Wire.endTransmission(), Wire.requestFrom(id,size), Wire.requestFrom(id,size,TRUE)). To indicate the queuing I had used `I2C_ERROR_CONTINUE`, this caused compatibility issues with the existing Arduino I2C Code base. So, back to Lying to the public(for their own good of course) about success! This update just returns `I2C_ERROR_OK` on ReSTART commands.
* add comments
add comments
* Change Return error for ReSTART operation to I2C_ERROR_OK
This change restores compatibility with pre-existing Arduino Libraries. The ReSTART queuing operations are hidden behind the scenes. Wire.endTransmission(id,len,FALSE); will know return I2C_ERROR_OK instead of I2C_ERROR_CONTINUE, Wire.lastError() will return the true condition of I2C_ERROR_CONTINUE.
* #1623, implementing suggested change
Splitted suggested fix issue #1623 in a header and source part. Dit not completely dive into the code.
Giving data twice as parameter feels wrong, but it compiles, and i can succesfully use the W5500 with SPI with this fix.
Doesn't compile without.
* #1623, implementing suggested change SPI.h/cpp
Splitted suggested fix issue #1623 in a header and source part. Dit not completely dive into the code.
Giving data twice as parameter feels wrong, but it compiles, and i can succesfully use the W5500 with SPI with this fix.
Doesn't compile without.
* Clean warnings when all warning enabled
Not used variables / functions due to debug log
Dual define with different values :
cores\esp32/binary.h
#define B110 6
#define B1000000 64
tools/sdk/include/newlib/sys/termios.h
#define B110 3
#define B1000000 23
Local variable returned in WiFiclient Secure
* change due to deprecated function
* Update with proper variable and label
* Update esp32-hal-i2c.c
* Apply changes requested
* Fix warnings due to #define conflict thanks @atanisoft
This allow to catch the events when connected /disconnected,, etc...
This also allow to get parameters of events like the remote address of connected devices, etc...
Small change but lot of flexibility
* Added HTTPUpdate class for downloading sketches from a server
* Added HTTPUpdate class for downloading sketches from a server
* Added HTTPUpdate to CMakeLists.txt
* Change ESP8266 class references to ESP32 for httpUpdate.ino example
* Change ESP8266 class references to ESP32 for httpUpdate.ino example. setLedPin() commented out because not all boards support LED_BUITLIN
* Added check to handle mixup of old and present api properly
* Correct HTTPClient::setTimeout() to convert milliseconds to seconds. Correct WiFiClient::setTimeout() to call Stream::setTimeout() with seconds converted back to milliseconds. Remove inproper checks for _insecure.
* Added small comment because it looked like the Travis build did not finish
* Pass client parameter into two new begin() functions. Set other begin() functions deprecated. Updated library version to 1.2
* Added working HTTPS example on a public url with a certificate
* Remove two unnecessary tests in ::disconnect()
* Add a scoping block to BasicHttpsClient.ino to assure HTTPClient is destroyed before WiFiClientSecure
* Added check to handle mixup of old and present api properly
* Correct HTTPClient::setTimeout() to convert milliseconds to seconds. Correct WiFiClient::setTimeout() to call Stream::setTimeout() with seconds converted back to milliseconds. Remove inproper checks for _insecure.
* Added small comment because it looked like the Travis build did not finish
* removed uint8_t Wire.endTransmission(uint8_t sendStop)
Having both endTransmission(bool) and endTransmission(uint8_t) creates problems.
There is no need for endTransmission(uint8_t)
endTransmission(1) and endTransmission(0) works with endTransmission(bool).
Removing endTransmission(uint8_t) allows the ESP32 code to be compatible with
all the other Arduino cores by allowing endTransmission(1) and endTranmission(0)
to work as it does on all the other cores.
* Wire library version bump for endTransmission() update
* TX Flow Control and Code cleanup
* Use semaphore instead of delay
TX functionality is done.
* Use single buffer and empty queue on exit
* Fix compile issues because of LwIP code relocation
* Add temporary header to fix Azure not compiling
* Fix AsyncUDP early init
* AsyncUDP Multicast fixes
* Add source mac address and rework multicast
* Allow redefinition of default pins for Serials 1 and 2
* Update IDF to 3276a13
* Update esptool.py to 2.5.0
* Fix sketches
* Fix log level in BluetoothSetial
* rmt driver initial version
* supporting conti mode plus interrupts
* using conitnous mode for sending more data
* working continous mode
* rmt driver cleanup after conti mode
* initial version of rmt driver
* adding a simple example
* adding channel and block locks
* modified of rmt interface for simpler/easier usage
* adding header sentinels, split interface to common and additional settings
* Fixes per code review + support for rx callback mode
* renamed internal structures and enums, fixed formatting
* cmake support for rmt
* refactored tx-conti interrupts to function to make it more readable
* added Tx and Rx examples
* added license headers
* minor updates per review
* used struct access, renamed defines, corrected diagram
* First commit of FFat library
* Fixed reboot loops if no fat present. Added CMakeLists
* Functionalize the partition checks
* Cleanup, especially in format
* Dont format if mounted. More wording cleanup
* 16M ffat should only be on 16M board
* Fix some casting issues that trip up the compiler when building as ESP-IDF component
Few testers let me know, they were unable with connection to Eduroam network under PEAP+MsCHAPv2 methods.
They were trying many modifications. Solution is very absurd.
Change board to STA mode manually.
One tester from Italy was able to connect to Eduroam network under TTLS + MsCHAPv2 with that sketch too!
Sketch was tested and worked almost for all testers with that problem.
* ReSTART fix, Sequencing fix
pr #1665 introduce a problem with ReSTART, when solving this problem I found an interaction between the TxFifo refill, RxFifo empty and CMD[] fill. during certain sequences a dataqueue command would be skipped, this skipping resulted in a mismatch between the contents of the TxFifo and the i2c command sequence. The problem manifested as an ACK error.
In addition to this required bug fix I propose:
* `Wire.begin()` be changed from a `void` to a `bool` this will allow the reset functionality of `Wire.begin()` to be reported. Currently `Wire.begin()` attempts to reset the i2c Peripheral, but cannot report success/failure.
* `Wire.busy()` be added. this `bool` function returns the hardware status of the bus. This status can be use in multi-master environments for application level interleaving of commands, also in single master environment, it can be used to detect a 'hung' bus. With the functional change to `Wire.begin()` this allows app level recover of a hung bus.
* `Wire.lastError()` value updated for all errors, previously when interleaving `Wire.endTransmission(false)` and `Wire.readTransmission(false)`, the 128 byte `Wire.write()` buffer was exhausted without generating and error(very exotic). I discovered this error when I created a sequence of directed reads to a EEPROM. Each directed read used 2 bytes of the 128 byte `write()` buffer, so after 64 consecutive ReSTART writes with ReSTART reads, `Wire()` had no room to record the directed address bytes. It generated just a NAK check without setting the EEPROMs internal register address. The succeeding ReSTART read succeeded at incorrect address.
* Changes to the HAL layer:
** added `i2cGetStatus()` which returns the i2c peripheral status word, used to detect bus_busy currently
** added `i2cDebug()` programmatic control of debug buffer output
** changed `i2cAddQueue()` to allow data_only queue element this will allow a i2c transaction to use multiple data pointers.
** removed direct access to DumpInts(), DumpI2c() from app, use i2cDebug() to set trigger points
*
* Update esp32-hal-i2c.c
* Update Wire.cpp
* ReSTART, Sequencing
pr #1665 introduce a problem with ReSTART, when solving this problem I found an interaction between the TxFifo refill, RxFifo empty and CMD[] fill. during certain sequences a dataqueue command would be skipped, this skipping resulted in a mismatch between the contents of the TxFifo and the i2c command sequence. The problem manifested as an ACK error.
In addition to this required bug fix I propose:
* `Wire.begin()` be changed from a `void` to a `bool` this will allow the reset functionality of `Wire.begin()` to be reported. Currently `Wire.begin()` attempts to reset the i2c Peripheral, but cannot report success/failure.
* `Wire.busy()` be added. this `bool` function returns the hardware status of the bus. This status can be use in multi-master environments for application level interleaving of commands, also in single master environment, it can be used to detect a 'hung' bus. With the functional change to `Wire.begin()` this allows app level recover of a hung bus.
* `Wire.lastError()` value updated for all errors, previously when interleaving `Wire.endTransmission(false)` and `Wire.readTransmission(false)`, the 128 byte `Wire.write()` buffer was exhausted without generating and error(very exotic). I discovered this error when I created a sequence of directed reads to a EEPROM. Each directed read used 2 bytes of the 128 byte `write()` buffer, so after 64 consecutive ReSTART writes with ReSTART reads, `Wire()` had no room to record the directed address bytes. It generated just a NAK check without setting the EEPROMs internal register address. The succeeding ReSTART read succeeded at incorrect address.
* Changes to the HAL layer:
** added `i2cGetStatus()` which returns the i2c peripheral status word, used to detect bus_busy currently
** added `i2cDebug()` programmatic control of debug buffer output
** changed `i2cAddQueue()` to allow data_only queue element this will allow a i2c transaction to use multiple data pointers.
** removed direct access to DumpInts(), DumpI2c() from app, use i2cDebug() to set trigger points
*
* Forgot DebugFlags Return
@andriyadi found this, total brain fade on my part.
If you receive a package with a data length of zero, parsePacket returns 0, but rx_buffer will exist. So if another parsePacket with no read access returns to zeros, there is still data that can be read. This example would not work: https://www.arduino.cc/en/Reference/EthernetUDPParsePacket
Also I added a check if rx_buffer exit when you try to flush it.
EEPROM.h uses data types which are declared through Arduino.h but that file does not contain an #include directive for Arduino.h. This does not cause any problems when the EEPROM library is #included from a .ino file because the Arduino IDE automatically adds an #include directive for Arduino.h but this is not the case for .cpp files. If a .cpp file has an #include directive for EEPROM.h that does not follow an #include directive for Arduino.h then compilation fails:
E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:91:5: error: 'float_t' does not name a type
float_t readFloat(int address);
^
E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:92:5: error: 'double_t' does not name a type
double_t readDouble(int address);
^
E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:95:5: error: 'String' does not name a type
String readString(int address);
^
E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:110:36: error: 'float_t' has not been declared
size_t writeFloat(int address, float_t value);
^
E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:111:37: error: 'double_t' has not been declared
size_t writeDouble(int address, double_t value);
^
E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:114:37: error: 'String' has not been declared
size_t writeString(int address, String value);
* Allow using argument with attachInterrupt
* formatting
replace tabs with spaces
* fix bug more then 1 interrupt
* leftover
* add example
* make attachInterruptArg public
* update example
* leftover
* fix sdmmc config
* Fix warnings in EEPROM
from @Curclamas
* remove leftover TAG in EEPROM
* Initial add of @stickbreaker i2c
* Add log_n
* fix warnings when log is off
* i2c code clean up and reorganization
* add flags to interrupt allocator
* fix sdmmc config
* Fix warnings in EEPROM
from @Curclamas
* remove leftover TAG in EEPROM
* fix errors with latest IDF
* fix debug optimization (#1365)
incorrect optimization for debugging tick markers.
* Fix some missing BT header
* Change BTSerial log calls
* Update BLE lib
* Arduino-ESP32 release management scripted (#1515)
* Calculate an absolute path for a custom partitions table (#1452)
* * Arduino-ESP32 release management scripted
(ready-to-merge)
* * secure env for espressif/arduino-esp32
* * build tests enabled
* gitter webhook enabled
* * gitter room link fixed
* better comment
* * filepaths fixed
* BT Serial adjustments
* * don't run sketch builds & tests for tagged builds
* Return false from WiFi.hostByName() if hostname is not resolved
* Free BT Memory when BT is not used
* WIFI_MODE_NULL is not supported anymore
* Select some key examples to build with PlatformIO to save some time
* Update BLE lib
* Fixed BLE lib
* Major WiFi overhaul
- auto reconnect on connection loss now works
- moved to event groups
- some code clean up and procedure optimizations
- new methods to get a more elaborate system ststus
* Add cmake tests to travis
* Add initial AsyncUDP
* Add NetBIOS lib and fix CMake includes
* Add Initial WebServer
* Fix WebServer and examples
* travis not quiting on build fail
* Try different travis build
* Update IDF to aaf1239
* Fix WPS Example
* fix script permission and add some fail tests to sketch builder
* Add missing space in WiFiClient::write(Stream &stream)
* Add `SYSTEM_EVENT_WIFI_READY` call back once wifi service is init. allows you to hook in, as the sdk does not generate this event for you.
As it stands the SDK does not appear to set `WIFI_MODE_NULL` correctly. if the wifi is initialised and set to `WIFI_MODE_NULL` it actually defaults to AP mode. This fix keeps `WIFI_MODE_NULL` within the ESP class if the wifi has not been init yet, and works in my testing. albeit a one sided conversation.
https://github.com/espressif/arduino-esp32/issues/1306
* make changes compatible with new _persistent behaviour.
wifi_err_reason_t doesn't have reason code 12. After reason code 11, we are getting wrong wifi disconnected reason message. Added "UNSPECIFIED" in place of reason code 12.
And above 201 reason code, it should be r-176 instead of r-177. Because messages are started from zeroth offset.
The wifi stack initialisation must be complete before calling `_udp_ota.parsePacket()` otherwise you just get a screen filled with
```
```
and due to the more async methods in ESP32 `handle()` may be called before this can occur.
If you develop on windows and need cr/lf files, see this:
https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#_formatting_and_whitespace
Git can handle this by auto-converting CRLF line endings into LF
when you add a file to the index, and vice versa when it checks out
code onto your filesystem. You can turn on this functionality with
the core.autocrlf setting. If you're on a Windows machine, set it
to true - this converts LF endings into CRLF when you check out code:
$ git config --global core.autocrlf true
* Update BLE lib
* Update IDF to f586f5e
* Restructure Bluetooth Serial includes
* Update esptool and gen_esp32part
* Add partition scheme selection for menuconfig
* Add partition scheme selection for Arduino IDE
* Fix BLE example
* Second attempt BLE fix
* Add exceptions to PIO
This code allows Wire.begin() to assign the default values of SDA, and SCL only if they have not been previously configured. Arduino libraries that use Wire() usually re-init the I2C interface in their initialization code with a call to Wire.begin(). If a user app sets custom pins assignment in setup(); These assignments will be overwritten with the default values whenever Wire.begin() is called.
* Add BluetoothSerial library
A simple UART to Classical Bluetooth bridge for ESP32
* Create README.md
* Fix typos
* Replace deprecated header and small fixes
* Add coexistence with BLE
* Add missing semicolon
The ESP8266 version of the mDNS library expected service name and protocol without leading '_' (underscore). The ESP32 version expected service name and protocol with leading '_' (underscore).
This small change makes the ESP32 version compatible with the ESP8266 version and keeps backward compatible with existing code by accepting service name and protocol either with or without leading '_' (underscore).
* enchanced EEPROMClass
* Added eeprom examles and modified partition
* added eeprom class and extra examples
* No changes
* No changes
* added eeprom class and examples
* fixed typo
* length() returns user-defined sector size
* updated and annotated example
* Retrieve some code from what has been done on the ESP8266. Clarify a bit the signification of several bytes in the response.
* Add the type and class as members of the DNS class for an eventual future use.
* Clarify the sense of a magic number present in DNS server.
* A bit of aesthetics for the DNS server.
* Add a structure for the DNS question, use it DNS server to store the question data and to create the DNS answer from scratch.
* Added a lastError method to WiFiClientSecure so that a connection error from mbedTLS can be retrieved if connection fails (and then presented to a user).
* Changed to dos CRLF
* Made buffer size a const\nMore cleanup to match source
* Small grammar fixes and clarifications
Just fixed some small grammar issues in the comments and clarified a few things that might seem confusing.
* More spelling fixes that I introduced...
* Update mDNS and LEDC
* update toolchain
* Update IDF to 1c3dd23
* Advertise the board variant for Arduino OTA
* Add generic variant definition for mDNS
* Allow configuration of Ethernet PHY clock source
Refer to https://github.com/espressif/esp-idf/pull/1127
The internal APLL can be used to generate the 50MHz clock for the internal EMAC and the external Ethernet PHY.
The clock can either be input on GPIO0 (as before) or output on GPIO0, GPIO16 or GPIO17 (only GPIO17 extensively tested).
New example available.
* Allow configuration of Ethernet PHY clock source
Refer to https://github.com/espressif/esp-idf/pull/1127
The internal APLL can be used to generate the 50MHz clock for the internal EMAC and the external Ethernet PHY.
The clock can either be input on GPIO0 (as before) or output on GPIO0, GPIO16 or GPIO17 (only GPIO17 extensively tested).
New example available.
When user selected HSPI with SPIClass name(HSPI) ESP was, by default,
still using VSPI ports (the ones defined in pins_arduino.h).
With this change when user selects HSPI then HSPI default ports will be
used.
If user won't specify HSPI then VSPI default ports will be used.
If user will specify SCLK, MOSI, MISO and SS with SPI.begin() then user
defined ports will be used no matter if VSPI or HSPI is selected.
With this change fe. SD library can use default HSPI ports. It was
possible to
pass HSPI SPI instance to SD lib, however even then it was using VSPI
ports which were (probably) GPIO matrixed to HSPI.
* ArduinoOTA would stop receiving any packets if the port received a zero-length UDP packet, commonly sent by network scanners like nmap. Fixed to flush() after every call to parsePacket(), even if read length is 0.
Additionally, added length checking to fix a potential buffer overflow in parseInt().
Finally, added an end() method that stops the OTA listener and releases resources.
* Only end MDNS in end() if mdns mode is enabled.
* Create ledcWrite_demo_ESP32_RGB.ino
adding the public domain example ledcWrite_demo_ESP32.ino to this repo. Added RGB to the name for people searching, added some comments, and renames things to make a bit more sense.
* Update ledcWrite_demo_ESP32_RGB.ino
renamed to ledcWrite_RGB.ino and added a couple more comments based on https://github.com/espressif/arduino-esp32/issues/689
* Rename libraries/ESP32/examples/AnalogOut/ledcWrite_demo_ESP32_RGB/ledcWrite_demo_ESP32_RGB.ino to libraries/ESP32/examples/AnalogOut/ledcWrite_RGB/ledcWrite_RGB.ino
Renamed.
* Addition of a i2cReset method and timeout handling for the case where the i2c hardware FSM (state machine) gets stuck in a busy state.
* Use newly added i2cReset function within the wire library.
* Add example to update ESP32 via SD card
* Delete update.bin from sd upon finishing update
* remove precompiled binary from example
* Check whether update.bin is a file
* Change disconnect function
Current implementation does not disconnect the WiFi. Use of `esp_wifi_disconnect()` does.
* Update WiFiSTA.cpp
put back the clear ssid + password
remove the duplicate `esp_wifi_set_config(WIFI_IF_STA, &conf);`
send() can return a value > 0 but less than size indicating it was able to accept some of the data in buffer. The caller must try again after updating the buffer pointer and size remaining.
* Add files via upload
Calls to writePattern() don't send the desired number of bytes when the pattern size doesn't divide evenly into the hardware FIFO size (e.g. sending 18-bit RGB data, 11 patterns take 63 bytes, so 1/64th of the data is never sent).
* Add files via upload
Remove white space changes.