/**
 * @brief Ansteuerung eines LC-Displays auf Basis des HD44780 mit einem PCF8574.
 *
 * Das Beispiel existiert ausschliesslich als MCAL-Version.
 *
 * @par
 * Verwendete Anschlusspins:
 *     PB8 : I2C1 SCL
 *     PB9 : I2C1 SDA
 *
 * @note
 * Neben der Funktion lcdSendString(), die einen Textstring ausgibt, existiert
 * die Funktion lcdSendChar().
 */

#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 PCF8574AN.
 * Beachten Sie hier, dass andere Ausführungen des PCF8574 andere
 * Basisadressen haben!
 */
//#define PCF8574AN_ADDR       (0x70)

bool timerTrigger = false;

int main(void)
{
    GPIO_TypeDef *port = GPIOB;
    I2C_TypeDef  *i2c  = I2C1;

    uint32_t dummy = 0UL;
    uint32_t pclock = sysGetPclk1Freq();

    DWT_Delay_Init();                           // Interne Funktion von ARM

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

    /**
     * Die beiden folgenden Zeilen muessen auskommentiert werden,
     * wenn Sie externe Pull-Up-Widerstände verwenden.
     */
    gpioSelectPushPullMode(port, PIN8, PULLUP);
    gpioSelectPushPullMode(port, PIN9, PULLUP);

    // Initialisierung des I2C-Controllers
//    i2cInit(i2c, pclock, I2C_DUTY_CYCLE_2, 17, I2C_CLOCK_100);
    i2cSelectI2C(i2c);                          // I2C1: Bustakt aktivieren
    i2cDisableDevice(i2c);
    i2cSetPeripheralClockFreq(i2c, pclock);     // I2C1: Periph. Clk in MHz
    i2cSetDutyCycle(i2c, I2C_DUTY_CYCLE_2);     // I2C1: Duty-cycle einstellen
    i2cSetRiseTime(i2c, 17);                    // I2C1: 17 ist ein bewaehrter Wert
    i2c->CCR |= 0x50;                           // I2C1: Keine MCAL-Funktion
    i2cEnableDevice(i2c);                       // I2C1: Aktivieren

    // 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;
    }
}
