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

/*
 * dmaAddresses.h
 *
 *  Created on: 31.03.2022
 *      Author: preitinger
 */

#ifndef DMAFRAMEWORK_DMAADDRESSES_H_
#define DMAFRAMEWORK_DMAADDRESSES_H_

#include "../Edma_neu.h"
#include "../KM_FpgaAddresses.h"

#define FPGA_ADDR_BASE                  0x02000000 // so definiert im Device-Tree, evtl. koennte man das mal von dort auslesen, wenn viel Zeit ist... ;-)
#define FPGA_ADDR_SIZE                  0x02000000
#define EDMA_BASE                       0x49000000

// Folgende Strukturen und Funktionen leicht abgewandelt aus drivers/dma/ti/edma.c uebernommen:

#define EDMA_PARM       0x4000  /* PaRAM entries */

#define PARM_OFFSET(param_no)   (EDMA_PARM + ((param_no) << 5))

// Schalter fuer diese Testadressen in dieser Datei,
// der ggf. in KM_testConfigs.h gesetzt wird: TEST_FPGA_ADDR

struct DmaAddressesEnv {
    void* mappedCpu;
    dma_addr_t mappedDma;
    uint32_t mappedSize;
    uint32_t magic;
};
static struct DmaAddressesEnv dmaAddressesEnv = {
        .magic = 0
};

void DmaAddressesEnv_init(void* mappedCpu, dma_addr_t mappedDma, uint32_t mappedSize) {
    struct DmaAddressesEnv* e = &dmaAddressesEnv;

    e->mappedCpu = mappedCpu;
    e->mappedDma = mappedDma;
    e->mappedSize = mappedSize;
    e->magic = 42;
}

void DmaAddressesEnv_exit(void) {
    // nothing to do (so far)
    ASSERT(dmaAddressesEnv.magic == 42);
}

static uint32_t dmaWriteAddrFpgaRamKm(off_t addrInRamKm);
static uint32_t dmaReadAddrFpgaRamKm(off_t addrInRamKm);
static uint32_t dmaAddrEdmaParamset(int ps);



/////////////////////////////////////////////////////////////////

#ifdef TEST_FPGA_ADDR

static const uint32_t testOffsetFpgaKmRam = 0;
static const uint32_t testOffsetEdmaParamsets = testOffsetFpgaKmRam + (1024 << 1);
static const uint32_t testOffsetEdmaParamsetsEnd = testOffsetEdmaParamsets + (256 << 5);

static bool checkAddrInKmRam(off_t addrInKmRam) {
    return addrInKmRam >= 0 && addrInKmRam < 1024;
}

static uint32_t dmaWriteAddrFpgaRamKm(off_t addrInKmRam) {
    return dmaAddressesEnv.mappedDma + testOffsetFpgaKmRam + (addrInKmRam << 1);
}

static uint32_t dmaReadAddrFpgaRamKm(off_t addrInKmRam) {
    return dmaAddressesEnv.mappedDma + testOffsetFpgaKmRam + (addrInKmRam << 1);
}

static void* testCpuAddrFpgaKmRam(off_t addrInKmRam) {
    return dmaAddressesEnv.mappedCpu + testOffsetFpgaKmRam + (addrInKmRam << 1);
}

//static uint32_t dmaAddrEdmaParamset(int ps) {
//    ASSERT(((dmaAddressesEnv.mappedDma + testOffsetEdmaParamsets) & (1 - (1 << 5))) == (dmaAddressesEnv.mappedDma + testOffsetEdmaParamsets));
//    return dmaAddressesEnv.mappedDma + testOffsetEdmaParamsets + (ps << 5);
//}




#else // ifdef TEST_FPGA_ADDR

static uint32_t dmaWriteAddrFpgaRamKm(off_t addrInRamKm) {
    return FPGA_ADDR_BASE | ADDR_RAM_KM | (addrInRamKm << 1);
}

static uint32_t dmaReadAddrFpgaRamKm(off_t addrInRamKm) {
    return FPGA_ADDR_BASE | ADDR_READ_KM | (addrInRamKm << 1);
}

static uint32_t dmaAddrMapped(off_t addrRelToMappedDma) __attribute((unused));

static uint32_t dmaAddrMapped(off_t addrRelToMappedDma) {
    return dmaAddressesEnv.mappedDma + addrRelToMappedDma;
}

#endif // ifdef TEST_FPGA_ADDR

static uint32_t dmaAddrEdmaParamset(int ps) {
    ASSERT(ps >= 0 && ps < 256);
    return EDMA_BASE | PARM_OFFSET(ps);
}



#endif /* DMAFRAMEWORK_DMAADDRESSES_H_ */
