-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Just has an `set_pixels` function for writing to the entire LED matrix via I2C for now.
- Loading branch information
1 parent
0c73e34
commit 8f93656
Showing
3 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright lowRISC Contributors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "sense_hat.hh" | ||
#include <cheri.hh> | ||
#include <platform-i2c.hh> | ||
|
||
using namespace CHERI; | ||
|
||
/** | ||
* Helper. Returns a pointer to the I2C device. | ||
*/ | ||
[[nodiscard, gnu::always_inline]] static Capability<volatile OpenTitanI2c> i2c() | ||
{ | ||
return MMIO_CAPABILITY(OpenTitanI2c, i2c1); | ||
} | ||
|
||
void __cheri_libcall Internal::init_i2c() | ||
{ | ||
/* Increase the reliability of the Sense HAT I2C against controller halts | ||
in case the I2C Controller gets into a bad state while loading demos. */ | ||
i2c()->control = i2c()->control & ~(OpenTitanI2c::ControlEnableHost | | ||
OpenTitanI2c::ControlEnableTarget); | ||
if (i2c()->interrupt_is_asserted(OpenTitanI2cInterrupt::ControllerHalt)) | ||
{ | ||
i2c()->reset_controller_events(); | ||
} | ||
|
||
/* Initialise the I2C controller as normal. */ | ||
i2c()->reset_fifos(); | ||
i2c()->host_mode_set(); | ||
i2c()->speed_set(100); | ||
} | ||
|
||
bool __cheri_libcall SenseHat::set_pixels(Colour pixels8x8[64]) | ||
{ | ||
uint8_t writeBuffer[1 + 64 * 3] = {0x0u}; | ||
uint32_t i = 0u; | ||
writeBuffer[i++] = 0x00u; // Address | ||
for (uint8_t row = 0u; row < 8u; row++) | ||
{ | ||
for (uint8_t column = 0u; column < 8u; column++) | ||
{ | ||
uint32_t index = row * 8u + column; | ||
if (pixels8x8[index].red > Colour::MaxRedValue) | ||
{ | ||
Debug::log("{}:{} exceeds maximum red.", row, column); | ||
return false; | ||
} | ||
writeBuffer[i++] = pixels8x8[index].red; | ||
} | ||
for (uint8_t column = 0u; column < 8u; column++) | ||
{ | ||
uint32_t index = row * 8u + column; | ||
if (pixels8x8[index].green > Colour::MaxGreenValue) | ||
{ | ||
Debug::log("{}:{} exceeds maximum green.", row, column); | ||
return false; | ||
} | ||
writeBuffer[i++] = pixels8x8[index].green; | ||
} | ||
for (uint8_t column = 0u; column < 8u; column++) | ||
{ | ||
uint32_t index = row * 8u + column; | ||
if (pixels8x8[index].blue > Colour::MaxBlueValue) | ||
{ | ||
Debug::log("{}:{} exceeds maximum blue.", row, column); | ||
return false; | ||
} | ||
writeBuffer[i++] = pixels8x8[index].blue; | ||
} | ||
} | ||
return i2c()->blocking_write(0x46u, writeBuffer, sizeof(writeBuffer), true); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright lowRISC Contributors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
/* | ||
* A driver used for writing to the Raspberry Pi Sense HAT LED Matrix | ||
* via an I2C connection. | ||
* | ||
* Warning: Aborting the I2C transaction (e.g. resetting the FPGA, switching | ||
* software slot or bitstream) can cause the in-progress I2C transaction which | ||
* is writing the entire framebuffer to be interrupted. This can leave the I2C | ||
* controller on the Sense HAT in a bad state, with no easy mechanism for | ||
* resetting it via the OpenTitan I2C controller. You should be aware of this | ||
* if you plan to use and rely on this driver. If the I2C controller does get | ||
* into a bad state, you must unplug (for a few seconds) and replug the Sense | ||
* HAT, or power cycle the entire Sonata FPGA. Do not use this driver if you | ||
* plan to switch software slots / bitstreams regularly. | ||
*/ | ||
|
||
#include <algorithm> | ||
#include <debug.hh> | ||
#include <utility> | ||
|
||
namespace Internal | ||
{ | ||
void __cheri_libcall init_i2c(); | ||
} // namespace Internal | ||
|
||
class SenseHat | ||
{ | ||
private: | ||
/// Flag set when we're debugging this driver. | ||
static constexpr bool DebugSenseHat = true; | ||
|
||
/// Helper for conditional debug logs and assertions. | ||
using Debug = ConditionalDebug<DebugSenseHat, "Sense HAT">; | ||
|
||
public: | ||
struct Colour | ||
{ | ||
// Sense HAT LED Matrix uses RGB 565 | ||
static constexpr uint8_t RedBits = 5; | ||
static constexpr uint8_t GreenBits = 6; | ||
static constexpr uint8_t BlueBits = 5; | ||
|
||
// Maximum values for each field, calculated from the number of bits | ||
static constexpr uint8_t MaxRedValue = (1 << RedBits) - 1; | ||
static constexpr uint8_t MaxGreenValue = (1 << GreenBits) - 1; | ||
static constexpr uint8_t MaxBlueValue = (1 << BlueBits) - 1; | ||
|
||
// Colour fields | ||
uint8_t red; | ||
uint8_t green; | ||
uint8_t blue; | ||
} __attribute__((packed)); | ||
|
||
/** | ||
* A constructor for the Sense HAT driver. Initialises the I2C controller | ||
* that will communicate with the Sense HAT's I2C Controller to write to | ||
* its LED Matrix. | ||
*/ | ||
SenseHat() | ||
{ | ||
Internal::init_i2c(); | ||
} | ||
|
||
/** | ||
* Set the values of all pixels in the 8x8 LED Matrix on the Sense HAT | ||
* via an I2C connection. Will block until the entire array has been | ||
* written. Values are read from `pixels8x8` in row-major order (i.e. | ||
* all of row 1, then all of row 2, etc.) | ||
*/ | ||
bool __cheri_libcall set_pixels(Colour pixels8x8[64]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters