sonata: simplified the PWM driver
There are now 6 general purpose PWM outputs and one dedicated to the
LCD's backlight. Instead of implementing the indexing logic and checks
in the driver. The driver is changed to only over map to a single PWM
output. We simply alias an array of these for the general purpose PWM
memory region.
The dutyCycle <= period assertion was removed, because dutyCycle >
period is the only way to acheive a constant high, 100% duty cycle
output from the Sonata system's PWM block.
diff --git a/sdk/include/platform/sunburst/platform-pwm.hh b/sdk/include/platform/sunburst/platform-pwm.hh
index 60f1704..727af3b 100644
--- a/sdk/include/platform/sunburst/platform-pwm.hh
+++ b/sdk/include/platform/sunburst/platform-pwm.hh
@@ -1,37 +1,20 @@
#pragma once
#include <debug.hh>
#include <stdint.h>
+#include <utils.hh>
-/**
- * A driver for Sonata's Pulse-Width Modulation (PWM).
- *
- * Documentation source can be found at:
- * https://github.com/lowRISC/sonata-system/blob/97a525c48f7bf051b999d0178dba04859819bc5e/doc/ip/pwm.md
- *
- * Rendered documentation is served from:
- * https://lowrisc.github.io/sonata-system/doc/ip/pwm.html
- */
-struct SonataPulseWidthModulation
+namespace SonataPulseWidthModulation
{
/**
- * Flag to set when debugging the driver for UART log messages.
+ * A driver for Sonata's Pulse-Width Modulation (PWM).
+ *
+ * Documentation source can be found at:
+ * https://github.com/lowRISC/sonata-system/blob/97a525c48f7bf051b999d0178dba04859819bc5e/doc/ip/pwm.md
+ *
+ * Rendered documentation is served from:
+ * https://lowrisc.github.io/sonata-system/doc/ip/pwm.html
*/
- static constexpr bool DebugDriver = false;
-
- /**
- * Helper for conditional debug logs and assertions.
- */
- using Debug = ConditionalDebug<DebugDriver, "PWM">;
-
- /**
- * The number of pulse-width modulated outputs that are available.
- */
- static constexpr size_t OutputCount = 1;
-
- /**
- * The pulse-width modulation outputs available on Sonata.
- */
- struct OutputRegisters
+ struct Output : private utils::NoCopyNoMove
{
/**
* The duty cycle of the wave, represented as a width counter. That
@@ -46,23 +29,45 @@
* as only an 8 bit counter is being used.
*/
uint32_t period;
- } outputs[OutputCount];
- /*
- * Sets the output of a specified pulse-width modulated output.
- *
- * The first argument is the index of the output. The second argument is
- * the period (length) of the output wave represented as a counter of
- * system clock cycles. The third argument is the number of clock cycles
- * for which a high pulse is sent within that period.
- *
- * So for example `output_set(0, 200, 31)` should set a 15.5% output.
- */
- void output_set(uint32_t index, uint8_t period, uint8_t dutyCycle) volatile
+ /*
+ * Sets the output of a specified pulse-width modulated output.
+ *
+ * @param period The length of the output wave represented as a counter
+ * of system clock cycles.
+ * @param dutyCycle The number of clock cycles for which a high pulse is
+ * sent within that period.
+ *
+ * So for example `output_set(0, 200, 31)` should set a 15.5% output.
+ * For a constant high output (100% duty cycle), set the dutyCycle >
+ * period.
+ */
+ void output_set(uint8_t period, uint8_t dutyCycle) volatile
+ {
+ this->period = period;
+ this->dutyCycle = dutyCycle;
+ }
+ };
+
+ /// A convenience structure that can map onto multiple PWM outputs.
+ template<size_t NumberOfPwms = 6>
+ struct Array
{
- Debug::Assert(index < OutputCount, "Specified PWM is out of range");
- Debug::Assert(dutyCycle <= period, "Duty cycle cannot exceed 100%");
- outputs[index].period = period;
- outputs[index].dutyCycle = dutyCycle;
- }
-};
+ Output output[NumberOfPwms];
+
+ template<size_t Index>
+ volatile Output *get() volatile
+ {
+ static_assert(Index < NumberOfPwms, "PWM index out of bounds");
+ return output + Index;
+ }
+ };
+
+ /**
+ * There are six general purpose PWM outputs are general purpose that can be
+ * pinmuxed to different outputs.
+ */
+ using General = Array<6>;
+ /// There is one dedicated PWM for the LCD backlight.
+ using LcdBacklight = Output;
+} // namespace SonataPulseWidthModulation