/**
 * Projekt Kap06-GPIO-02
 *
 * 2. Beispiel zum "Toggeln" von GPIO-Port A / Pin 0
 */

#include <stm32f446xx.h>
#include <system_stm32f4xx.h>

/**
 * Kommentar in Zeile 14 entfernen, wenn Sie die MCAL testen möchten.
 */
//#define MCAL

#ifdef MCAL
#include <mcalGPIO.h>
#endif

// Funktionsprototypen
void delayMillis(uint16_t delay);


int main(void)
{
#ifdef MCAL     // Start der MCAL-Version
    gpioSelectPort(GPIOA);
    gpioSelectPinMode(GPIOA, PIN0, OUTPUT);

    while(1)
    {
        gpioTogglePin(GPIOA, PIN0);
        delayMillis(500);
    }

#else           // Ende der MCAL-Version, Beginn: Direkte Registerprogrammierung

    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;    // GPIOA: Clock aktivieren

    GPIOA->MODER &= ~GPIO_MODER_MODE0_Msk;  // GPIOA: PA0 zuruecksetzen
    GPIOA->MODER |= GPIO_MODER_MODE0_0;     // GPIOA: PA0 --> Ausgang

    // Vermeidung von Read-Modify-Write (RMW)
    while (1)
    {
        GPIOA->BSRR = GPIO_BSRR_BS_0;       // BS = Bit setzen in GPIO_BSRR_BS_0
        delayMillis(500);
        GPIOA->BSRR = GPIO_BSRR_BR_0;       // BS = Bit zurueck in GPIO_BSRR_BR_0
        delayMillis(500);
    }

#endif          // Ende: Direkte Registerprogrammierung
}

/**
 * !!!Sehr schlechte Version eines Delay!!!
 */
void delayMillis(uint16_t delay)
{
    uint16_t i = 0;

    for (; delay > 0; --delay)
    {
        for (i = 0; i < 1245; ++i)
        {
            ;
        }
    }
}
