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

/*
 * tx_size_fifo.h
 *
 *  Created on: 01.06.2022
 *      Author: preitinger
 */

#ifndef FPGASERIAL_TX_SIZE_FIFO_H_
#define FPGASERIAL_TX_SIZE_FIFO_H_

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

#include "fpgaMem.h"

/**
 * implementiert den Fifo im ram_km des FPGAs fuer die Byte-Groessen der TX-Subbloecke.
 * (Je vom FPGA getriggerten TX-DMA-Transfers wird ein TX-Subblock vom KM zum FPGA transportiert. Danach muss das FPGA wissen wie viele Bytes davon tatsaechlich gesendet werden sollen.)
 */
typedef struct {
    // begin, end und nextWrite beinhalten je eine Adresse fuer den ram_km
    off_t begin;
    off_t end;
    off_t nextWrite;
} TTxSizeFifo;

void tx_size_fifo_init(TTxSizeFifo* p, off_t begin, off_t end) {
    p->begin = begin;
    p->end = end;
    p->nextWrite = p->begin;
}

void tx_size_fifo_push(TTxSizeFifo* p, uint16_t size) {
    ASSERT(p->nextWrite >= p->begin && p->nextWrite < p->end);
//    pr_info("Zieladresse fuer tx_size_fifo_push: 0x%x\n", (int) p->nextWrite);
    ramKmWrite16(p->nextWrite, size);

    if (++p->nextWrite == p->end) {
        p->nextWrite = p->begin;
    }

    ASSERT(p->nextWrite >= p->begin && p->nextWrite < p->end);
}

int tx_size_fifo_chars_in_buffer(TTxSizeFifo* p, int remainingSubBlocks) {
    int n = 0;
    off_t nextRead;

    ASSERT(remainingSubBlocks >= 0);
    nextRead = p->nextWrite;

    while (remainingSubBlocks > 0) {
        if (nextRead == p->begin) {
            nextRead = p->end;
        }

        --nextRead;
        n += ramKmRead16(nextRead);
        --remainingSubBlocks;
    }

    return n;
}



#endif /* FPGASERIAL_TX_SIZE_FIFO_H_ */
