/**
 * @brief Ansteuerung eines LC-Displays auf Basis des HD44780 mit einem PCF8574.
 *
 * @par
 * Verwendete Anschlusspins:
 *     PB8 : I2C1 SCL
 *     PB9 : I2C1 SDA
 *
 * @note
 * Neben der Funktion lcdSendString(), die einen Textstring ausgibt, habe ich
 * die Funktion lcdSendChar() vorbereitet. Obwohl sie mit Ausnahme des Parameters
 * zur Einstellung der identisch
 * wird weiterentwickelt. Die Parameter pclk, duty und trise werden ignoriert
 * und intern durch funktionierende Werte ersetzt. Annahme: Die Werte basieren
 * auf pclk = 16 MHz.
 *
 *
 */

/**
 ******************************************************************************
 * @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 <mcalI2C.h>
#include <mcalSystem.h>

#include <lcd.h>
#include <dwtDelay.h>

/**
 * I2C-Adresse des PCF8574A.
 * Beachten Sie hier, dass andere Ausführungen des PCF8574 andere
 * Basisadressen haben!
 */
//#define PCF8574A_ADDR       (0x70)

bool timerTrigger = false;

int main(void)
{
//    char text[] = "ABC - Die Katze ...";
    uint32_t pclk1Freq = 0UL;
    uint32_t dummy = 0UL;

    // Initialisierung des Systick-Timers
//    systickInit(SYSTICK_1MS);
//    systickSetMillis(&ledTimer, 500);

    DWT_Delay_Init();

    // GPIOB-Bustakt aktivieren wegen der Verwendung von PB8/PB9.
    gpioInitPort(GPIOB);
    gpioSelectPinMode(GPIOB, PIN8, ALTFUNC);
    gpioSelectAltFunc(GPIOB, PIN8, AF4);            // PB8 : I2C1 SCL
    gpioSelectPinMode(GPIOB, PIN9, ALTFUNC);
    gpioSelectAltFunc(GPIOB, PIN9, AF4);            // PB9 : I2C1 SDA
    gpioSetOutputType(GPIOB, PIN8, OPENDRAIN);
    gpioSetOutputType(GPIOB, PIN9, OPENDRAIN);

    /**
     * Die beiden folgenden Zeilen muessen auskommentiert werden,
     * wenn Sie externe Pull-Up-Widerstände verwenden.
     */
    gpioSelectPushPullType(GPIOB, PIN8, PULLUP);    // Verwendung des internen Pullup-Widerstandes
    gpioSelectPushPullType(GPIOB, PIN9, PULLUP);    // Verwendung des internen Pullup-Widerstandes

    // Initialisierung des I2C-Controllers
    pclk1Freq = systemGetPclk1Freq();                 // Get APB1 peripheral clock
    i2cInit(I2C1, pclk1Freq, I2C_DUTY_CYCLE_2, 17, I2C_CLOCK_100);

    // Initialisierung des Displays
    lcdInit(I2C1);
    lcdSendCmd(I2C1, LCD_ADDR, LCD_CLEAR);

    lcdSendCmd(I2C1, LCD_ADDR, LCD_CURSOR_HOME);

    lcdSendChar(I2C1, LCD_ADDR, 1, 1, '1');
    lcdSendString(I2C1, LCD_ADDR, 1, 3, "Zeile 1", 7);
    lcdSendChar(I2C1, LCD_ADDR, 2, 1, '2');
    lcdSendString(I2C1, LCD_ADDR, 2, 3, "Zeile 2", 7);
    lcdSendChar(I2C1, LCD_ADDR, 3, 1, '3');
    lcdSendString(I2C1, LCD_ADDR, 3, 3, "Zeile 3", 7);
    lcdSendChar(I2C1, LCD_ADDR, 4, 1, '4');
    lcdSendString(I2C1, LCD_ADDR, 4, 3, "Zeile 4", 7);


    /* Hauptprogramm: Endlosschleife */
    while(1)
    {
        ++dummy;
    }
}
