diff --git a/README.md b/README.md
index 92bd3367..83e7b5ca 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,12 @@ In other cases you can contact the developer via email:
Value, NUMBERS[j]->Nachkomma) + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
NUMBERS[j]->Value = NUMBERS[j]->PreValue;
diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp
index d5479c31..d8537b86 100644
--- a/code/components/jomjol_helper/Helper.cpp
+++ b/code/components/jomjol_helper/Helper.cpp
@@ -80,7 +80,7 @@ void memCopyGen(uint8_t* _source, uint8_t* _target, int _size)
FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec)
{
- printf("open config file %s in mode %s\n", nm, _mode);
+ printf("open file %s in mode %s\n", nm, _mode);
FILE *pfile = fopen(nm, _mode);
/*
diff --git a/code/main/Color.cpp b/code/main/Color.cpp
deleted file mode 100644
index b2beb9ac..00000000
--- a/code/main/Color.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#include "Color.h"
-#include
-#include
-#include
-
-namespace {
-
-// Int -> fixed point
-int up( int x ) { return x * 255; }
-
-} // namespace
-
-int iRgbSqrt( int num ) {
- // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29
- assert( "sqrt input should be non-negative" && num >= 0 );
- assert( "sqrt input should no exceed 16 bits" && num <= 0xFFFF );
- int res = 0;
- int bit = 1 << 16;
- while ( bit > num )
- bit >>= 2;
- while ( bit != 0 ) {
- if ( num >= res + bit ) {
- num -= res + bit;
- res = ( res >> 1 ) + bit;
- } else
- res >>= 1;
- bit >>= 2;
- }
- return res;
-}
-
-Rgb::Rgb( Hsv y ) {
- // https://stackoverflow.com/questions/24152553/hsv-to-rgb-and-back-without-floating-point-math-in-python
- // greyscale
- if( y.s == 0 ) {
- r = g = b = y.v;
- return;
- }
-
- const int region = y.h / 43;
- const int remainder = ( y.h - ( region * 43 ) ) * 6;
-
- const int p = ( y.v * ( 255 - y.s ) ) >> 8;
- const int q = ( y.v * ( 255 - ( ( y.s * remainder ) >> 8 ) ) ) >> 8;
- const int t = ( y.v * ( 255 - ( ( y.s * (255 -remainder ) ) >> 8 ) ) ) >> 8;
-
- switch( region ) {
- case 0: r = y.v; g = t; b = p; break;
- case 1: r = q; g = y.v; b = p; break;
- case 2: r = p; g = y.v; b = t; break;
- case 3: r = p; g = q; b = y.v; break;
- case 4: r = t; g = p; b = y.v; break;
- case 5: r = y.v; g = p; b = q; break;
- default: __builtin_trap();
- }
-
- a = y.a;
-}
-
-Rgb& Rgb::operator=( Hsv hsv ) {
- Rgb r{ hsv };
- swap( r );
- return *this;
-}
-
-Rgb Rgb::operator+( Rgb in ) const {
- auto copy = *this;
- copy += in;
- return copy;
-}
-
-Rgb& Rgb::operator+=( Rgb in ) {
- unsigned int red = r + in.r;
- r = ( red < 255 ) ? red : 255;
- unsigned int green = g + in.g;
- g = ( green < 255 ) ? green : 255;
- unsigned int blue = b + in.b;
- b = ( blue < 255 ) ? blue : 255;
- return *this;
-}
-
-Rgb& Rgb::blend( Rgb in ) {
- unsigned int inAlpha = in.a * ( 255 - a );
- unsigned int alpha = a + inAlpha;
- r = iRgbSqrt( ( ( r * r * a ) + ( in.r * in.r * inAlpha ) ) / alpha );
- g = iRgbSqrt( ( ( g * g * a ) + ( in.g * in.g * inAlpha ) ) / alpha );
- b = iRgbSqrt( ( ( b * b * a ) + ( in.b * in.b * inAlpha ) ) / alpha );
- a = alpha;
- return *this;
-}
-
-uint8_t IRAM_ATTR Rgb::getGrb( int idx ) {
- switch ( idx ) {
- case 0: return g;
- case 1: return r;
- case 2: return b;
- }
- __builtin_unreachable();
-}
-
-Hsv::Hsv( Rgb r ) {
- int min = std::min( r.r, std::min( r.g, r.b ) );
- int max = std::max( r.r, std::max( r.g, r.b ) );
- int chroma = max - min;
-
- v = max;
- if ( chroma == 0 ) {
- h = s = 0;
- return;
- }
-
- s = up( chroma ) / max;
- int hh;
- if ( max == r.r )
- hh = ( up( int( r.g ) - int( r.b ) ) ) / chroma / 6;
- else if ( max == r.g )
- hh = 255 / 3 + ( up( int( r.b ) - int( r.r ) ) ) / chroma / 6;
- else
- hh = 2 * 255 / 3 + ( up( int( r.r ) - int( r.g ) ) ) / chroma / 6;
-
- if ( hh < 0 )
- hh += 255;
- h = hh;
-
- a = r.a;
-}
-
-Hsv& Hsv::operator=( Rgb rgb ) {
- Hsv h{ rgb };
- swap( h );
- return *this;
-}
diff --git a/code/main/Color.h b/code/main/Color.h
deleted file mode 100644
index 1923cf0b..00000000
--- a/code/main/Color.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#pragma once
-
-#include
-#include "esp_attr.h"
-union Hsv;
-
-union Rgb {
- struct __attribute__ ((packed)) {
- uint8_t r, g, b, a;
- };
- uint32_t value;
-
- Rgb( uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, uint8_t a = 255 ) : r( r ), g( g ), b( b ), a( a ) {}
- Rgb( Hsv c );
- Rgb& operator=( Rgb rgb ) { swap( rgb ); return *this; }
- Rgb& operator=( Hsv hsv );
- Rgb operator+( Rgb in ) const;
- Rgb& operator+=( Rgb in );
- bool operator==( Rgb in ) const { return in.value == value; }
- Rgb& blend( Rgb in );
- void swap( Rgb& o ) { value = o.value; }
- void linearize() {
- r = channelGamma(r);
- g = channelGamma(g);
- b = channelGamma(b);
- }
-
- uint8_t IRAM_ATTR getGrb( int idx );
-
- void stretchChannels( uint8_t maxR, uint8_t maxG, uint8_t maxB ) {
- r = stretch( r, maxR );
- g = stretch( g, maxG );
- b = stretch( b, maxB );
- }
-
- void stretchChannelsEvenly( uint8_t max ) {
- stretchChannels( max, max, max );
- }
-
-private:
- uint8_t stretch( int value, uint8_t max ) {
- return ( value * max ) >> 8;
- }
-
- uint8_t channelGamma( int channel ) {
- /* The optimal gamma correction is x^2.8. However, this is expensive to
- * compute. Therefore, we use x^3 for gamma correction. Also, we add a
- * bias as the WS2812 LEDs do not turn on for values less than 4. */
- if (channel == 0)
- return channel;
- channel = channel * channel * channel * 251;
- channel >>= 24;
- return static_cast< uint8_t >( 4 + channel );
- }
-};
-
-union Hsv {
- struct __attribute__ ((packed)) {
- uint8_t h, s, v, a;
- };
- uint32_t value;
-
- Hsv( uint8_t h, uint8_t s = 0, uint8_t v = 0, uint8_t a = 255 ) : h( h ), s( s ), v( v ), a( a ) {}
- Hsv( Rgb r );
- Hsv& operator=( Hsv h ) { swap( h ); return *this; }
- Hsv& operator=( Rgb rgb );
- bool operator==( Hsv in ) const { return in.value == value; }
- void swap( Hsv& o ) { value = o.value; }
-};
diff --git a/code/main/SmartLeds.cpp b/code/main/SmartLeds.cpp
deleted file mode 100644
index a2ba7b29..00000000
--- a/code/main/SmartLeds.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "SmartLeds.h"
-
-IsrCore SmartLed::_interruptCore = CoreCurrent;
-intr_handle_t SmartLed::_interruptHandle = NULL;
-
-SmartLed*& IRAM_ATTR SmartLed::ledForChannel( int channel ) {
- static SmartLed* table[8] = { nullptr };
- assert( channel < 8 );
- return table[ channel ];
-}
-
-void IRAM_ATTR SmartLed::interruptHandler(void*) {
- for (int channel = 0; channel != 8; channel++) {
- auto self = ledForChannel( channel );
-
- if ( RMT.int_st.val & (1 << (24 + channel ) ) ) { // tx_thr_event
- if ( self )
- self->copyRmtHalfBlock();
- RMT.int_clr.val |= 1 << ( 24 + channel );
- } else if ( RMT.int_st.val & ( 1 << (3 * channel ) ) ) { // tx_end
- if ( self )
- xSemaphoreGiveFromISR( self->_finishedFlag, nullptr );
- RMT.int_clr.val |= 1 << ( 3 * channel );
- }
- }
-}
-
-void IRAM_ATTR SmartLed::copyRmtHalfBlock() {
- int offset = detail::MAX_PULSES * _halfIdx;
- _halfIdx = !_halfIdx;
- int len = 3 - _componentPosition + 3 * ( _count - 1 );
- len = std::min( len, detail::MAX_PULSES / 8 );
-
- if ( !len ) {
- for ( int i = 0; i < detail::MAX_PULSES; i++) {
- RMTMEM.chan[ _channel].data32[i + offset ].val = 0;
- }
- }
-
- int i;
- for ( i = 0; i != len && _pixelPosition != _count; i++ ) {
- uint8_t val = _buffer[ _pixelPosition ].getGrb( _componentPosition );
- for ( int j = 0; j != 8; j++, val <<= 1 ) {
- int bit = val >> 7;
- int idx = i * 8 + offset + j;
- RMTMEM.chan[ _channel ].data32[ idx ].val = _bitToRmt[ bit & 0x01 ].value;
- }
- if ( _pixelPosition == _count - 1 && _componentPosition == 2 ) {
- RMTMEM.chan[ _channel ].data32[ i * 8 + offset + 7 ].duration1 =
- _timing.TRS / ( detail::RMT_DURATION_NS * detail::DIVIDER );
- }
-
- _componentPosition++;
- if ( _componentPosition == 3 ) {
- _componentPosition = 0;
- _pixelPosition++;
- }
- }
-
- for ( i *= 8; i != detail::MAX_PULSES; i++ ) {
- RMTMEM.chan[ _channel ].data32[ i + offset ].val = 0;
- }
-}
diff --git a/code/main/SmartLeds.h b/code/main/SmartLeds.h
deleted file mode 100644
index 824eb337..00000000
--- a/code/main/SmartLeds.h
+++ /dev/null
@@ -1,530 +0,0 @@
-#pragma once
-
-/*
- * A C++ driver for the WS2812 LEDs using the RMT peripheral on the ESP32.
- *
- * Jan "yaqwsx" Mrázek
- *
- * Based on the work by Martin F. Falatic - https://github.com/FozzTexx/ws2812-demo
- */
-
-/*
- * 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
-#include
-#include
-
-#if defined ( ARDUINO )
- extern "C" { // ...someone forgot to put in the includes...
- #include "esp32-hal.h"
- #include "esp_intr_alloc.h"
- #include "esp_ipc.h"
- #include "driver/gpio.h"
- #include "driver/periph_ctrl.h"
- #include "freertos/semphr.h"
- #include "soc/rmt_struct.h"
- #include
- #include "esp_idf_version.h"
-#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL( 4, 0, 0 )
- #include "soc/dport_reg.h"
-#endif
- }
-#elif defined ( ESP_PLATFORM )
- extern "C" { // ...someone forgot to put in the includes...
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- }
- #include
-#endif
-
-#include "Color.h"
-
-namespace detail {
-
-struct TimingParams {
- uint32_t T0H;
- uint32_t T1H;
- uint32_t T0L;
- uint32_t T1L;
- uint32_t TRS;
-};
-
-union RmtPulsePair {
- struct {
- int duration0:15;
- int level0:1;
- int duration1:15;
- int level1:1;
- };
- uint32_t value;
-};
-
-static const int DIVIDER = 4; // 8 still seems to work, but timings become marginal
-static const int MAX_PULSES = 32; // A channel has a 64 "pulse" buffer - we use half per pass
-static const double RMT_DURATION_NS = 12.5; // minimum time of a single RMT duration based on clock ns
-
-} // namespace detail
-
-using LedType = detail::TimingParams;
-
-static const LedType LED_WS2812 = { 350, 700, 800, 600, 50000 };
-static const LedType LED_WS2812B = { 400, 850, 850, 400, 50100 };
-static const LedType LED_SK6812 = { 300, 600, 900, 600, 80000 };
-static const LedType LED_WS2813 = { 350, 800, 350, 350, 300000 };
-
-enum BufferType { SingleBuffer = 0, DoubleBuffer };
-
-enum IsrCore { CoreFirst = 0, CoreSecond = 1, CoreCurrent = 2};
-
-class SmartLed {
-public:
- // The RMT interrupt must not run on the same core as WiFi interrupts, otherwise SmartLeds
- // can't fill the RMT buffer fast enough, resulting in rendering artifacts.
- // Usually, that means you have to set isrCore == CoreSecond.
- //
- // If you use anything other than CoreCurrent, the FreeRTOS scheduler MUST be already running,
- // so you can't use it if you define SmartLed as global variable.
- SmartLed( const LedType& type, int count, int pin, int channel = 0, BufferType doubleBuffer = SingleBuffer, IsrCore isrCore = CoreCurrent)
- : _timing( type ),
- _channel( channel ),
- _count( count ),
- _firstBuffer( new Rgb[ count ] ),
- _secondBuffer( doubleBuffer ? new Rgb[ count ] : nullptr ),
- _finishedFlag( xSemaphoreCreateBinary() )
- {
- assert( channel >= 0 && channel < 8 );
- assert( ledForChannel( channel ) == nullptr );
-
- xSemaphoreGive( _finishedFlag );
-
- DPORT_SET_PERI_REG_MASK( DPORT_PERIP_CLK_EN_REG, DPORT_RMT_CLK_EN );
- DPORT_CLEAR_PERI_REG_MASK( DPORT_PERIP_RST_EN_REG, DPORT_RMT_RST );
-
- PIN_FUNC_SELECT( GPIO_PIN_MUX_REG[ pin ], 2 );
- gpio_set_direction( static_cast< gpio_num_t >( pin ), GPIO_MODE_OUTPUT );
- gpio_matrix_out( static_cast< gpio_num_t >( pin ), RMT_SIG_OUT0_IDX + _channel, 0, 0 );
- initChannel( _channel );
-
- RMT.tx_lim_ch[ _channel ].limit = detail::MAX_PULSES;
- RMT.int_ena.val |= 1 << ( 24 + _channel );
- RMT.int_ena.val |= 1 << ( 3 * _channel );
-
- _bitToRmt[ 0 ].level0 = 1;
- _bitToRmt[ 0 ].level1 = 0;
- _bitToRmt[ 0 ].duration0 = _timing.T0H / ( detail::RMT_DURATION_NS * detail::DIVIDER );
- _bitToRmt[ 0 ].duration1 = _timing.T0L / ( detail::RMT_DURATION_NS * detail::DIVIDER );
-
- _bitToRmt[ 1 ].level0 = 1;
- _bitToRmt[ 1 ].level1 = 0;
- _bitToRmt[ 1 ].duration0 = _timing.T1H / ( detail::RMT_DURATION_NS * detail::DIVIDER );
- _bitToRmt[ 1 ].duration1 = _timing.T1L / ( detail::RMT_DURATION_NS * detail::DIVIDER );
-
- if ( !anyAlive() ) {
- _interruptCore = isrCore;
- if(isrCore != CoreCurrent) {
- ESP_ERROR_CHECK(esp_ipc_call_blocking(isrCore, registerInterrupt, NULL));
- } else {
- registerInterrupt(NULL);
- }
- }
-
- ledForChannel( channel ) = this;
- }
-
- ~SmartLed() {
- ledForChannel( _channel ) = nullptr;
- if ( !anyAlive() ) {
- if(_interruptCore != CoreCurrent) {
- ESP_ERROR_CHECK(esp_ipc_call_blocking(_interruptCore, unregisterInterrupt, NULL));
- } else {
- unregisterInterrupt(NULL);
- }
- }
- vSemaphoreDelete( _finishedFlag );
- }
-
- Rgb& operator[]( int idx ) {
- return _firstBuffer[ idx ];
- }
-
- const Rgb& operator[]( int idx ) const {
- return _firstBuffer[ idx ];
- }
-
- void show() {
- _buffer = _firstBuffer.get();
- startTransmission();
- swapBuffers();
- }
-
- bool wait( TickType_t timeout = portMAX_DELAY ) {
- if( xSemaphoreTake( _finishedFlag, timeout ) == pdTRUE ) {
- xSemaphoreGive( _finishedFlag );
- return true;
- }
- return false;
- }
-
- int size() const {
- return _count;
- }
-
- Rgb *begin() { return _firstBuffer.get(); }
- const Rgb *begin() const { return _firstBuffer.get(); }
- const Rgb *cbegin() const { return _firstBuffer.get(); }
-
- Rgb *end() { return _firstBuffer.get() + _count; }
- const Rgb *end() const { return _firstBuffer.get() + _count; }
- const Rgb *cend() const { return _firstBuffer.get() + _count; }
-
-private:
- static intr_handle_t _interruptHandle;
- static IsrCore _interruptCore;
-
- static void initChannel( int channel ) {
- RMT.apb_conf.fifo_mask = 1; //enable memory access, instead of FIFO mode.
- RMT.apb_conf.mem_tx_wrap_en = 1; //wrap around when hitting end of buffer
- RMT.conf_ch[ channel ].conf0.div_cnt = detail::DIVIDER;
- RMT.conf_ch[ channel ].conf0.mem_size = 1;
- RMT.conf_ch[ channel ].conf0.carrier_en = 0;
- RMT.conf_ch[ channel ].conf0.carrier_out_lv = 1;
- RMT.conf_ch[ channel ].conf0.mem_pd = 0;
-
- RMT.conf_ch[ channel ].conf1.rx_en = 0;
- RMT.conf_ch[ channel ].conf1.mem_owner = 0;
- RMT.conf_ch[ channel ].conf1.tx_conti_mode = 0; //loop back mode.
- RMT.conf_ch[ channel ].conf1.ref_always_on = 1; // use apb clock: 80M
- RMT.conf_ch[ channel ].conf1.idle_out_en = 1;
- RMT.conf_ch[ channel ].conf1.idle_out_lv = 0;
- }
-
- static void registerInterrupt(void *) {
- ESP_ERROR_CHECK(esp_intr_alloc( ETS_RMT_INTR_SOURCE, 0, interruptHandler, nullptr, &_interruptHandle));
- }
-
- static void unregisterInterrupt(void*) {
- esp_intr_free( _interruptHandle );
- }
-
- static SmartLed*& IRAM_ATTR ledForChannel( int channel );
- static void IRAM_ATTR interruptHandler( void* );
-
- void IRAM_ATTR copyRmtHalfBlock();
-
- void swapBuffers() {
- if ( _secondBuffer )
- _firstBuffer.swap( _secondBuffer );
- }
-
- void startTransmission() {
- // Invalid use of the library
- if( xSemaphoreTake( _finishedFlag, 0 ) != pdTRUE )
- abort();
-
- _pixelPosition = _componentPosition = _halfIdx = 0;
- copyRmtHalfBlock();
- if ( _pixelPosition < _count )
- copyRmtHalfBlock();
-
- RMT.conf_ch[ _channel ].conf1.mem_rd_rst = 1;
- RMT.conf_ch[ _channel ].conf1.tx_start = 1;
- }
-
- static bool anyAlive() {
- for ( int i = 0; i != 8; i++ )
- if ( ledForChannel( i ) != nullptr ) return true;
- return false;
- }
-
- const LedType& _timing;
- int _channel;
- detail::RmtPulsePair _bitToRmt[ 2 ];
- int _count;
- std::unique_ptr< Rgb[] > _firstBuffer;
- std::unique_ptr< Rgb[] > _secondBuffer;
- Rgb *_buffer;
-
- xSemaphoreHandle _finishedFlag;
-
- int _pixelPosition;
- int _componentPosition;
- int _halfIdx;
-};
-
-class Apa102 {
-public:
- struct ApaRgb {
- ApaRgb( uint8_t r = 0, uint8_t g = 0, uint32_t b = 0, uint32_t v = 0xFF )
- : v( 0xE0 | v ), b( b ), g( g ), r( r )
- {}
-
- ApaRgb& operator=( const Rgb& o ) {
- r = o.r;
- g = o.g;
- b = o.b;
- return *this;
- }
-
- ApaRgb& operator=( const Hsv& o ) {
- *this = Rgb{ o };
- return *this;
- }
-
- uint8_t v, b, g, r;
- };
-
- static const int FINAL_FRAME_SIZE = 4;
- static const int TRANS_COUNT = 2 + 8;
-
- Apa102( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer )
- : _count( count ),
- _firstBuffer( new ApaRgb[ count ] ),
- _secondBuffer( doubleBuffer ? new ApaRgb[ count ] : nullptr ),
- _initFrame( 0 )
- {
- spi_bus_config_t buscfg;
- memset( &buscfg, 0, sizeof( buscfg ) );
- buscfg.mosi_io_num = datapin;
- buscfg.miso_io_num = -1;
- buscfg.sclk_io_num = clkpin;
- buscfg.quadwp_io_num = -1;
- buscfg.quadhd_io_num = -1;
- buscfg.max_transfer_sz = 65535;
-
- spi_device_interface_config_t devcfg;
- memset( &devcfg, 0, sizeof( devcfg ) );
- devcfg.clock_speed_hz = 1000000;
- devcfg.mode = 0;
- devcfg.spics_io_num = -1;
- devcfg.queue_size = TRANS_COUNT;
- devcfg.pre_cb = nullptr;
-
- auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 );
- assert( ret == ESP_OK );
-
- ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi );
- assert( ret == ESP_OK );
-
- std::fill_n( _finalFrame, FINAL_FRAME_SIZE, 0xFFFFFFFF );
- }
-
- ~Apa102() {
- // ToDo
- }
-
- ApaRgb& operator[]( int idx ) {
- return _firstBuffer[ idx ];
- }
-
- const ApaRgb& operator[]( int idx ) const {
- return _firstBuffer[ idx ];
- }
-
- void show() {
- _buffer = _firstBuffer.get();
- startTransmission();
- swapBuffers();
- }
-
- void wait() {
- for ( int i = 0; i != _transCount; i++ ) {
- spi_transaction_t *t;
- spi_device_get_trans_result( _spi, &t, portMAX_DELAY );
- }
- }
-private:
- void swapBuffers() {
- if ( _secondBuffer )
- _firstBuffer.swap( _secondBuffer );
- }
-
- void startTransmission() {
- for ( int i = 0; i != TRANS_COUNT; i++ ) {
- _transactions[ i ].cmd = 0;
- _transactions[ i ].addr = 0;
- _transactions[ i ].flags = 0;
- _transactions[ i ].rxlength = 0;
- _transactions[ i ].rx_buffer = nullptr;
- }
- // Init frame
- _transactions[ 0 ].length = 32;
- _transactions[ 0 ].tx_buffer = &_initFrame;
- spi_device_queue_trans( _spi, _transactions + 0, portMAX_DELAY );
- // Data
- _transactions[ 1 ].length = 32 * _count;
- _transactions[ 1 ].tx_buffer = _buffer;
- spi_device_queue_trans( _spi, _transactions + 1, portMAX_DELAY );
- _transCount = 2;
- // End frame
- for ( int i = 0; i != 1 + _count / 32 / FINAL_FRAME_SIZE; i++ ) {
- _transactions[ 2 + i ].length = 32 * FINAL_FRAME_SIZE;
- _transactions[ 2 + i ].tx_buffer = _finalFrame;
- spi_device_queue_trans( _spi, _transactions + 2 + i, portMAX_DELAY );
- _transCount++;
- }
- }
-
- spi_device_handle_t _spi;
- int _count;
- std::unique_ptr< ApaRgb[] > _firstBuffer, _secondBuffer;
- ApaRgb *_buffer;
-
- spi_transaction_t _transactions[ TRANS_COUNT ];
- int _transCount;
-
- uint32_t _initFrame;
- uint32_t _finalFrame[ FINAL_FRAME_SIZE ];
-};
-
-class LDP8806 {
-public:
- struct LDP8806_GRB {
-
- LDP8806_GRB( uint8_t g_7bit = 0, uint8_t r_7bit = 0, uint32_t b_7bit = 0 )
- : g( g_7bit ), r( r_7bit ), b( b_7bit )
- {
- }
-
- LDP8806_GRB& operator=( const Rgb& o ) {
- //Convert 8->7bit colour
- r = ( o.r * 127 / 256 ) | 0x80;
- g = ( o.g * 127 / 256 ) | 0x80;
- b = ( o.b * 127 / 256 ) | 0x80;
- return *this;
- }
-
- LDP8806_GRB& operator=( const Hsv& o ) {
- *this = Rgb{ o };
- return *this;
- }
-
- uint8_t g, r, b;
- };
-
- static const int LED_FRAME_SIZE_BYTES = sizeof( LDP8806_GRB );
- static const int LATCH_FRAME_SIZE_BYTES = 3;
- static const int TRANS_COUNT_MAX = 20;//Arbitrary, supports up to 600 LED
-
- LDP8806( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer, uint32_t clock_speed_hz = 2000000 )
- : _count( count ),
- _firstBuffer( new LDP8806_GRB[ count ] ),
- _secondBuffer( doubleBuffer ? new LDP8806_GRB[ count ] : nullptr ),
- // one 'latch'/start-of-data mark frame for every 32 leds
- _latchFrames( ( count + 31 ) / 32 )
- {
- spi_bus_config_t buscfg;
- memset( &buscfg, 0, sizeof( buscfg ) );
- buscfg.mosi_io_num = datapin;
- buscfg.miso_io_num = -1;
- buscfg.sclk_io_num = clkpin;
- buscfg.quadwp_io_num = -1;
- buscfg.quadhd_io_num = -1;
- buscfg.max_transfer_sz = 65535;
-
- spi_device_interface_config_t devcfg;
- memset( &devcfg, 0, sizeof( devcfg ) );
- devcfg.clock_speed_hz = clock_speed_hz;
- devcfg.mode = 0;
- devcfg.spics_io_num = -1;
- devcfg.queue_size = TRANS_COUNT_MAX;
- devcfg.pre_cb = nullptr;
-
- auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 );
- assert( ret == ESP_OK );
-
- ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi );
- assert( ret == ESP_OK );
-
- std::fill_n( _latchBuffer, LATCH_FRAME_SIZE_BYTES, 0x0 );
- }
-
- ~LDP8806() {
- // noop
- }
-
- LDP8806_GRB& operator[]( int idx ) {
- return _firstBuffer[ idx ];
- }
-
- const LDP8806_GRB& operator[]( int idx ) const {
- return _firstBuffer[ idx ];
- }
-
- void show() {
- _buffer = _firstBuffer.get();
- startTransmission();
- swapBuffers();
- }
-
- void wait() {
- while ( _transCount-- ) {
- spi_transaction_t *t;
- spi_device_get_trans_result( _spi, &t, portMAX_DELAY );
- }
- }
-private:
- void swapBuffers() {
- if ( _secondBuffer )
- _firstBuffer.swap( _secondBuffer );
- }
-
- void startTransmission() {
- _transCount = 0;
- for ( int i = 0; i != TRANS_COUNT_MAX; i++ ) {
- _transactions[ i ].cmd = 0;
- _transactions[ i ].addr = 0;
- _transactions[ i ].flags = 0;
- _transactions[ i ].rxlength = 0;
- _transactions[ i ].rx_buffer = nullptr;
- }
- // LED Data
- _transactions[ 0 ].length = ( LED_FRAME_SIZE_BYTES * 8 ) * _count;
- _transactions[ 0 ].tx_buffer = _buffer;
- spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY );
- _transCount++;
-
- // 'latch'/start-of-data marker frames
- for ( int i = 0; i < _latchFrames; i++ ) {
- _transactions[ _transCount ].length = ( LATCH_FRAME_SIZE_BYTES * 8 );
- _transactions[ _transCount ].tx_buffer = _latchBuffer;
- spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY );
- _transCount++;
- }
- }
-
- spi_device_handle_t _spi;
- int _count;
- std::unique_ptr< LDP8806_GRB[] > _firstBuffer, _secondBuffer;
- LDP8806_GRB *_buffer;
-
- spi_transaction_t _transactions[ TRANS_COUNT_MAX ];
- int _transCount;
-
- int _latchFrames;
- uint8_t _latchBuffer[ LATCH_FRAME_SIZE_BYTES ];
-};
diff --git a/code/main/version.cpp b/code/main/version.cpp
index 85a37164..e0b9b140 100644
--- a/code/main/version.cpp
+++ b/code/main/version.cpp
@@ -1,4 +1,4 @@
-const char* GIT_REV="be90240";
+const char* GIT_REV="4fe9ab9";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
-const char* BUILD_TIME="2021-10-23 16:33";
\ No newline at end of file
+const char* BUILD_TIME="2021-11-14 08:39";
\ No newline at end of file
diff --git a/code/version.cpp b/code/version.cpp
index 85a37164..e0b9b140 100644
--- a/code/version.cpp
+++ b/code/version.cpp
@@ -1,4 +1,4 @@
-const char* GIT_REV="be90240";
+const char* GIT_REV="4fe9ab9";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
-const char* BUILD_TIME="2021-10-23 16:33";
\ No newline at end of file
+const char* BUILD_TIME="2021-11-14 08:39";
\ No newline at end of file
diff --git a/firmware/bootloader.bin b/firmware/bootloader.bin
index 02cb4166..f8f0fda7 100644
Binary files a/firmware/bootloader.bin and b/firmware/bootloader.bin differ
diff --git a/firmware/firmware.bin b/firmware/firmware.bin
index 1e30840b..9719ccb4 100644
Binary files a/firmware/firmware.bin and b/firmware/firmware.bin differ
diff --git a/firmware/html.zip b/firmware/html.zip
index 36896475..e4a81000 100644
Binary files a/firmware/html.zip and b/firmware/html.zip differ