#include <mil.h>
#include <milfpga.h>
#include <fpga_minmax.h>
#define FUNCTION_NB_PARAM 3
#define FUNCTION_OPCODE_FPGA_MIN_MAX 2
#define FUNCTION_PARAMETER_ERROR_CODE 1
#define FUNCTION_WRONG_FPGA_ERROR_CODE 2
void FPGAMinMax(MIL_ID SrcImageId, MIL_UINT32* pMinValue, MIL_UINT32* pMaxValue);
void MFTYPE FPGAMinMaxSlave(MIL_ID Func);
void FPGAMinMaxPrimitive(MIL_ID Func, MIL_ID MilSourceImage, MIL_UINT32* pMinValue, MIL_UINT32* pMaxValue);
void FPGAInitializeShadowRegisters(MIL_ID Func, FPGA_MINMAX_USER_ST* pShadow, MIL_BUFFER_INFO Buf);
void FPGAMinMaxPrimitive(MIL_ID Func,
MIL_ID MilSourceImage,
MIL_UINT32* pMinValue,
MIL_UINT32* pMaxValue)
{
MIL_BUFFER_INFO Src;
MIL_FPGA_CONTEXT MinMaxContext;
FPGA_MINMAX_USER_ST ShadowRegisters;
memset(&ShadowRegisters, 0, sizeof(ShadowRegisters));
MfuncInquire(MilSourceImage, M_BUFFER_INFO, &Src);
if(MfpgaCommandAlloc(MfuncBufOwnerSystemId(Src), M_DEV0, FPGA_MINMAX_FID,
M_DEFAULT, M_DEV0, M_SYNCHRONOUS, M_DEFAULT, &MinMaxContext))
{
FPGAInitializeShadowRegisters(Func, &ShadowRegisters, Src);
MfpgaSetSource(MinMaxContext, Src, M_INPUT0, M_DEFAULT);
MfpgaSetRegister(MinMaxContext, M_USER, 0, sizeof(ShadowRegisters),
(void*)(&ShadowRegisters), M_WHEN_DISPATCHED);
MfpgaGetRegister(MinMaxContext, M_USER, 0, sizeof(ShadowRegisters),
(void*)(&ShadowRegisters), M_WHEN_COMPLETED);
MfpgaCommandQueue(MinMaxContext, M_DEFAULT, M_DEFAULT);
*pMinValue = (MIL_UINT32)ShadowRegisters.min.f.min;
*pMaxValue = (MIL_UINT32)ShadowRegisters.max.f.max;
MfpgaCommandFree(MinMaxContext, M_DEFAULT);
}
else
{
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("No MinMax acceleration supported by this FPGA configuration."),
MIL_TEXT("Please select the proper FPGA configuration file."),
MIL_TEXT("See the processing FPGA section of the milconfig utility."),
M_NULL
);
}
}
void FPGAInitializeShadowRegisters(MIL_ID Func, FPGA_MINMAX_USER_ST* pShadow,
MIL_BUFFER_INFO Buf)
{
MIL_INT BufferType = MfuncBufType(Buf);
pShadow->max.f.max = 0;
pShadow->min.f.min = 0xffffffff;
switch(BufferType)
{
case 8+M_SIGNED:
pShadow->ctrl.f.srctype = 0; break;
case 8+M_UNSIGNED:
pShadow->ctrl.f.srctype = 1; break;
case 16+M_SIGNED:
pShadow->ctrl.f.srctype = 2; break;
case 16+M_UNSIGNED:
pShadow->ctrl.f.srctype = 3; break;
case 32+M_SIGNED:
pShadow->ctrl.f.srctype = 4; break;
case 32+M_UNSIGNED:
pShadow->ctrl.f.srctype = 5; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_PARAMETER_ERROR_CODE,
MIL_TEXT("Invalid source buffer type."),
M_NULL, M_NULL, M_NULL
);
break;
}
if(MfuncBufSizeBand(Buf) == 3)
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_PARAMETER_ERROR_CODE,
MIL_TEXT("Only 1 band buffers are supported."),
M_NULL, M_NULL, M_NULL
);
}
void FPGAMinMax(MIL_ID SrcImageId, MIL_UINT32* pMinValue, MIL_UINT32* pMaxValue)
{
MIL_ID Func;
MfuncAlloc(MIL_TEXT("FPGAMinMax"),
FUNCTION_NB_PARAM,
FPGAMinMaxSlave, M_NULL, M_NULL,
M_USER_MODULE_1+FUNCTION_OPCODE_FPGA_MIN_MAX,
M_DEFAULT,
&Func
);
MfuncParamMilId (Func, 1, SrcImageId, M_IMAGE, M_IN);
MfuncParamDataPointer(Func, 2, pMinValue, sizeof(MIL_UINT32), M_OUT);
MfuncParamDataPointer(Func, 3, pMaxValue, sizeof(MIL_UINT32), M_OUT);
MfuncCall(Func);
MfuncFree(Func);
}
void MFTYPE FPGAMinMaxSlave(MIL_ID Func)
{
MIL_ID SrcImageId;
MIL_UINT32 *pMinValue, *pMaxValue;
MfuncParamValue(Func, 1, &SrcImageId);
MfuncParamValue(Func, 2, &pMinValue);
MfuncParamValue(Func, 3, &pMaxValue);
FPGAMinMaxPrimitive(Func, SrcImageId, pMinValue, pMaxValue);
}