#include <mil.h>
#include <milfpga.h>
#include <fpga_gainoffset.h>
#include <fpga_minmax.h>
#include <fpga_splitter.h>
#define FUNCTION_NB_PARAM_OFFSET_GAIN_MIN_MAX 7
#define FUNCTION_OPCODE_FPGA_OFFSET_GAIN_MIN_MAX 7
#define FUNCTION_PARAMETER_ERROR_CODE 1
#define FUNCTION_WRONG_FPGA_ERROR_CODE 2
void FPGAOffsetGainMinMax(MIL_ID SrcImageId, MIL_ID OffsetImageId,
MIL_ID GainImageId, MIL_INT Src4, MIL_ID DstImageId,
MIL_UINT32* pMinValue, MIL_UINT32* pMaxValue);
void MFTYPE FPGAOffsetGainMinMaxSlave(MIL_ID Func);
void FPGAOffsetGainMinMaxPrimitive(MIL_ID Func, MIL_ID MilSourceImage,
MIL_ID MilOffsetImage, MIL_ID MilGainImage, MIL_INT Src4,
MIL_ID MilImageDst, MIL_UINT32* pMinValue, MIL_UINT32* pMaxValue);
void FPGAInitializeShadowRegisters(MIL_ID Func, FPGA_GAINOFFSET_USER_ST* pOGShadow,
FPGA_MINMAX_USER_ST* pMMShadow, FPGA_SPLITTER_USER_ST* pSplitShadow,
MIL_BUFFER_INFO Src1, MIL_BUFFER_INFO Src2, MIL_BUFFER_INFO Src3,
MIL_INT Src4, MIL_BUFFER_INFO Dst);
void FPGAOffsetGainMinMaxPrimitive(MIL_ID Func,
MIL_ID MilSourceImage,
MIL_ID MilOffsetImage,
MIL_ID MilGainImage,
MIL_INT Src4,
MIL_ID MilImageDst,
MIL_UINT32* pMinValue,
MIL_UINT32* pMaxValue)
{
MIL_BUFFER_INFO Src, Offset, Gain, Dst;
MIL_FPGA_CONTEXT OffsetGainContext, MinMaxContext, SplitterContext;
FPGA_GAINOFFSET_USER_ST GOShadow;
FPGA_MINMAX_USER_ST MMShadow;
FPGA_SPLITTER_USER_ST SPltShadow;
memset(&GOShadow, 0, sizeof(GOShadow));
memset(&MMShadow, 0, sizeof(MMShadow));
memset(&SPltShadow, 0, sizeof(SPltShadow));
MfuncInquire(MilSourceImage, M_BUFFER_INFO, &Src);
MfuncInquire(MilOffsetImage, M_BUFFER_INFO, &Offset);
MfuncInquire(MilGainImage, M_BUFFER_INFO, &Gain);
MfuncInquire(MilImageDst, M_BUFFER_INFO, &Dst);
if(MfpgaCommandAlloc(MfuncBufOwnerSystemId(Src), M_DEV0, FPGA_GAINOFFSET_FID,
M_DEFAULT, M_DEV0, M_SYNCHRONOUS, M_DEFAULT, &OffsetGainContext))
{
if(MfpgaCommandAlloc(MfuncBufOwnerSystemId(Src), M_DEV0, FPGA_MINMAX_FID,
M_DEFAULT, M_DEV0, M_SYNCHRONOUS, M_DEFAULT, &MinMaxContext))
{
if(MfpgaCommandAlloc(MfuncBufOwnerSystemId(Src), M_DEV0, FPGA_SPLITTER_FID,
M_DEFAULT, M_DEV0, M_SYNCHRONOUS, M_DEFAULT, &SplitterContext))
{
FPGAInitializeShadowRegisters(Func, &GOShadow, &MMShadow, &SPltShadow,
Src, Offset, Gain, Src4, Dst);
MfpgaSetSource(SplitterContext, Src, M_INPUT0, M_DEFAULT);
MfpgaSetLink(SplitterContext, M_OUTPUT0, OffsetGainContext,
M_INPUT0, M_DEFAULT);
MfpgaSetLink(SplitterContext, M_OUTPUT1, MinMaxContext, M_INPUT0,
M_DEFAULT);
MfpgaSetRegister(SplitterContext, M_USER, 0, sizeof(SPltShadow),
(void*)(&SPltShadow), M_WHEN_DISPATCHED);
MfpgaSetSource(OffsetGainContext, Offset, M_INPUT1, M_DEFAULT);
MfpgaSetSource(OffsetGainContext, Gain, M_INPUT2, M_DEFAULT);
MfpgaSetDestination(OffsetGainContext, Dst, M_OUTPUT0, M_DEFAULT);
MfpgaSetRegister(OffsetGainContext, M_USER, 0, sizeof(GOShadow),
(void*)(&GOShadow), M_WHEN_DISPATCHED);
MfpgaSetRegister(MinMaxContext, M_USER, 0, sizeof(MMShadow),
(void*)(&MMShadow), M_WHEN_DISPATCHED);
MfpgaGetRegister(MinMaxContext, M_USER, 0, sizeof(MMShadow),
(void*)(&MMShadow), M_WHEN_COMPLETED);
MfpgaCommandQueue(OffsetGainContext,M_DEFAULT, M_WAIT);
MfpgaCommandQueue(MinMaxContext, M_DEFAULT, M_WAIT);
MfpgaCommandQueue(SplitterContext, M_DEFAULT, M_DEFAULT);
*pMinValue = (MIL_UINT32)MMShadow.min.f.min;
*pMaxValue = (MIL_UINT32)MMShadow.max.f.max;
MfpgaCommandFree(OffsetGainContext, M_DEFAULT);
MfpgaCommandFree(MinMaxContext, M_DEFAULT);
MfpgaCommandFree(SplitterContext, M_DEFAULT);
}
else
{
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("No Splitter 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
);
}
}
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
);
}
}
else
{
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("No Gain&Offset 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_GAINOFFSET_USER_ST* pOGShadow,
FPGA_MINMAX_USER_ST* pMMShadow,
FPGA_SPLITTER_USER_ST* pSplitShadow,
MIL_BUFFER_INFO Src1,
MIL_BUFFER_INFO Src2,
MIL_BUFFER_INFO Src3,
MIL_INT Src4,
MIL_BUFFER_INFO Dst)
{
MIL_UINT lMaxValue, Src1Type, Src2Type, Src3Type, DstType, i, j;
lMaxValue = (MIL_UINT)MfuncBufMaxValue(Src1);
Src1Type = MfuncBufType(Src1);
Src2Type = MfuncBufType(Src2);
Src3Type = MfuncBufType(Src3);
DstType = MfuncBufType(Dst);
switch(Src1Type)
{
case 8+M_UNSIGNED:
pOGShadow->ctrl.f.srctype = 0x1; break;
case 16+M_UNSIGNED:
pOGShadow->ctrl.f.srctype = 0x3; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("Invalid source buffer type."),
M_NULL, M_NULL, M_NULL
);
break;
}
switch(Src2Type)
{
case 8+M_UNSIGNED:
pOGShadow->ctrl.f.offtype = 0x1; break;
case 16+M_UNSIGNED:
pOGShadow->ctrl.f.offtype = 0x3; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("Invalid offset buffer type."),
M_NULL, M_NULL, M_NULL
);
break;
}
switch(Src3Type)
{
case 8+M_UNSIGNED:
pOGShadow->ctrl.f.gaintype = 0x1; break;
case 16+M_UNSIGNED:
pOGShadow->ctrl.f.gaintype = 0x3; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("Invalid gain buffer type."),
M_NULL, M_NULL, M_NULL
);
break;
}
switch(DstType)
{
case 8+M_UNSIGNED:
pOGShadow->ctrl.f.dsttype = 0x1; break;
case 16+M_UNSIGNED:
pOGShadow->ctrl.f.dsttype = 0x3; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("Invalid destination buffer type."),
M_NULL, M_NULL, M_NULL
);
break;
}
pOGShadow->clipval.f.clipval = lMaxValue;
j=1;
for(i=0; i<32; i++)
{
if(Src4 & j)
{
pOGShadow->ctrl.f.shift = i;
break;
}
j <<= 1;
}
pMMShadow->max.f.max = 0;
pMMShadow->min.f.min = 0xffffffff;
switch(Src1Type)
{
case 8+M_SIGNED:
pMMShadow->ctrl.f.srctype = 0; break;
case 8+M_UNSIGNED:
pMMShadow->ctrl.f.srctype = 1; break;
case 16+M_SIGNED:
pMMShadow->ctrl.f.srctype = 2; break;
case 16+M_UNSIGNED:
pMMShadow->ctrl.f.srctype = 3; break;
case 32+M_SIGNED:
pMMShadow->ctrl.f.srctype = 4; break;
case 32+M_UNSIGNED:
pMMShadow->ctrl.f.srctype = 5; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("Invalid source buffer type."),
M_NULL, M_NULL, M_NULL
);
break;
}
pSplitShadow->ctrl.f.outen = 0x3;
}
void FPGAOffsetGainMinMax(MIL_ID SrcImageId, MIL_ID OffsetImageId,
MIL_ID GainImageId, MIL_INT Src4, MIL_ID DstImageId,
MIL_UINT32* pMinValue, MIL_UINT32* pMaxValue)
{
MIL_ID Func;
MfuncAlloc(MIL_TEXT("FPGAOffsetGainMinMax"),
FUNCTION_NB_PARAM_OFFSET_GAIN_MIN_MAX,
FPGAOffsetGainMinMaxSlave, M_NULL, M_NULL,
M_USER_MODULE_1+FUNCTION_OPCODE_FPGA_OFFSET_GAIN_MIN_MAX,
M_DEFAULT,
&Func
);
MfuncParamMilId (Func, 1, SrcImageId, M_IMAGE, M_IN);
MfuncParamMilId (Func, 2, OffsetImageId, M_IMAGE, M_IN);
MfuncParamMilId (Func, 3, GainImageId, M_IMAGE, M_IN);
MfuncParamMilInt (Func, 4, Src4);
MfuncParamMilId (Func, 5, DstImageId, M_IMAGE, M_OUT);
MfuncParamDataPointer(Func, 6, pMinValue, sizeof(MIL_UINT32), M_OUT);
MfuncParamDataPointer(Func, 7, pMaxValue, sizeof(MIL_UINT32), M_OUT);
MfuncCall(Func);
MfuncFree(Func);
}
void MFTYPE FPGAOffsetGainMinMaxSlave(MIL_ID Func)
{
MIL_ID SrcImageId, OffsetImageId, GainImageId, DstImageId;
MIL_INT Src4;
MIL_UINT32 *pMinValue, *pMaxValue;
MfuncParamValue(Func, 1, &SrcImageId);
MfuncParamValue(Func, 2, &OffsetImageId);
MfuncParamValue(Func, 3, &GainImageId);
MfuncParamValue(Func, 4, &Src4);
MfuncParamValue(Func, 5, &DstImageId);
MfuncParamValue(Func, 6, &pMinValue);
MfuncParamValue(Func, 7, &pMaxValue);
FPGAOffsetGainMinMaxPrimitive(Func, SrcImageId, OffsetImageId,
GainImageId, Src4, DstImageId, pMinValue, pMaxValue);
}