We are preparing to integrate two cameras with the RT1176.
Currently, one camera is successfully operating with the CSI interface.
For the additional camera, we are working on implementing the functionality to receive 16-bit parallel camera data using FLEXIO2.
Referring to AN12686 and the an-flexio_camera_rt1010 GitHub repository, we attempted to receive 16-bit data.
While the DMA callback is triggered, the received data appears to be incorrect.
The HSYNC and PCLK (24MHz) signals are being received correctly.
We would appreciate guidance on what additional configurations might be required.
Please find the relevant code attached. Your assistance would be greatly appreciated.
Best regards,
void FLEXIO_CAMERA_Init(FLEXIO_CAMERA_Type *base, const flexio_camera_config_t *config)
{
assert((base != NULL) && (config != NULL));
assert(base->shifterCount > 0U);
uint32_t i = 0U;
volatile uint32_t controlVal = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate flexio clock. */
CLOCK_EnableClock(s_flexioClocks[FLEXIO_CAMERA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
flexio_shifter_config_t shifterConfig;
flexio_timer_config_t timerConfig;
/* Clear the shifterConfig & timerConfig struct. */
(void)memset(&shifterConfig, 0, sizeof(shifterConfig));
(void)memset(&timerConfig, 0, sizeof(timerConfig));
/* Configure flexio camera */
controlVal = base->flexioBase->CTRL;
controlVal &=
~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
controlVal |= (FLEXIO_CTRL_DBGE(config->enableInDebug) | FLEXIO_CTRL_FASTACC(config->enableFastAccess) |
FLEXIO_CTRL_FLEXEN(config->enablecamera));
if (!config->enableInDoze)
{
controlVal |= FLEXIO_CTRL_DOZEN_MASK;
}
base->flexioBase->CTRL = controlVal;
/* FLEXIO_CAMERA shifter config */
shifterConfig.timerSelect = base->timerIdx;
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
shifterConfig.pinSelect = base->datPinStartIdx;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
shifterConfig.parallelWidth = 16 - 1U;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromNextShifterOutput;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
/* Configure the shifters as FIFO buffer. */
for (i = base->shifterStartIdx; i < (base->shifterStartIdx + base->shifterCount - 1U); i++)
{
FLEXIO_SetShifterConfig(base->flexioBase, (uint8_t)i, &shifterConfig);
}
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
FLEXIO_SetShifterConfig(base->flexioBase, (uint8_t)i, &shifterConfig);
/* FLEXIO_CAMERA timer config, the PCLK's clk is source of timer to drive the shifter, the HREF is the selecting
* signal for available data. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->hrefPinIdx);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
timerConfig.pinSelect = base->pclkPinIdx;
timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
timerConfig.timerReset = kFLEXIO_TimerResetOnTimerTriggerRisingEdge;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge;
timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
#ifdef __CAMERA_DATA_16BIT__
timerConfig.timerCompare = 2*((32*base->shifterCount)/16)-1U;
#else
timerConfig.timerCompare = 8U * base->shifterCount - 1U;
#endif
FLEXIO_SetTimerConfig(base->flexioBase, (uint8_t)base->timerIdx, &timerConfig);
/* Clear flags. */
FLEXIO_ClearShifterErrorFlags(base->flexioBase, (((1UL << (base->shifterCount)) - 1U) << (base->shifterStartIdx)));
FLEXIO_ClearTimerStatusFlags(base->flexioBase, 1UL << (base->timerIdx));
}
int32_t cameraStartFrame(volatile uint8_t *pDest, const uint32_t numFrames)
{
busy = true;
flexio_camera_transfer_t cameraTransfer;
cameraTransfer.dataAddress = (uint32_t)pDest;
cameraTransfer.dataNum = g_width * g_height * sizeof(uint16_t) * numFrames;
frameCounter = 0;
numFramesExpected = numFrames;
FLEXIO_CAMERA_ClearStatusFlags(&g_FlexioCameraDevice, kFLEXIO_CAMERA_RxDataRegFullFlag | kFLEXIO_CAMERA_RxErrorFlag);
g_cameraEdmaHandle.rxState = 0;
FLEXIO_CAMERA_TransferReceiveEDMA(&g_FlexioCameraDevice, &g_cameraEdmaHandle, &cameraTransfer);
return 0;
}
int InitParallelCamera(void)
{
edma_config_t edmaConfig;
flexio_camera_config_t cameraConfig;
CLOCK_EnableClock(kCLOCK_Flexio2);
FLEXIO_Reset(FLEXIO2);
/* Configure DMAMUX */
DMAMUX_Init(DMAMUX0);
// DMAMUX_SetSource(DMAMUX0, FLEXIO_CAMERA_DMA_CHN, FLEXIO_CAMERA_DMA_MUX_SRC);
// DMAMUX_SetSource(DMAMUX0, FLEXIO_CAMERA_DMA_CHN, (g_FlexioCameraDevice.shifterStartIdx + 1U));
DMAMUX_EnableAlwaysOn(DMAMUX0, FLEXIO_CAMERA_DMA_CHN, true);
DMAMUX_EnableChannel(DMAMUX0, FLEXIO_CAMERA_DMA_CHN);
/* Configure DMA */
EDMA_GetDefaultConfig(&edmaConfig);
edmaConfig.enableDebugMode = true;
EDMA_Init(DMA0, &edmaConfig);
EDMA_CreateHandle(&g_edmaHandle, DMA0, FLEXIO_CAMERA_DMA_CHN);
FLEXIO_Reset(FLEXIO2);
FLEXIO_CAMERA_GetDefaultConfig(&cameraConfig);
FLEXIO_CAMERA_Init(&g_FlexioCameraDevice, &cameraConfig);
/* Clear all the flag. */
FLEXIO_CAMERA_ClearStatusFlags(&g_FlexioCameraDevice, kFLEXIO_CAMERA_RxDataRegFullFlag | kFLEXIO_CAMERA_RxErrorFlag);
FLEXIO_ClearTimerStatusFlags(FLEXIO2, 0xFF);
/* Enable FlexIO. */
FLEXIO_CAMERA_Enable(&g_FlexioCameraDevice, true);
int32_t status = FLEXIO_CAMERA_TransferCreateHandleEDMA(&g_FlexioCameraDevice, &g_cameraEdmaHandle, FLEXIO_CAMERA_UserCallback, NULL, &g_edmaHandle);
PRINTF(">>>> end InitparallelCamera() status = %d\r\n", status);
}