Edit:
Got it figured!
Short answer; the complete definition of the callback configuration structure is:
Code: Select all
typedef struct {
rmt_encode_simple_cb_t callback; /*!< Callback to call for encoding data into RMT items */
void *arg; /*!< Opaque user-supplied argument for callback */
size_t min_chunk_size; /*!< Minimum amount of free space, in RMT symbols, the
encoder needs in order to guarantee it always
returns non-zero. Defaults
to 64 if zero / not given. */
} rmt_simple_encoder_config_t;
So in the example, modify this structure to read:
Code: Select all
const rmt_simple_encoder_config_t simple_encoder_cfg = {
encoder_callback,
&brightness
//Note we don't set min_chunk_size here as the default of 64 is good enough.
};
And lo and behold it all works with
`uint8_t brightness = 0;`
and the callback_encoder modified to:
Code: Select all
.
.
.
uint8_t photons = *( uint8_t* )arg; // Cast arg to uint8_t* and dereference to get the brightness value
if ( data_pos < data_size ) {
// Encode a byte
// uint8_t currentByte = scale8( data_bytes[ data_pos ], brightness );
// uint8_t currentByte = data_bytes[ data_pos ];
// currentByte = scale8_video( currentByte, brightness );
uint8_t currentByte = scale8_video( data_bytes[ data_pos ], photons );
.
.
.
Yippe-ki-a!
===================
I've figured out a way to modify the data on the fly.
By declaring a global variable `brightness`, and changing the encoder_callback function, I can do (portion of the encoder callback function here):
Code: Select all
.
.
.
if ( data_pos < data_size ) {
// Encode a byte
uint8_t currentByte = scale8_video( data_bytes[ data_pos ], brightness );
size_t symbol_pos = 0;
for ( int bitmask = 0x80; bitmask != 0; bitmask >>= 1 ) {
symbols[ symbol_pos++ ] = ( currentByte & bitmask ) ? ws2812_one : ws2812_zero;
}
// We're done; we should have written 8 symbols.
return symbol_pos;
}
.
.
.
which works fine (`scale8_video()` modifies the byte without affecting the original data).
Now the callback function is declared as:
Code: Select all
static size_t encoder_callback( const void* data, size_t data_size,
size_t symbols_written, size_t symbols_free,
rmt_symbol_word_t* symbols, bool *done, void* arg )
and the last argument `void* arg` is an opaque pointer to arguments that can be used inside `encoder_callback()`.
However, I cannot figure out the syntax to make this happen -- that is pass the value of `brightness` into `encoder_callback() as an argument.
With `brightness`declared as a global as
`uint8_t brightness = 0;`
and declaring:
`void* arg = &brightness;`
and then modifying the above code snippet to:
Code: Select all
.
.
.
uint8_t photons = *( uint8_t* )arg; // Cast arg to uint8_t* and dereference to get the brightness value
if ( data_pos < data_size ) {
// Encode a byte
uint8_t currentByte = scale8_video( data_bytes[ data_pos ], photons );
size_t symbol_pos = 0;
for ( int bitmask = 0x80; bitmask != 0; bitmask >>= 1 ) {
symbols[ symbol_pos++ ] = ( currentByte & bitmask ) ? ws2812_one : ws2812_zero;
}
// We're done; we should have written 8 symbols.
return symbol_pos;
}
.
.
.
The machine crashes as soon as the call to send the buffer to the LED's is called.
Any help on figuring this out would be very greatly appreciated.