OpenSourceSimWheelESP32
Open-source wireless steering wheel/button box for ESP32 boards
Loading...
Searching...
No Matches
OutputHardware.hpp
Go to the documentation of this file.
1
12#pragma once
13
14//---------------------------------------------------------------
15// Imports
16//---------------------------------------------------------------
17
18#include "SimWheelTypes.hpp"
19#include "driver/rmt_tx.h" // For rmt_channel_handle_t & rmt_encoder_handle_t
20#include <vector>
21#include <initializer_list>
22
23//---------------------------------------------------------------
24// Pixel vector
25//---------------------------------------------------------------
26
32{
33public:
35 using size_type = typename ::std::vector<Pixel>::size_type;
36
38 using vector_type = typename ::std::vector<Pixel>;
39
56 static void shift(
57 vector_type &data,
58 size_type from_index,
59 size_type to_index,
60 size_type shift = 1);
61
68 static void shift_left(vector_type &data, size_type count) noexcept;
69
76 static void shift_right(vector_type &data, size_type count) noexcept;
77
84 static void fill(vector_type &data, const Pixel &color) noexcept;
85
94 static void fill(
95 vector_type &data,
96 size_type fromIndex,
97 size_type toIndex,
98 const Pixel &color) noexcept;
99
100}; // PixelVectorHelper
101
102//---------------------------------------------------------------
103// Led strip encoder
104//---------------------------------------------------------------
105
111{
112public:
114 using pixel_vector_type = typename ::std::vector<Pixel>;
115
129 OutputGPIO dataPin,
130 uint8_t pixelCount,
131 bool useLevelShift,
133 bool reverse_display = false);
134
136 virtual ~LEDStrip();
137
144
151
153 LEDStrip(const LEDStrip &other) = delete;
154
156 LEDStrip &operator=(const LEDStrip &other) = delete;
157
163 uint8_t getPixelCount() { return pixelCount; }
164
176 void brightness(uint8_t value) { brightnessWeight = value + 1; }
177
185 {
186 pixel_vector_type result(pixelCount, color);
187 return result;
188 }
189
194 void clear()
195 {
196 show(pixelVector(0));
197 }
198
205
206private:
208 static constexpr uint32_t clockResolutionHz = 10000000;
210 static constexpr size_t symbols_per_byte = 8;
212 static constexpr size_t symbols_per_pixel =
213 sizeof(Pixel) * symbols_per_byte;
214
216 rmt_channel_handle_t rmtHandle = nullptr;
218 rmt_encoder_handle_t pixel_encoder_handle = nullptr;
220 rmt_bytes_encoder_config_t byte_enc_config{};
222 uint8_t pixelCount;
224 PixelFormat pixelFormat;
226 uint16_t brightnessWeight = 128;
228 uint32_t restTimeNs = 280000;
230 bool reversed = false;
231
244 static size_t pixels_rmt_encoder(
245 const void *data,
246 size_t data_size,
247 size_t symbols_written,
248 size_t symbols_free,
249 rmt_symbol_word_t *symbols,
250 bool *done,
251 void *arg);
252};
253
254//---------------------------------------------------------------
255// PCF8574 LED Driver
256//---------------------------------------------------------------
257
266{
267public:
276 I2CBus bus,
277 uint8_t address7bits);
278
288 void setLed(uint8_t index, bool state);
289
296 void shiftLeft();
297
305
311 void swap() { _state = ~_state; }
312
317 void show() const;
318
324 uint8_t getState() const { return _state; };
325
333 void setState(uint8_t state) { _state = state; }
334
336 {
337 setState(0);
338 show();
339 }
340
341private:
343 uint8_t _state = 0;
344
346 void *device = nullptr;
347};
348
349//---------------------------------------------------------------
350// Single LED
351//---------------------------------------------------------------
352
361{
362public:
369
375 void set(bool state) { _state = state; }
376
383 bool get() { return _state; }
384
390 void swap() { _state = !_state; }
391
396 void show();
397
398 ~SingleLED() { _pin.grant(); }
399
400private:
401 OutputGPIO _pin;
402 bool _state = false;
403};
404
405//------------------------------------------------------------------------------
406// Monochrome OLED
407//------------------------------------------------------------------------------
408
415{
417 bool flip_horizontal = false;
419 bool flip_vertical = false;
421 bool inverted_display = false;
423 uint8_t screen_width = 128;
425 uint8_t screen_height = 64;
427 uint8_t start_row = 0;
429 uint8_t start_col = 0;
431 uint8_t display_offset = 0;
433 uint8_t contrast = 127;
439 uint8_t COMpins = 0x12;
441 uint8_t oscillator_frequency = 0x80;
442
443public:
447 {
448 OLEDParameters result;
449 result.start_col = 2;
450 return result;
451 }
452
462 uint8_t width,
463 uint8_t height,
464 const OLEDParameters &params)
465 {
466 OLEDParameters result{params};
467 result.screen_width = width;
468 result.screen_height = height;
469 return result;
470 }
471};
472
480{
482 enum class Controller : uint8_t
483 {
485 SSD1306,
487 SH1107,
489 SH1106,
491 UNKNOWN
492 };
493
499 Controller guess_controller() const noexcept;
500
507 bool available() const noexcept { return (device); }
508
509protected:
511 constexpr OLEDBase() noexcept : device{nullptr} {}
512
524 ::std::initializer_list<uint8_t> &&try_addresses,
525 I2CBus bus) noexcept;
526
528 virtual ~OLEDBase() noexcept;
529
532 OLEDBase(const OLEDBase &other) noexcept = delete;
533
536 OLEDBase(OLEDBase &&other) noexcept;
537
540 OLEDBase &operator=(const OLEDBase &other) noexcept = delete;
541
544 OLEDBase &operator=(OLEDBase &&other) noexcept;
545
554 bool write(const uint8_t *buffer, ::std::size_t size) const noexcept;
555
563 bool write_cmd(uint8_t command) const noexcept;
564
573 bool write_cmd(uint8_t command, uint8_t arg) const noexcept;
574
584 bool write_cmd(uint8_t command, uint8_t arg1, uint8_t arg2) const noexcept;
585
595 const uint8_t *buffer,
596 ::std::size_t size) const noexcept;
597
605 bool read_status(uint8_t &status) const noexcept;
606
607private:
609 void *device = nullptr;
610};
611
616struct OLED : public OLEDBase
617{
618
620 constexpr OLED() : OLEDBase(), _params{}, width_b{0}, height_b{0}
621 {
622 _params.screen_width = 0;
623 _params.screen_height = 0;
624 }
625
633 const OLEDParameters &params,
634 I2CBus bus);
635
644 const OLEDParameters &params,
645 uint8_t address7bits,
646 I2CBus bus);
647
650 OLED(const OLED &other) noexcept = delete;
651
654 OLED(OLED &&other) noexcept = default;
655
658 OLED &operator=(const OLED &other) noexcept = delete;
659
662 OLED &operator=(OLED &&other) noexcept = default;
663
666 OLEDParameters parameters() const noexcept { return _params; }
667
669 ::std::size_t frame_size() const noexcept
670 {
671 return width_b * height_b * 8;
672 }
673
676 void contrast(uint8_t value);
677
680 void enable_display(bool yesOrNo);
681
684 void turn(bool onOrOff);
685
687 void inverse_display(bool yesOrNo);
688
691 void clear(bool inverted = false);
692
695 void show(const uint8_t *frame);
696
697protected:
701 uint8_t width_b;
703 uint8_t height_b;
704
706 void init();
707
715 void locate(uint8_t x, uint8_t page);
716
727 inline uint8_t row2col(
728 uint8_t bit_index,
729 const uint8_t *from,
730 uint8_t row_count);
731};
Types and constants required for custom firmware setup.
I2CBus
I2C bus controller.
PixelDriver
Pixel driver.
@ WS2812
WS2812 family.
PixelFormat
Byte order of pixel data starting with the least significant byte.
Low-level interface to LED strips.
pixel_vector_type pixelVector(const Pixel &color=0)
Create a vector of pixels suitable for this LED strip.
typename ::std::vector< Pixel > pixel_vector_type
Pixel vector type.
uint8_t getPixelCount()
Retrieve the pixel count in the strip.
void show(const pixel_vector_type &pixels)
Show pixels all at once.
void brightness(uint8_t value)
Set the global brightness.
LEDStrip(OutputGPIO dataPin, uint8_t pixelCount, bool useLevelShift, PixelDriver driver=PixelDriver::WS2812, bool reverse_display=false)
Create an LED strip.
LEDStrip(const LEDStrip &other)=delete
Copy constructor (deleted)
virtual ~LEDStrip()
Destructor.
void clear()
Turn off all LEDs immediately.
LEDStrip & operator=(const LEDStrip &other)=delete
Copy-assignment (deleted)
LEDStrip & operator=(LEDStrip &&other)
Move-assignment.
LEDStrip(LEDStrip &&other)
Move constructor.
8-LED driver based on the PCF8574 GPIO expander
void shiftLeft()
Shift all lights to the left.
uint8_t getState() const
Get the state of each LED.
PCF8574LedDriver(I2CBus bus, uint8_t address7bits)
Construct a LED driver.
void swap()
Invert the state of all LEDs.
void shiftRight()
Shift all lights to the right.
void setLed(uint8_t index, bool state)
Set the state of a single LED.
void setState(uint8_t state)
Set the state of each LED all at once.
void show() const
Show the required LEDs all at once.
A simple LED driver for a single LED.
void swap()
Invert the state of the LED.
SingleLED(OutputGPIO pin)
Create a new single-LED driver.
void set(bool state)
Set the state of the LED.
bool get()
Get the state of the LED.
void show()
Show the state of the LED.
Everything related to pixel control.
Definition SimWheel.hpp:735
void grant() const
Grant this GPIO for non-exclusive use.
Base class for all displays compatible with SSD1306 (I2C interface)
Controller
OLED controllers that can be automatically detected.
@ SSD1306
SSD1306 OLED controller.
@ UNKNOWN
Unknown OLED controller.
@ SH1107
SH1107 OLED controller.
@ SH1106
SH1106 OLED controller.
OLEDBase(::std::initializer_list< uint8_t > &&try_addresses, I2CBus bus) noexcept
Create an OLED base object.
Controller guess_controller() const noexcept
Guess the OLED controller.
bool available() const noexcept
Check if the OLED was found in the I2C bus.
bool write(const uint8_t *buffer, ::std::size_t size) const noexcept
Raw write.
bool write_gdd_ram(const uint8_t *buffer, ::std::size_t size) const noexcept
Write to GDD RAM.
bool read_status(uint8_t &status) const noexcept
Read the status register.
constexpr OLEDBase() noexcept
Create an uninitialized OLED base object.
virtual ~OLEDBase() noexcept
Destructor.
bool write_cmd(uint8_t command) const noexcept
Write a command with no arguments.
Monochrome OLED working parameters.
bool flip_horizontal
True to flip horizontally.
uint8_t oscillator_frequency
Display clock divide ratio/oscillator frequency.
static OLEDParameters for132x64()
Base parameters for 128x64 displays having a 132x64 controller.
uint8_t display_offset
Row offset where the physical display meets the logical display.
uint8_t screen_height
Screen height resolution in pixels.
bool inverted_display
True to swap black and white pixels.
uint8_t screen_width
Screen width resolution in pixels.
uint8_t start_col
Column pixel index where display starts.
bool flip_vertical
True to flip vertically.
uint8_t COMpins
COM pins value as required by the controller, bit[4] = COM pin configuration, bit[5] = COM left/right...
uint8_t contrast
Display contrast (higher value means higher contrast)
uint8_t start_row
Row pixel index where display starts.
static OLEDParameters withResolution(uint8_t width, uint8_t height, const OLEDParameters &params)
Force a specific graphics resolution.
Monochrome OLED.
void show(const uint8_t *frame)
Display a frame at once.
void contrast(uint8_t value)
Set the display contrast.
constexpr OLED()
Create an uninitialized OLED.
uint8_t height_b
Screen height in bytes.
void inverse_display(bool yesOrNo)
Switch pixel colors.
OLED(const OLEDParameters &params, I2CBus bus)
Create an OLED using any of the default I2C addresses.
OLEDParameters parameters() const noexcept
Get the OLED parameters passed in the constructor.
OLED(OLED &&other) noexcept=default
Move-constructor (default)
void turn(bool onOrOff)
Turn display on/off.
void clear(bool inverted=false)
Clear the display.
void init()
Initialize the display (called from the constructor)
OLEDParameters _params
OLED parameters given in the constructor.
uint8_t width_b
Screen width in bytes.
uint8_t row2col(uint8_t bit_index, const uint8_t *from, uint8_t row_count)
Utility function to translate a row-major vector graphic to the column-major format used by OLED scre...
OLED & operator=(const OLED &other) noexcept=delete
Copy-Assignment (deleted)
OLED(const OLED &other) noexcept=delete
Copy-constructor (deleted)
::std::size_t frame_size() const noexcept
Get the frame size in bytes.
OLED(const OLEDParameters &params, uint8_t address7bits, I2CBus bus)
Create an OLED using a specific I2C address.
void locate(uint8_t x, uint8_t page)
Set the start page and start column before display.
OLED & operator=(OLED &&other) noexcept=default
Move-Assignment (default)
void enable_display(bool yesOrNo)
Enable/Disable GDD RAM display.
Output-capable GPIO pin number.
Helper class to wrap around pixel vectors.
typename ::std::vector< Pixel > vector_type
Type of the backing variable.
static void shift_right(vector_type &data, size_type count) noexcept
Shift right (or up)
typename ::std::vector< Pixel >::size_type size_type
Size type of this vector.
static void fill(vector_type &data, const Pixel &color) noexcept
Fill the entire vector with a pixel color.
static void shift_left(vector_type &data, size_type count) noexcept
Shift left (or down)
static void fill(vector_type &data, size_type fromIndex, size_type toIndex, const Pixel &color) noexcept
Fill a segment with a pixel color.
static void shift(vector_type &data, size_type from_index, size_type to_index, size_type shift=1)
Shift the contents of a vector up (right) or down (left)
Pixel in 3-byte packed RGB format.