/***************************************************************************/
/*                             Druckersoftware                             */
/*                    Copyright (C) Carl Valentin GmbH                     */
/***************************************************************************/

/*
 * uartParams.h
 *
 *  Created on: 11.07.2022
 *      Author: preitinger
 */

#ifndef FPGASERIAL_UARTPARAMS_H_
#define FPGASERIAL_UARTPARAMS_H_

#include <linux/types.h>
#include <linux/bits.h>

#include "../KM_bit_utils.h"

/**
 * Parameter fuer das UART-Modul im FPGA
 */
static int up_uartPeriodCount(int baudrate) {
    const int freq = 64000000; // 64MHz Takt im FPGA
    // Anzahl us je Bit: 1000000 / baudrate
    // Anzahl 64Mhz-Takte je Bit: 64 * 1000000 / baudrate
    // 3 Takte abgezogen fuer Setzen des Counter-Load-Triggers, Zuruecksetzen des Counts im Counter, zus. Takt fuer Uebergang von 0 zu "-1"
    // da bei pruefen auf -1 nur das Vorzeichen-Bit gelesen werden muss und nicht alle
    int res = freq / baudrate - 3;
//    pr_info("baudrate=%d; res=%d\n", baudrate, res);
    ASSERT(res >= 0 && res < (1 << 21));
    return res;
}

/**
 * Parameter fuer das UART-Modul im FPGA
 */
static int up_uartDataBits(int dataBits) {
    int res = dataBits - 2;
    ASSERT(res >= 0  && res < (1 << 4));
    return res;
}

static uint16_t up_word0(int txPeriodCount) {
    uint16_t res = 0;
    setBits(&res, 0, txPeriodCount, 0, 16);
    return res;
}

static uint16_t up_word1(int txPeriodCount, int rxPeriodCount) {
    uint16_t res = 0;
    setBits(&res, 0, txPeriodCount, 16, 5);
    setBits(&res, 5, rxPeriodCount, 0, 11);
    return res;
}

static uint16_t up_word2(int rxPeriodCount, int dataBits, int parity, int stopBits) {
    uint16_t res = 0;
//    pr_info("up_word2: rxPeriodCount=0x%x, dataBits=0x%x, parity=0x%x, stopBits=0x%x\n", rxPeriodCount, dataBits, parity, stopBits);
    setBits(&res, 0, rxPeriodCount, 11, 10);
    setBits(&res, 10, dataBits, 0, 3);
    setBits(&res, 13, parity, 0, 2);
    setBits(&res, 15, stopBits, 0, 1);
    return res;
}

static uint16_t up_word3(uint8_t startChar, uint8_t stopChar) {
    uint16_t res = 0;
    setBits(&res, 0, startChar, 0, 8);
    setBits(&res, 8, stopChar, 0, 8);

    return res;
}

#endif /* FPGASERIAL_UARTPARAMS_H_ */
