/***************************************************************************/
/*                             Druckersoftware                             */
/***************************************************************************/

/*
 * JobApi_commands.h
 *
 *  Created on: 13.04.2022
 *      Author: preitinger
 */

#ifndef JOBAPI_JOBAPI_COMMANDS_H_
#define JOBAPI_JOBAPI_COMMANDS_H_

// 2 hoechste Bytes immer Kommando, 2 niedrigste Bytes optional fuer Argumente

#define EPC_CMD_MASK                        0xffff0000
#define EPC_ARG_MASK                        0x0000ffff

#define EPC_CHAN_ALLOC                      0x00000000
#define EPC_CHAN_CROSSBAR                   0x00010000
#define EPC_CHAN_FREE                       0x00020000
#define EPC_PRMS_ALLOC                      0x00030000
#define EPC_PRMS_FREE                       0x00040000
#define EPC_PIN_MUX                         0x00050000
#define EPC_WAIT_FOR_ANY_DMA_COMPLETION     0x00060000
#define EPC_CLOSE                           0x00070000

#define EPC_ARG_BYTE_LO(cmd) ((cmd) & 0xff)
#define EPC_ARG_BYTE_HI(cmd) (((cmd) >> 8) && 0xff)

static void epc_packPinmuxArgs(/*in*/int off, int mode, bool pullEnabled, bool upSelected,
               bool receiverEnabled, /*out*/uint32_t* dest) __attribute((unused));

static void epc_packPinmuxArgs(/*in*/int off, int mode, bool pullEnabled, bool upSelected,
               bool receiverEnabled, /*out*/uint32_t* dest) {

    // off 0 bis 0x234, 10 bits
    // mode 0 bis 7, 3 bits
    // bools je 1 bit

    int offLen = 10;
    int modeLen = 3;
    int boolLen = 1;
    int pos = 0;

    ASSERT(16 >= offLen + modeLen + boolLen * 3); // sonst passts nicht in das low nibble von *dest
    *dest &= ~GENMASK(15, 0);

    addBits(dest, off, &pos, offLen);
    addBits(dest, mode, &pos, modeLen);
    addBits(dest, pullEnabled ? 1 : 0, &pos, boolLen);
    addBits(dest, upSelected ? 1 : 0, &pos, boolLen);
    addBits(dest, receiverEnabled ? 1 : 0, &pos, boolLen);
    ASSERT(pos == offLen + modeLen + boolLen * 3);
    ASSERT(pos <= 16);
}

static void epc_unpackPinmuxArgs(/*in*/uint32_t src, /*out*/int* off, int* mode,
                 bool* pullEnabled, bool* upSelected, bool* receiverEnabled) {

    int offLen = 10;
    int modeLen = 3;
    int boolLen = 1;
    int pos = 0;
    ASSERT(16 >= offLen + modeLen + boolLen * 3); // sonst passts nicht in das low nibble von *dest

    *off = (int) takeBits(src, &pos, offLen);
    *mode = (int) takeBits(src, &pos, modeLen);
    *pullEnabled = (bool) takeBits(src, &pos, boolLen);
    *upSelected = (bool) takeBits(src, &pos, boolLen);
    *receiverEnabled = (bool) takeBits(src, &pos, boolLen);
}


#endif /* JOBAPI_JOBAPI_COMMANDS_H_ */
