/*******************************************************************************
 * This file is part of the PB2DFU library developed
 * within the EU Artemis project SMECY (Smart Multicore Embedded Systems)
 * Artemis JU 100230 and MSMT 7H10001,       http://www.smecy.eu
 * Copyright (C) 2011 UTIA AV CR, v.v.i.     http://sp.utia.cz
 * 
 * This program is distributed WITHOUT ANY WARRANTY; without even 
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
 *  PURPOSE.
 *
 * This file has been released within the SMECY project
 * consortium for the requirements of the SMECY project.
 * Any use outside the SMECY consortium and/or for any
 * developments outside the scope of the SMECY project is prohibited.
 *
 * For more details contact Roman Bartosinski <bartosr@utia.cas.cz>.
 *******************************************************************************
 * Filename  : dfu_fp01_1x1.h
 * Authors   : Roman Bartosinski <bartosr@utia.cas.cz>
 * Project   : SMECY
 * Purpose   : Header file of firmware API for DFU_FP01_1x1 hardware accelerator
 * Release   : 
 * Version   : 0.1
 * Date      : 2011/01/10
 *
 * Long Description:
 *  Functions, constants and definitions specific for the DFU_FP01_1x1
 *  hardware accelerator in EdkDSP platform.
 * 
 *******************************************************************************
 * Modifications:
 *  Author: Roman Bartosinski
 *  Date  : 2011/04/18
 *  Description: Renamed functions and constants in PB2MB interface:
 *      MB2PB -> PB2MB, PB2MB_FL_ -> PB2MB_STAT_, MB2PB_FL_ -> PB2MB_CTRL_, ...
 *  --
 *  
 ******************************************************************************/

#ifndef _DFU_FP01_1X1_HEADER_
#define _DFU_FP01_1X1_HEADER_

/**
 * enum dfu_fp01_operations - codes of operations supported by accelerator DFU_FP01
 * @DFU_OP_VVER: ask about HW version
 * @DFU_OP_VZ2A: copy vector    a[i] = z[j]
 * @DFU_OP_VB2A: copy vector    a[i] = b[j]
 * @DFU_OP_VZ2B: copy vector    b[i] = z[j]
 * @DFU_OP_VA2B: copy vector    b[i] = a[j]
 * @DFU_OP_VADD: add vectors    z[i] = a[j] + b[k]
 * @DFU_OP_VADD_BZ2A: add vectors    a[i] = b[j] + z[k]
 * @DFU_OP_VADD_AZ2B: add vectors    b[i] = a[j] + z[k]
 * @DFU_OP_VSUB: sub vectors    z[i] = a[j] - b[k]
 * @DFU_OP_VSUB_BZ2A: sub vectors    a[i] = b[j] + z[k]
 * @DFU_OP_VSUB_AZ2B: sub vectors    b[i] = a[j] + z[k]
 * @DFU_OP_VMULT: mult vectors   z[i] = a[j] * b[k]
 * @DFU_OP_VMULT_BZ2A: mult vectors   a[i] = b[j] * z[k]
 * @DFU_OP_VMULT_AZ2B: mult vectors   b[i] = a[j] * z[k]
 * @DFU_OP_VPROD: vector product z = a[i..i+nn]*b[i..i+nn]
 * @DFU_OP_VMAC: vector MAC     z[i] = z[i] + a[j]*b[k] 1..13
 * @DFU_OP_VMSUBAC: vector MSUBAC  z[i] = z[i] - a[j]*b[k] 1..13
 *
 * These codes are used with functions %pb2dfu_start_op and %pd2dfu_restart_op
 * to select operation performed in the accelerator.
 */
/*enum dfu_fp01_operations {
	DFU_OP_VVER       = 0x00,
	DFU_OP_VZ2A       = 0x01,
	DFU_OP_VB2A       = 0x02,
	DFU_OP_VZ2B       = 0x03,
	DFU_OP_VA2B       = 0x04,
	DFU_OP_VADD       = 0x05,
	DFU_OP_VADD_BZ2A  = 0x06,
	DFU_OP_VADD_AZ2B  = 0x07,
	DFU_OP_VSUB       = 0x08,
	DFU_OP_VSUB_BZ2A  = 0x09,
	DFU_OP_VSUB_AZ2B  = 0x0A,
	DFU_OP_VMULT      = 0x0B,
	DFU_OP_VMULT_BZ2A = 0x0C,
	DFU_OP_VMULT_AZ2B = 0x0D,
	DFU_OP_VPROD      = 0x0E,
	DFU_OP_VMAC       = 0x0F,
	DFU_OP_VMSUBAC    = 0x10,
}; */
#define DFU_OP_VVER       0x00 // ask about HW version
#define DFU_OP_VZ2A       0x01 // copy vector    a[i] <= z[j]
#define DFU_OP_VB2A       0x02 // copy vector    a[i] <= b[j]
#define DFU_OP_VZ2B       0x03 // copy vector    b[i] <= z[j]
#define DFU_OP_VA2B       0x04 // copy vector    b[i] <= a[j]
#define DFU_OP_VADD       0x05 // add vectors    z[i] <= a[j] + b[k]
#define DFU_OP_VADD_BZ2A  0x06 // add vectors    a[i] <= b[j] + z[k]
#define DFU_OP_VADD_AZ2B  0x07 // add vectors    b[i] <= a[j] + z[k]
#define DFU_OP_VSUB       0x08 // sub vectors    z[i] <= a[j] - b[k]
#define DFU_OP_VSUB_BZ2A  0x09 // sub vectors    a[i] <= b[j] + z[k]
#define DFU_OP_VSUB_AZ2B  0x0A // sub vectors    b[i] <= a[j] + z[k]
#define DFU_OP_VMULT      0x0B // mult vectors   z[i] <= a[j] * b[k]
#define DFU_OP_VMULT_BZ2A 0x0C // mult vectors   a[i] <= b[j] * z[k]
#define DFU_OP_VMULT_AZ2B 0x0D // mult vectors   b[i] <= a[j] * z[k]
#define DFU_OP_VPROD      0x0E // vector product z    <= a[i..i+nn]*b[i..i+nn]
#define DFU_OP_VMAC       0x0F // vector MAC     z[i] <= z[i] + a[j]*b[k] 1..13
#define DFU_OP_VMSUBAC    0x10 // vector MSUBAC  z[i] <= z[i] - a[j]*b[k] 1..13


/**
 * enum dfu_fp01_memories - identifiers of data memories in DFU_FP01 accelerator
 * @DFU_MEM_A: target memory is data memory A
 * @DFU_MEM_B: target memory is data memory B
 * @DFU_MEM_Z: target memory is data memory Z
 *
 * The identifiers are used with functions %pb2dfu_set_... to select target data memory.
 */
/*enum dfu_fp01_memories {
	 DFU_MEM_A,
	 DFU_MEM_B,
	 DFU_MEM_Z
}; */
#define DFU_MEM_A 0x00
#define DFU_MEM_B 0x01
#define DFU_MEM_Z 0x02


/***********************************/
/* functions for interfacing MB-PB */

/**
 * pb2mb_read_data - read (blocking) data from a host CPU (MB)
 * 
 * The function communicates with a host CPU (MB) and waits for
 * one data byte which is acknowledged. 
 * Return Value: The function returns value of the received data byte.
 */
unsigned char pb2mb_read_data();

/**
 * pb2mb_write_data - send (blocking) data to a host CPU (MB)
 * @data: one byte which will be send to MB
 *
 * The function sends one data byte and wait for acknowledgement.
 * Return Value: The function doesn't return any value.
 */
void pb2mb_write_data(unsigned char data);

/**
 * pb2mb_eoc - send (blocking) a message 'End Of Computation' to a host CPU (MB)
 * @data: one data byte which will be send to MB with the EOC message
 *
 * The function sends message End of Computation (EOC) with an optional
 * data byte to a host CPU (MB). Then it waits for acknowlegement from
 * the host CPU. The message should be send anytime the accelerator wants
 * to synchronize computation with a host CPU. Usually, the message is
 * sent after the entire computation.
 * Return Value: The function doesn't return any value.
 */
void pb2mb_eoc(unsigned char data);

/**
 * pb2mb_req_reset - send (blocking) a message 'Request for Reset' to a host CPU (MB)
 * @data: one data byte which will be send to MB with the RR message
 *
 * The function sends message 'Request for Reset' (RR) with an optional
 * data byte to a host CPU (MB). Then it waits for acknowlegement from
 * the host CPU. The message should be send before reseting controller
 * to inform the host CPU that the accelerator's controller will be
 * reset to the initial state.
 * Return Value: The function doesn't return any value.
 */
void pb2mb_req_reset(unsigned char data);

/**
 * pb2mb_reset - reset accelerator itself
 *
 * The function sets accelerator's controller to the initial state and
 * set the accelerator's status bit.
 * Return Value: The function doesn't return any value.
 */
void pb2mb_reset();


/************************************/
/* functions for interfacing PB-DFU */

/**
 * pb2dfu_wait4hw - PB will wait for end of computation
 *
 * The function waits for finishing computation in the accelerator.
 * The function should be called before subsequent run of the next
 * operation. The next operation can be prepared before the waiting
 * to speed up the entire computation.
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_wait4hw();

/**
 * pb2dfu_start_op - start operation in DFU with specified length of data vectors
 * @op: DFU operation (constants %DFU_OP_xxx)
 * @cnt: length of input data vectors
 *
 * The function covers two functions (pb2dfu_set_cnt and pb2dfu_restart_op).
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_start_op(unsigned char op, unsigned char cnt);

/**
 * pb2dfu_restart_op - start operation in DFU
 * @op: DFU operation (constants DFU_OP_xxx)
 *
 * All parameters of the operation must be set before this function.
 * All parameters are registered and so only changed parameters from
 * previous operations must be set. On the other hand, the operation
 * must be always set because the function starts a required operation
 * in the DFU. 
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_restart_op(unsigned char op);

/**
 * pb2dfu_set_cnt - set length of input data vectors for the next operation
 * @cnt: length of input data vectors
 *
 * The function sets length of the input data vectors.
 * The simple operations (as VADD, VMULT) will be performed @cnt-times
 * as one pipelined operation.
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_set_cnt(unsigned char cnt);

/**
 * pb2dfu_set_addr - set address of the first element in the vector
 * @mem: select data memory (constant %DFU_MEM_xxx)
 * @addr: address of the first element in vector saved in memory @mem in the current bank
 *
 * The function sets lower part of the initial pointer (index of the first
 * element of vector in the specified memory bank) to @addr for memory
 * @mem and bank which is set with function %pb2dfu_set_bank. All data
 * memories are organized into memory banks with 256 elements.
 * The value will be used with the next operation.
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_set_addr(unsigned char mem, unsigned char addr);

/**
 * pb2dfu_set_bank - select bank for specified memory
 * @mem: select data memory (constant %DFU_MEM_xxx)
 * @bank: bank which will be used for the next operation
 *
 * The function sets higher part of the initial pointer (bank of memory
 * @mem used for the next operation) to @bank for memory @mem.
 * Lower part of the initial pointer can be set with function
 * %pb2dfu_set_addr. The value will be used with the next operation.
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_set_bank(unsigned char mem, unsigned char bank);

/**
 * pb2dfu_set_fulladdr - set full address (bank and offset) of the first element in the vector
 * @mem: select data memory (constant %DFU_MEM_xxx)
 * @bank: bank of memory @mem which will be used for the next operation
 * @addr: address of the first element in vector saved in memory @mem in the selected bank
 *
 * The function sets full address of the initial pointer (the first
 * element of a vector) in memory @mem. Each full address consists of
 * bank and address in the bank which can be also set separately with
 * functions %pb2dfu_set_bank and %pb2dfu_set_addr.
 * The address will be used with the next operation.
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_set_fulladdr(unsigned char mem, unsigned char bank, unsigned char addr);

/**
 * pb2dfu_set_inc - set increment of offset for vector in selected memory
 * @mem: select data memory (constant %DFU_MEM_xxx)
 * @inc: increment between two elements of vector in the memory @mem
 *
 * The function sets address increment to @inc for vector from memory
 * @mem. Pointer to memory @mem is increment about @inc before processing
 * the next vector element.
 * The value will be used with the next operation.
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_set_inc(unsigned char mem, unsigned short inc);

/**
 * pb2dfu_set_restart_addr - set restart address for using vector elements in loop
 * @mem: select data memory (constant %DFU_MEM_xxx)
 * @addr: restart address (lower part of the full address)
 *
 * The restart address @addr is used if elements of the vector in memory
 * @mem are used in a loop. When the pointer to the next element overflow
 * to the other bank it is set (lower part of the full address) to the
 * restart address @addr.
 * The value will be used with the next operation.
 * Return Value: The function doesn't return any value.
 */
void pb2dfu_set_restart_addr(unsigned char mem, unsigned char addr);


#endif /* _DFU_FP01_1X1_HEADER_ */
