2009008_ja-JP

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2009008_ja-JP

2009008_ja-JP

RT1176でのFlexIOを使用したパラレルカメラ機能の実装
 
RT1176に2台のカメラを統合する準備をしています。
 
現在、1台のカメラがCSIインターフェースで正常に動作しています。
 
追加カメラについては、FLEXIO2を使用して16ビットパラレルカメラデータを受信する機能の実装に取り組んでいます。
 
AN12686 と flexio_camera_rt1010 GitHub リポジトリを参照して、16 ビット データの受信を試みました。
 
DMA コールバックがトリガーされている間、受信したデータが正しくないように見えます。
 
HSYNCおよびPCLK(24MHz)信号は正しく受信されています。
 
どのような追加設定が必要になるかについてのガイダンスをいただければ幸いです。
 
添付されている関連コードを見つけてください。あなたの援助を大いに歓迎するでしょう。
 
よろしくお願いいたします。
 
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 !(定義(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) & FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* フレキシオクロックをアンゲートします。*/
CLOCK_EnableClock(s_flexioClocks[FLEXIO_CAMERA_GetInstance(ベース)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
 
    flexio_shifter_config_t shifterConfig;
    flexio_timer_config_t timerConfig;
 
/* shifterConfig と timerConfig 構造体をクリアします。*/
    (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
    (void)memset(&timerConfig, 0, sizeof(timerConfig));
 
/* フレキシオカメラの設定 */
    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シフター設定 */
shifterConfig.timerSelect = base->timerIdx;
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
    shifterConfig.pinConfig     = kFLEXIO_PinConfigOutputDisabled;
shifterConfig.pinSelect = base->datPinStartIdx;
shifterConfig.pin極性 = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
shifterConfig.parallelWidth = 16 - 1U;
    shifterConfig.inputSource   = kFLEXIO_ShifterInputFromNextShifterOutput;
    shifterConfig.shifterStop   = kFLEXIO_ShifterStopBitDisable;
    shifterConfig.shifterStart  = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
/* シフターを FIFO バッファーとして構成します。*/
    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、PCLKのclkはシフターを駆動するタイマーのソースであり、HREFは選択です
*利用可能なデータの信号。*/
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);
/* フラグをクリアします。*/
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)
{
ビジー = true;
 
flexio_camera_transfer_t cameraTransfer;
cameraTransfer.dataAddress = (uint32_t)pDest;
cameraTransfer.dataNum = g_width * g_height * sizeof(uint16_t) * numFrames;
 
フレームカウンター = 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);
/* 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);
 
/* 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);
 
/* すべてのフラグをクリアします。*/
FLEXIO_CAMERA_ClearStatusFlags(&g_FlexioCameraDevice, kFLEXIO_CAMERA_RxDataRegFullFlag | kFLEXIO_CAMERA_RxErrorFlag);
FLEXIO_ClearTimerStatusFlags(FLEXIO2, 0xFF);
 
/* FlexIO を有効にします。*/
FLEXIO_CAMERA_Enable(&g_FlexioCameraDevice, true);
 
int32_tステータス = FLEXIO_CAMERA_TransferCreateHandleEDMA(&g_FlexioCameraDevice, &g_cameraEdmaHandle, FLEXIO_CAMERA_UserCallback, NULL, &g_edmaHandle);
 
PRINTF(">>>> end InitparallelCamera() status = %d\r\n", status);
}
 
Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

HSYNC中に受信されたバイトは幅x4バイトでした。

受信したフレームに問題が発生し、flexio が 32 バイトすべてを受信しませんでした。

いつもありがとうございます。


BR,
seobi

Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

問題について詳しく説明しましょう。

316x240の解像度でも、FlexIOやDMAを使用せずにピクセルを直接描画すると、ディスプレイは正常に機能します。

ただし、FlexIOおよびDMAを介して受信したピクセルを使用すると、ディスプレイが破損する可能性があります。

16ビットモードであり、320x240は正常に動作します。312x240も正常に動作します(8の倍数)。

ただし、316x240 と 308x240 の解像度 (4 の倍数) では問題が発生します。

FlexIO および DMA を介して受信したフレーム サイズが影響を受けています。

なぜこの問題が発生しますか?


BR,
seobi

Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

Hi @seobi,

これは、画面のバッファのバイト サイズの性質によるものです。これらはバイトサイズであり、それぞれに8ビットが含まれていることを意味します。

Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

フレクシオ経由でDMAを受信すると、320x240ピクセルのフレームが正常に受信されます。(16ビットモード)

ただし、316x240ピクセルは異常に受信されます。そして、312x240ピクセルが再び正常に受信されます。

8の倍数である水平値は正常に受信されますが、4の倍数は異常に受信されます(フレームが壊れます)。

DMAは32バイトを基準に伝送され、フレキシオは8つのシフターを使用します。

なぜ8の倍数しかないのか教えていただけますか?

seobi_0-1737333312038.pngseobi_0-1737333312038.png

BR.
seobi

Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

下の写真でわかるように、フレキシオが1番目のピクセルを見逃すと、その行の32番目のピクセルごとに壊れます。

shift_pixel.PNGshift_pixel.PNG


フレキシオはHSYNCのリギングエッジから始まり、kFLEXIO_PinActiveLowが設定されているので、リセットするのに十分な時間だと思いました。

pclk.PNGpclk.PNG

フレキシオのタイマーのタイミングに問題はありませんか?

私はあなたの助けを待っています。



Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

このプロジェクトでは、flexioで使用されているedmaを1つだけ使用しています。

私はedmaがデフォルトの最大帯域幅を持っていることを知っています。

適切な速度を得るためには、何を変更すればよいですか?

Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

Hi @seobi,

DMAがFlexIOカメラの120MHzに従って適切な速度で実行されていることを確認し、31ビット目と32ビットを処理するのに十分な時間を確保します。


Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

RT1176 の FlexIO2 のルート クロックは、最初は 24MHz に設定されていました。

ルートクロックを120MHzに置き換えた後、通常は16ビットを受信するようになりました。

しかし、下の写真のように、問題があります。

ピクセルをカウントすると、31,32番目のバイトは異常に見えます。

FLEXIO_CAMERA_TransferReceiveEDMA() 関数の DMA 設定は、一度に 32 バイトを処理するように設定されています。これは関連していますか?

ご助言をお待ちしております。

grayscale.PNGgrayscale.PNG

Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

下図の黄色の波形は、FLEXIO_CAMERA_TransferReceiveEDMA(&g_FlexioCameraDevice, &g_cameraEdmaHandle, &cameraTransfer) が呼び出され、User Callback が呼び出されたタイミングを表しています。

緑色の波形はHSYNC受信のタイミングを示しています。

FlexIO2を使用して16ビットパラレルカメラからデータを受信する場合、HSYNCがトリガーとして機能することを理解しました。

しかし、実際の波形を観察すると、FLEXIO_CAMERA_TransferReceiveEDMA()が呼び出されるとすぐにデータが蓄積され始めることに気づきました。

指定された量のデータを受信すると、すぐにユーザーコールバックが呼び出されます。

興味深いことに、2番目の黄色の波形は、HSYNCがトリガされる前でも表示されます。

「timerConfig.triggerPolarity」に基づくHSYNCのHigh期間中のみDMAでデータを受信するように設計された構造ではありませんか?= kFLEXIO_TimerTriggerPolarityActiveHigh"?

HSYNC期間中のみデータを受信する正しい方法は何ですか?

私はどうしてもあなたの助けが必要です。

seobi_0-1733894052956.pngseobi_0-1733894052956.png


Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

私のカメラは13ビットパラレルカメラです。

FlexIO2ピン1から16までのデータラインを、PCLK、VSYNC、およびHSYNCとともに順番に使用しました。

さらに、未使用の 16 ビットの最後の 3 ビットは未接続のままです。

これ以上のハードウェア操作は必要ないようです。

データを読み取るときは、特定の垂直線のみが読み取られます。

添付のソースコードに16ビット処理の問題がないか確認していただけますか?

シフターとタイマーの設定が疑われているのですが、あまり情報がありません...

私はどうしてもあなたの助けが必要です。


seobi_0-1733797756913.pngseobi_0-1733797756913.png


Re: RT1176でのFlexIOを使用したパラレルカメラ機能の実装

Hi @seobi,

FlexIO側ではどのカメラを使用していますか?GitHub で説明されている広範な HW 構成 (nxp-appcodehub/an-flexio_camera_rt1010) をミラーリングしたと確信していますか?

BR,
Edwin.

Tags (1)
No ratings
Version history
Last update:
‎01-06-2026 01:18 AM
Updated by: