diff --git a/examples-api-use/minimal-example.cc b/examples-api-use/minimal-example.cc index 81fbef5..2f0ace9 100644 --- a/examples-api-use/minimal-example.cc +++ b/examples-api-use/minimal-example.cc @@ -44,7 +44,12 @@ static void DrawOnCanvas(Canvas *canvas) { } int main(int argc, char *argv[]) { - Canvas *canvas = rgb_matrix::CreateMatrixFromFlags(&argc, &argv); + RGBMatrix::Options defaults; + defaults.rows = 32; + defaults.chain_length = 1; + defaults.parallel = 1; + defaults.show_refresh_rate = true; + Canvas *canvas = rgb_matrix::CreateMatrixFromFlags(&argc, &argv, &defaults); if (canvas == NULL) return 1; diff --git a/include/gpio.h b/include/gpio.h index 3679eb8..b0deb69 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -92,6 +92,7 @@ public: // "nano_wait_spec" contains a list of time periods we'd like // invoke later. This can be used to pre-process timings if needed. static PinPulser *Create(GPIO *io, uint32_t gpio_mask, + bool allow_hardware_pulsing, const std::vector &nano_wait_spec); virtual ~PinPulser() {} diff --git a/include/led-matrix.h b/include/led-matrix.h index 84d02a9..05b177d 100644 --- a/include/led-matrix.h +++ b/include/led-matrix.h @@ -57,21 +57,25 @@ public: // The "rows" are the number // of rows supported by the display, so 32 or 16. Default: 32. + // Flag: --led-rows int rows; // The chain_length is the number of displays daisy-chained together // (output of one connected to input of next). Default: 1 + // Flag: --led-chain int chain_length; // The number of parallel chains connected to the Pi; in old Pis with 26 // GPIO pins, that is 1, in newer Pis with 40 interfaces pins, that can // also be 2 or 3. The effective number of pixels in vertical direction is // then thus rows * parallel. Default: 1 + // Flag: --led-parallel int parallel; // Set PWM bits used for output. Default is 11, but if you only deal with // limited comic-colors, 1 might be sufficient. Lower require less CPU and // increases refresh-rate. + // Flag: --led-pwm-bits int pwm_bits; // This allows to change the base time-unit for the on-time in the lowest @@ -93,18 +97,26 @@ public: // ghosting in high-contrast applications (e.g. text), increase the value. // If you want to tweak, watch the framerate (--led-show-refresh) while // playing with this number and the PWM values. + // Flag: --led-pwm-lsb-nanoseconds int pwm_lsb_nanoseconds; + // Allow to use the hardware subsystem to create pulses. This won't do + // anything if output enable is not connected to GPIO 18. + // Flag: --led-hardware-pulse + bool allow_hardware_pulsing; + // The initial brightness of the panel in percent. Valid range is 1..100 // Default: 100 + // Flag: --led-brightness int brightness; // Scan mode: 0=progressive, 1=interlaced + // Flag: --led-scan-mode int scan_mode; - bool show_refresh_rate; - bool swap_green_blue; - bool inverse_colors; + bool show_refresh_rate; // Flag: --led-show-refresh + bool swap_green_blue; // Flag: --led-swap-green-blue + bool inverse_colors; // Flag: --led-inverse }; // Create an RGBMatrix. @@ -268,6 +280,14 @@ private: internal::Framebuffer *const frame_; }; +struct RuntimeOptions { + RuntimeOptions(); + + int gpio_slowdown; // 0 = no slowdown. Flag: --led-slowdown-gpio + int daemon; // -1 disabled. 0=off, 1=on. Flag: --led-daemon + int drop_privileges; // -1 disabled. 0=off, 1=on. flag: --led-drop-privs +}; + // Convenience utility to create a Matrix and extract relevant values from the // command line. Commandline flags are something like --led-rows, --led-chain, // --led-parallel. See output of PrintMatrixFlags() for all available options. @@ -281,6 +301,8 @@ private: // out-parameter, so its values are changed according to what the user // set on the command line. // +// Same for the last parameter for RuntimeOptions (see struct RuntimeOptions). +// // Example use: /* using rgb_matrix::RGBMatrix; @@ -305,14 +327,6 @@ int main(int argc, char **argv) { delete matrix; // Make sure to delete it in the end. } */ -struct RuntimeOptions { - RuntimeOptions(); - - int gpio_slowdown; // 0 = no slowdown. - int daemon; // -1 disabled. 0=off, 1=on. - int drop_privileges; // -1 disabled. 0=off, 1=on. -}; - RGBMatrix *CreateMatrixFromFlags( int *argc, char ***argv, RGBMatrix::Options *default_options = NULL, diff --git a/lib/framebuffer-internal.h b/lib/framebuffer-internal.h index 3a6f988..974f107 100644 --- a/lib/framebuffer-internal.h +++ b/lib/framebuffer-internal.h @@ -34,6 +34,7 @@ public: // Initialize GPIO bits for output. Only call once. static void InitGPIO(GPIO *io, int rows, int parallel, + bool allow_hardware_pulsing, int pwm_lsb_nanoseconds); // Set PWM bits used for output. Default is 11, but if you only deal with diff --git a/lib/framebuffer.cc b/lib/framebuffer.cc index 156b4d1..d264f98 100644 --- a/lib/framebuffer.cc +++ b/lib/framebuffer.cc @@ -74,6 +74,7 @@ Framebuffer::~Framebuffer() { } /* static */ void Framebuffer::InitGPIO(GPIO *io, int rows, int parallel, + bool allow_hardware_pulsing, int pwm_lsb_nanoseconds) { if (sOutputEnablePulser != NULL) return; // already initialized. @@ -133,6 +134,7 @@ Framebuffer::~Framebuffer() { bitplane_timings.push_back(pwm_lsb_nanoseconds << b); } sOutputEnablePulser = PinPulser::Create(io, output_enable_bits.raw, + allow_hardware_pulsing, bitplane_timings); } diff --git a/lib/gpio.cc b/lib/gpio.cc index e2368dc..e352d31 100644 --- a/lib/gpio.cc +++ b/lib/gpio.cc @@ -413,9 +413,10 @@ private: // Public PinPulser factory PinPulser *PinPulser::Create(GPIO *io, uint32_t gpio_mask, + bool allow_hardware_pulsing, const std::vector &nano_wait_spec) { if (!Timers::Init()) return NULL; - if (HardwarePinPulser::CanHandle(gpio_mask)) { + if (allow_hardware_pulsing && HardwarePinPulser::CanHandle(gpio_mask)) { return new HardwarePinPulser(gpio_mask, nano_wait_spec); } else { return new TimerBasedPinPulser(io, gpio_mask, nano_wait_spec); diff --git a/lib/led-matrix.cc b/lib/led-matrix.cc index 912d8de..78ba39c 100644 --- a/lib/led-matrix.cc +++ b/lib/led-matrix.cc @@ -129,6 +129,12 @@ RGBMatrix::Options::Options() pwm_lsb_nanoseconds(130), #endif +#ifdef DISABLE_HARDWARE_PULSES + allow_hardware_pulsing(false), +#else + allow_hardware_pulsing(true), +#endif + brightness(100), #ifdef RGB_SCAN_INTERLACED @@ -195,6 +201,7 @@ void RGBMatrix::SetGPIO(GPIO *io, bool start_thread) { if (io != NULL && io_ == NULL) { io_ = io; internal::Framebuffer::InitGPIO(io_, params_.rows, params_.parallel, + params_.allow_hardware_pulsing, params_.pwm_lsb_nanoseconds); } if (start_thread) { diff --git a/lib/options-initialize.cc b/lib/options-initialize.cc index 21a88b3..7060202 100644 --- a/lib/options-initialize.cc +++ b/lib/options-initialize.cc @@ -131,6 +131,8 @@ static bool FlagInit(int &argc, char **&argv, continue; if (ConsumeBoolFlag("swap-green-blue", it, &mopts->swap_green_blue)) continue; + if (ConsumeBoolFlag("hardware-pulse", it, &mopts->allow_hardware_pulsing)) + continue; // Runtime options. if (ConsumeIntFlag("slowdown-gpio", it, end, &ropts->gpio_slowdown, &err)) @@ -264,14 +266,17 @@ void PrintMatrixFlags(FILE *out, const RGBMatrix::Options &d, "\t--led-%sswap-green-blue : Switch if your matrix has green/blue " "swapped %s.\n" "\t--led-pwm-lsb-nanoseconds : PWM Nanoseconds for LSB " - "(Default: %d)\n", + "(Default: %d)\n" + "\t--led-%shardware-pulse : %sse hardware pin-pulse generation.\n", d.rows, d.chain_length, d.parallel, d.pwm_bits, d.brightness, d.scan_mode, d.show_refresh_rate ? "no-" : "", d.show_refresh_rate ? "Don't s" : "S", d.inverse_colors ? "no-" : "", d.inverse_colors ? "off" : "on", - d.swap_green_blue ? "no-" : "", d.swap_green_blue ? "off" : "on", - d.pwm_lsb_nanoseconds - ); + d.swap_green_blue ? "no-" : "", d.swap_green_blue ? "off" : "on", + d.pwm_lsb_nanoseconds, + d.allow_hardware_pulsing ? "no-" : "", + d.allow_hardware_pulsing ? "Don't u" : "U"); + fprintf(out, "\t--led-slowdown-gpio=<0..2>: " "Slowdown GPIO. Needed for faster Pis and/or slower panels " "(Default: %d).\n", r.gpio_slowdown);