diff --git a/examples/all/lcd_test.cc b/examples/all/lcd_test.cc index 00fcadd..c32ddde 100644 --- a/examples/all/lcd_test.cc +++ b/examples/all/lcd_test.cc @@ -5,18 +5,58 @@ #include #include "../../libraries/lcd.hh" +#include "../snake/cherry_bitmap.h" #include "lowrisc_logo.h" +using namespace sonata::lcd; + +// Positions to draw messages on the screen +static constexpr Point TopMessagePos = {12, 8}; +static constexpr Point BottomMessagePos = {38, 114}; +static constexpr Size BottomMessageOffset = {77, 0}; + /// Thread entry point. void __cheri_compartment("lcd_test") lcd_test() { - using namespace sonata::lcd; + // Initialise the LCD + auto lcd = SonataLcd(); + auto screen = Rect::from_point_and_size(Point::ORIGIN, lcd.resolution()); - auto lcd = SonataLcd(); - auto screen = Rect::from_point_and_size(Point::ORIGIN, lcd.resolution()); + // Draw the lowRISC logo to the LCD auto logoRect = screen.centered_subrect({105, 80}); lcd.draw_image_rgb565(logoRect, lowriscLogo105x80); - lcd.draw_str({1, 1}, "Hello world!", Color::White, Color::Black); + + // Make a version of the cherry bitmap with a white background. + uint8_t cherryImage10x10WhiteBg[200]; + for (uint32_t i = 0; i < 200; i += 2) + { + if (cherryImage10x10[i] == 0x00 && cherryImage10x10[i + 1] == 0x00) + { + cherryImage10x10WhiteBg[i] = 0xFF; + cherryImage10x10WhiteBg[i + 1] = 0xFF; + } + else + { + cherryImage10x10WhiteBg[i] = cherryImage10x10[i]; + cherryImage10x10WhiteBg[i + 1] = cherryImage10x10[i + 1]; + } + } + const uint8_t *img = static_cast(cherryImage10x10WhiteBg); + + // Draw the messages & cherry image to the LCD + lcd.draw_str(TopMessagePos, + "Running on Sonata!", + Color::White, + Color::Black, + Font::LucidaConsole_10pt); + lcd.draw_str(BottomMessagePos, + "Protected by CHERI", + Color::White, + Color::Black, + Font::M3x6_16pt); + Point imgPos = {BottomMessagePos.x + BottomMessageOffset.width, + BottomMessagePos.y + BottomMessageOffset.height}; + lcd.draw_image_rgb565(Rect::from_point_and_size(imgPos, {10, 10}), img); while (true) { diff --git a/examples/all/rgbled_lerp.cc b/examples/all/rgbled_lerp.cc new file mode 100644 index 0000000..f782c5b --- /dev/null +++ b/examples/all/rgbled_lerp.cc @@ -0,0 +1,42 @@ +// Copyright lowRISC Contributors. +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include + +// The max brightness of the RGB LEDs +static constexpr uint8_t MaxBrightness = 25; +// The number of milliseconds per RGB LED update +static constexpr uint32_t MsecPerUpdate = 150; + +[[noreturn]] void __cheri_compartment("rgbled_lerp") lerp_rgbleds() +{ + // Initialise the LED RGB driver. + auto rgbled = MMIO_CAPABILITY(SonataRgbLedController, rgbled); + + bool increasing = true; + uint8_t lerpT = 0; + while (true) + { + // Update the RGB values by linearly interpolating + rgbled->rgb(SonataRgbLed::Led0, lerpT, MaxBrightness - lerpT, 0); + rgbled->rgb(SonataRgbLed::Led1, 0, MaxBrightness - lerpT, lerpT); + rgbled->update(); + + // Progress one timestep, increasing or decreasing the lerp variable. + thread_millisecond_wait(MsecPerUpdate); + if (increasing && lerpT == MaxBrightness) + { + increasing = false; + continue; + } + if (!increasing && lerpT == 0) + { + increasing = true; + continue; + } + lerpT = increasing ? ++lerpT : --lerpT; + } +} diff --git a/examples/all/xmake.lua b/examples/all/xmake.lua index ecb32d2..c7a97c4 100644 --- a/examples/all/xmake.lua +++ b/examples/all/xmake.lua @@ -16,6 +16,9 @@ compartment("i2c_example") add_deps("debug") add_files("i2c_example.cc") +compartment("rgbled_lerp") + add_files("rgbled_lerp.cc") + compartment("proximity_sensor_example") add_deps("debug") add_files("proximity_sensor_example.cc") diff --git a/examples/xmake.lua b/examples/xmake.lua index ac32343..66c5da6 100644 --- a/examples/xmake.lua +++ b/examples/xmake.lua @@ -137,3 +137,35 @@ firmware("proximity_test") }, {expand = false}) end) after_link(convert_to_uf2) + + +-- Demo that does proximity test as well as LCD screen, etc for demos. +firmware("leds_and_lcd") + add_deps("freestanding", "led_walk_raw", "lcd_test", "rgbled_lerp") + on_load(function(target) + target:values_set("board", "$(board)") + target:values_set("threads", { + { + compartment = "led_walk_raw", + priority = 2, + entry_point = "start_walking", + stack_size = 0x200, + trusted_stack_frames = 1 + }, + { + compartment = "lcd_test", + priority = 2, + entry_point = "lcd_test", + stack_size = 0x1000, + trusted_stack_frames = 1 + }, + { + compartment = "rgbled_lerp", + priority = 2, + entry_point = "lerp_rgbleds", + stack_size = 0x200, + trusted_stack_frames = 1 + } + }, {expand = false}) + end) + after_link(convert_to_uf2)