/*
 * Parth Sarthi Sharma ([email protected])
 * Code based on examples from Raspberry Pi Foundation.
 * The code initializes a pin to be PWM output and then
 * turns the duty cycle up and down in order to fade an LED in and out
 */
#include <stdio.h> //The standard C library
#include "pico/stdlib.h" //Standard library for Pico
#include "pico/time.h" //The pico time library
#include "hardware/irq.h" //The hardware interrupt library
#include "hardware/pwm.h" //The hardware PWM library

#define LEDPin 9 //The LED Pin

void wrapHandler(){ //The PWM wrap handler function
    static int fade = 0; //Brightness level
    static bool rise = true; //Check if fading in or out
    pwm_clear_irq(pwm_gpio_to_slice_num(LEDPin)); //Clear the interrupt flag

    if(rise){ //If the brightness is rising
        fade++; //Increment the brightness level
        if(fade > 255){ //If the fade is greater than 255
            fade = 255; //Set the fade to be 255
            rise = false; //Set flag to make brightness fall
        }
    }
    else{ //If the brightness is dalling
        fade--; //Decrement the brightness level
        if(fade < 0){ //If the fade is lesser than 0
            fade = 0; //Set the fade to be 0
            rise = true; //Set flag to make brightness rise
        }
    }
    pwm_set_gpio_level(LEDPin, fade * fade); //Set the PWM level for the slice and channel associated with a GPIO. We use a square to make the change in brightness appear linear.
}

int main(){
    gpio_set_function(LEDPin, GPIO_FUNC_PWM); //Set the LED Pin to be PWM
    uint sliceNum = pwm_gpio_to_slice_num(LEDPin); //Get PWM slice number

    pwm_clear_irq(sliceNum); //Clear the IRQ for the linked slice
    pwm_set_irq_enabled(sliceNum, true); //Enable the IRQ for the given slice
    irq_set_exclusive_handler(PWM_IRQ_WRAP, wrapHandler); //Set an exclusive interrupt handler for the interrupt
    irq_set_enabled(PWM_IRQ_WRAP, true); //Enable or disable a specific interrupt on the executing core

    pwm_config config = pwm_get_default_config(); //Get a set of default values for PWM configuration
    pwm_config_set_clkdiv(&config, 4.f); //Set clock divider in a PWM configuration
    pwm_init(sliceNum, &config, true); //Initialise a PWM with settings from a configuration object

    while(1){
        tight_loop_contents(); //Empty function
    }
}
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT