* add Sense() test
* fix IsInitialized() always returning false
* add tests for most exported Methods
* add negative test cases for Sense()
* add license to test
* fix CRC checksum of read timeout test
* fix read timeout test
* remove read timeout test
* remove opts from test case
- Removed useless ReadRaw
- Changed the scope of ReadAndCombine to private readAndCombine
- Renamed ExampleNewI2C & ExampleNewSpi to follow the recommandations. Exposed an I2CAddr for those who may need it.
It is a 7 colour ePaper/eInk HAT that comes with 5.7" (600 x 448 pixel) or 4" (640 x 400 pixel).
Refactors the existing 3 color Inky and adds additional fields to
auto-detect via EEPROM.
Tested with 5.7" version.
The current and shunt voltage register values are signed, twos
complement format. In my tests interpreting them directly in the
way implemented here gave output consistent with other ina219
libraries.
Co-authored-by: Eldon Stegall <periphgithub@eldondev.com>
Some SPI devices take a while to set up for transfer, and while doing
so, show the first bit they're about to send.
This causes the first LED to always interpret the first symbol as a
logical 1. Zapping out the whole strip will leave the first LED green,
and the first pixel will always be slightly green-ish.
Prevent this, by applying the same 3 bit padding we have at the end to
the front.
Signed-off-by: Florian Klink <flokli@flokli.de>
* waveshare2in13v2: Populate bounds only once
The forthcoming introduction of image orientation will make the
computation slightly more complicated. The bounds are fixed during the
lifetime of a "Dev" instance, so it's better to retain them.
* waveshare2in13v2: Make sending image part of drawOpts
* waveshare2in13v2: Unexport drawSpec members
The members of the "drawSpec" structure are only for internal use, so
rename them to start with a lower-case letter.
* waveshare2in13v2: Implement support for rotating image
A new option named "Origin" controls which of the four corners of the
display should be used as the (0,0) position for the image. The
in-memory buffer is kept in logical orientation. The actual rotation
happens only when sending updates.
By aligning the buffer accordingly the code is already prepared for
a more efficient sending of image data for the "TopRight" and
"BottomLeft" origins. See the TODO comment on "drawSpec.BufferDstOffset"
for details.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
Additional research provided information confirming that Waveshare
2.13in v2 displays are in fact GDEH0213B72, not GDEH0213B73, or at least
equivalent.
Resolve the remaining two TODOs by adding an upper limit on the frame
rate (defaults to 15 per second) and sending an image every once in
a while even when there were no changes (defaults to once a minute).
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
With the introduction of the shadow buffer in commit 4f99575 there's
always a sufficiently large memory buffer to keep the bytes to send for
clearing and the dedicated code using a smaller buffer is no longer
needed. This also has the advantage of automatically updating both
on-device buffers.
Enable the clock and analog parts when configuring the mode. In probably
all use cases a drawing operation is following soon after anyway.
Putting the device to sleep disables these hardware parts again.
The datasheets of the comparable SSD1680, SSD1675B and GDEH0213B73
controllers describe this command as "Write register for display
option".
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
Update both image buffers (B/W and red) and configure the controller to
only refresh the changed areas. With this change the "DrawPartial"
function becomes equivalent to "Draw" and is thus marked as deprecated.
It didn't really provide additional functionality before as partial
updates weren't truly implemented.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
It's perfectly acceptable to update a display in full mode before
switching to partial mode and vice-versa. There's no need for a full
soft-reset in-between.
This change breaks the API: the "Init" function no longer receives
a parameter. The default is to always start in the full update mode.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
Merge the common logic in the "initDisplayFull" and "initDisplayPartial"
functions and separate out the parts related to the display update mode.
In a forthcoming change the update mode will no longer be set when
initializing, but rather via a separate setter function, requiring the
ability to reconfigure the display controller without a full
re-initialization.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
This is necessary for partial updates of the display--not just
incremental updates of the full display, but updating part of the
display in general.
On the horizontal axis only whole bytes can be written, so updates need
to be aligned to 8 pixels. One option would be to require the caller of
Dev.Draw to only operate at multiples of 8. Another would be to read
back the contents of bytes to be updated partially and combine the data.
According to the datasheet the controller supports that (command 0x27).
The simplest option, however, is to maintain a shadow buffer in the
driver. Updates are applied to the buffer from which only the changed
destination rectangle is sent to the display. The permanent cost is
a bit more than 4kB of memory for a 122x250 display while saving on
memory allocations for a temporary image buffer on updates.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
The busy pin from the e-paper display is only used to read, not to
write, and thus there's no need for the PinIO interface. PinIn is
enough.
In addition the WaitForEdge function can be used to shorten the delays
when waiting for the display to become idle. Spurious or missed edges
are acceptable: the delay isn't very long.
This is an API-breaking change, albeit a simple one: Previously the
Dev.Clear function received a byte named "color". It was sent directly
to the display, thus acting more like a pattern to fill the display
with. In practice only 0 and 255 are likely to be used.
With this change the function is changed to receive a value of type
color.Color which is then converted to image1bit.Bit before filling the
display. The latter is also given a unittest.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
When the destination rectangle didn't start at (0,0) or cover the whole
display the Dev.Draw function would continue to update the display in
full. Obviously that didn't result in a good output.
This change updates the drawing logic to only update the affected area
(aligned to whole bytes on the horizontal axis) and limits the amount of
transferred data to the minimum needed to cover the destination
rectangle.
The calculation of the various offsets as well as the function sending
the image data are written to support unittesting.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
The structure definition and the functions were already split up. Moving
to a separate file simplifies the code structure.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>