sifive / freedom-metal

Bare Metal Compatibility Library for the Freedom Platform
Other
154 stars 47 forks source link

Support to enable parent interrupt of PWM channel ID in metal_pwm_cfg_interrupt #363

Closed aidenschoi closed 3 years ago

aidenschoi commented 3 years ago

Issue Description PWM Interrupt doesn't work well with example-pwm in freedom-metal-next branch on sesame.

Root Cause In sesame core.dts, the number of pwm interrupt channel ID is 4. pwm0 : 35, 36, 37, 38, pwm1 : 39, 40, 41, 42

        L43: pwm@10020000 {
            clocks = <&L39>;
            compatible = "sifive,pwm0";
            interrupt-parent = <&L3>;
            interrupts = <35 36 37 38>;
            reg = <0x0 0x10020000 0x0 0x1000>;
            reg-names = "control";
            sifive,comparator-widthbits = <16>;
            sifive,ncomparators = <4>;
        };
        L44: pwm@10021000 {
            clocks = <&L39>;
            compatible = "sifive,pwm0";
            interrupt-parent = <&L3>;
            interrupts = <39 40 41 42>;
            reg = <0x0 0x10021000 0x0 0x1000>;
            reg-names = "control";
            sifive,comparator-widthbits = <16>;
            sifive,ncomparators = <4>;
        };

But, the implement in j2 file considered the index only for the first one instead of all indexes. So there is no API to get which index in PLIC to enable/disable interrupt. Also, there is no code to enable parent interrupt (PLIC) of PWM.

Test example-pwm works well with ENABLE_INTERRUPTS on sesame with vcu-118 fpga. all index interrupts of pwm work well. I checked it with clang-formater.

Additionally, to test this PR, it should change example-pwm code too as below.

--- a/software/example-pwm/example-pwm.c
+++ b/software/example-pwm/example-pwm.c
@@ -31,7 +31,7 @@

 #ifdef ENABLE_INTERRUPTS

-void metal_sifive_pwm0_source0_handler(void)
+void metal_sifive_pwm0_source_0_handler(void)
{
     static unsigned int i = 0;

@@ -73,7 +63,8 @@ int main(void) {
     metal_pwm_trigger(pwm, 0, METAL_PWM_CONTINUOUS);

 #ifdef ENABLE_INTERRUPTS
-    metal_pwm_cfg_interrupt(pwm, METAL_PWM_INTERRUPT_ENABLE);
+    metal_pwm_cfg_interrupt(pwm, METAL_PWM_INTERRUPT_ENABLE, 0);
+    metal_cpu_enable_interrupts();
#else
     metal_pwm_set_duty(pwm, 2, 90, METAL_PWM_PHASE_CORRECT_DISABLE);
     metal_pwm_set_duty(pwm, 3, 20, METAL_PWM_PHASE_CORRECT_DISABLE);
aidenschoi commented 3 years ago

@nategraff-sifive @keith-packard Can you please review this PR?

nategraff-sifive commented 3 years ago

@aidenschoi Would you mind making the corresponding PR to example-pwm?

aidenschoi commented 3 years ago

@nategraff-sifive I created https://github.com/sifive/example-pwm/pull/2 in example-pwm, too.

aidenschoi commented 3 years ago

@nategraff-sifive @keith-packard did you complete reviewing this PR and https://github.com/sifive/example-pwm/pull/2 in example-pwm?