Added I2C and RGB LEDs to sonata board description
diff --git a/sdk/boards/sonata.json b/sdk/boards/sonata.json index 0930fcd..ad5cc7e 100644 --- a/sdk/boards/sonata.json +++ b/sdk/boards/sonata.json
@@ -16,6 +16,14 @@ "start" : 0x80100000, "end" : 0x80100034 }, + "i2c0": { + "start" : 0x80200000, + "end" : 0x80200080 + }, + "i2c1": { + "start" : 0x80201000, + "end" : 0x80201080 + }, "spi0": { "start" : 0x80300000, "end" : 0x80301000 @@ -28,6 +36,10 @@ "start" : 0x80302000, "end" : 0x80303000 }, + "rgbled" : { + "start" : 0x80009000, + "end" : 0x80009020 + }, "plic": { "start" : 0x88000000, "end" : 0x88400000
diff --git a/sdk/include/platform/sunburst/platform-rgbctrl.hh b/sdk/include/platform/sunburst/platform-rgbctrl.hh index df32044..1e5a153 100644 --- a/sdk/include/platform/sunburst/platform-rgbctrl.hh +++ b/sdk/include/platform/sunburst/platform-rgbctrl.hh
@@ -7,8 +7,8 @@ */ enum class SonataRgbLed { - Led0, - Led1, + Led0 = 0, + Led1 = 1, }; /** @@ -20,15 +20,20 @@ * Registers for setting the 8-bit red, green, and blue values * for the two RGB Leds. */ - uint32_t rgbLed0; - uint32_t rgbLed1; - /// Control Register + uint32_t ledColors[2]; + /** + * Control Register. See `SonataRgbLedController::ControlFields` for the + * fields. + */ uint32_t control; - /// Status Register + /** + * Status Register See `SonataRgbLedController::StatusFields` for the + * fields. + */ uint32_t status; /// Control Register Fields - enum [[clang::flag_enum]] : uint32_t{ + enum [[clang::flag_enum]] ControlFields : uint32_t{ /// Write 1 to set RGB LEDs to specified colours. ControlSet = 1 << 0, /** @@ -39,7 +44,7 @@ }; /// Status Register Fields - enum [[clang::flag_enum]] : uint32_t{ + enum [[clang::flag_enum]] StatusFields : uint32_t{ /** * When asserted controller is idle and new colours can be set, * otherwise writes to regLed0, regLed1, and control are ignored. @@ -47,37 +52,44 @@ StatusIdle = 1 << 0, }; + /** + * Blocks until the controller is not busy. + * + * The controller can be busy when it is in the process of updating the + * LEDs. While busy, register writes will be ignored. + */ void wait_for_idle() volatile { while ((status & StatusIdle) == 0) {} } + /** + * Set the desired Red, Green, and Blue value of an LED. To apply these + * changes, one needs to run `SonataRgbLedController::update()`. + */ void - rgb(uint8_t red, uint8_t green, uint8_t blue, SonataRgbLed led) volatile + rgb(SonataRgbLed led, uint8_t red, uint8_t green, uint8_t blue) volatile { - uint32_t rgb = (static_cast<uint32_t>(blue) << 16) | - (static_cast<uint32_t>(green) << 8) | - static_cast<uint32_t>(red); wait_for_idle(); - - switch (led) - { - case SonataRgbLed::Led0: - rgbLed0 = rgb; - case SonataRgbLed::Led1: - rgbLed1 = rgb; - }; + ledColors[static_cast<uint32_t>(led)] = + (static_cast<uint32_t>(blue) << 16) | + (static_cast<uint32_t>(green) << 8) | static_cast<uint32_t>(red); } + /// Update the colours of the LEDs. void update() volatile { wait_for_idle(); control = ControlSet; } - void clear() volatile + /// Switch all of the RGB LEDs off. + void off() volatile { wait_for_idle(); control = ControlOff; } }; + +static_assert(sizeof(SonataRgbLedController) == 16, + "The SonataRgbLedController structure is the wrong size.");