/**
 * Projekt Kap10-GPTIM-03-PWM-TIM2
 * ===============================
 *
 * Kanal 1 von TIM2 steuert als PWM-Ausgang eine LED an (dimmen).
 */
/**
 ******************************************************************************
 * @file           : main.c
 * @author         : Auto-generated by STM32CubeIDE
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */

#if !defined(__SOFT_FP__) && defined(__ARM_FP)
  #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif

#include <stdint.h>
#include <stdbool.h>

#include <stm32f4xx.h>

#include <mcalSysTick.h>
#include <mcalGPIO.h>
#include <mcalTimer.h>

void updateTimers(void);

bool     timerTrigger = false;
uint32_t pwmTimer= 0UL;

int main(void)
{
	bool     direction = UP;
	uint32_t preloadVal = 100;

	systickInit(SYSTICK_1MS);
	systickSetMillis(&pwmTimer, 10);

    /* GPIOA + TIM2: AF konfigurieren */
	gpioInitPort(GPIOA);

    /* TIM2, Channel 1 = Output (PA15) --> AF1 */
	gpioSelectPinMode(GPIOA, PIN15, ALTFUNC);
	gpioSelectAltFunc(GPIOA, PIN15, AF1);

    /* TIM2 konfigurieren */
    timerBusClkOn(TIM2);                      // Aus Modul mcalTimer.c/.h
    timerSetPrescaler(TIM2, (10 - 1));
    timerSetAutoReloadValue(TIM2, (10000 - 1));
    timerResetCounter(TIM2);

    timerSetCapCompMode(TIM2, TIMIO_CH1, TIMIO_OUTPUT, CHN_PWM_MODE_1);
    timerSetPreloadValue(TIM2, TIMIO_CH1, preloadVal);
    timerStart(TIM2);

    while(1)
    {
    	if (timerTrigger == TRUE)
    	{
    		updateTimers();
    	}

    	if (isSystickExpired(pwmTimer))
    	{
    		if (direction == UP)
    		{
    		    preloadVal = timerGetPreloadValue(TIM2, TIMIO_CH1) * 105/100;
    		    timerSetPreloadValue(TIM2, TIMIO_CH1, preloadVal);
    			if (TIM2->CCR1 > 10000)
    			{
    				direction = DOWN;
    			}
    		}
    		else
    		{
                preloadVal = timerGetPreloadValue(TIM2, TIMIO_CH1) * 95/100;
                timerSetPreloadValue(TIM2, TIMIO_CH1, preloadVal);
    			if (TIM2->CCR1 < 100)
            	{
            		direction = UP;
            	}
    		}
        	systickSetMillis(&pwmTimer, 10);
    	}
    }

    return 0;
}

/**
 * @brief Updates all timers within this function.
 */
void updateTimers(void)
{
	DECREMENT_TIMER(pwmTimer);
	timerTrigger = FALSE;
}
