/**
 ******************************************************************************
 * @file           : main.c
 * @author         : Auto-generated by STM32CubeIDE
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2020 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 <stm32f4xx.h>
#include <stdint.h>
#include <stdbool.h>

#include <mcalSysTick.h>
#include <mcalGPIO.h>
#include <mcalSPI.h>
#include <max7219.h>

void max7219Init(SPI_TypeDef *spi);

bool timerTrigger = false;


int main(void)
{
    uint32_t spiTimer = 0UL;
    uint8_t  data = 0;

    // Initialisiert den Systick-Timer
    systickInit(SYSTICK_1MS);
    systickSetMillis(&spiTimer, 1000);

    // SPI: Wir verwenden GPIOA
    gpioInitPort(GPIOA);
    gpioSelectPinMode(GPIOA, PIN4, OUTPUT);     // PA4 = ~CS
    gpioSelectPinMode(GPIOA, PIN5, ALTFUNC);    // PA5 = SPI1 Clock
    gpioSelectAltFunc(GPIOA, PIN5, AF5);
    gpioSelectPinMode(GPIOA, PIN7, ALTFUNC);    // PA7 = SPI1 MOSI
    gpioSelectAltFunc(GPIOA, PIN7, AF5);

    // Init SPI1
    spiInitSPI(SPI1, CLK_DIV_16, DATA_FORMAT_8, SSM_ON, SSI_LVL_HIGH, MASTER, SPI_PHASE_EDGE_1, SPI_IDLE_LOW);
//    spiInitSPI(SPI1, CLK_DIV_16, DATA_FORMAT_16, SSM_ON, SSI_LVL_HIGH, MASTER, SPI_PHASE_EDGE_1, SPI_IDLE_LOW);

    // Init MAX7219
    max7219Init(SPI1);
    max7219SetDecodeMode(SPI1, DECODE_ALL);
    max7219Shutdown(SPI1);
    max7219TurnOn(SPI1);

    while (1)
    {
        if (timerTrigger == true)
        {
            DECREMENT_TIMER(spiTimer);
            timerTrigger = false;
        }

        if (isSystickExpired(spiTimer))
        {
            systickSetMillis(&spiTimer, 1000);

            // Prueft das gewaehlte Datenformat
            if (!(SPI1->CR1 & SPI_CR1_DFF))
            {
                spiWriteByte(SPI1, GPIOA, PIN4, REG_DIG0);
                spiWriteByte(SPI1, GPIOA, PIN4, data++);
            }
            else
            {
                spiWriteWord(SPI1, GPIOA, PIN4, ((REG_DIG0_SL8 << 8) | data++));
            }

            if (data > 9)
            {
                data = 0;
            }
        }
    }

    return 0;
}


