C
Qt Quick Ultralite imagedecoder Example
/****************************************************************************** ** ** Copyright (C) 2024 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Ultralite module. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ******************************************************************************/ #include "cy_project.h" #include "cyjpg_def.h" #include "cyjpg_basetypes.h" #include "cyjpg_typedef.h" #include "cyjpg.h" #include <cygfx_driver_api.h> #include <cygfx_basetypes.h> #include <sm_util.h> #include <platforminterface/printf.h> // #define TVII_DEBUG_JPEG_DECODER // Fetch/store buffer information #define FETCH_BUF_START_ADDR 0x28028000U #define FETCH_BUF_LENGTH 0x70000U #define STORE_BUF0_START_ADDR 0x243a0000 #define STORE_BUF0_LENGTH 0x60000U #define STORE_BUF1_START_ADDR 0x24340000 #define STORE_BUF1_LENGTH 0x60000U /* Subsample type */ // CYJPG_YUV444 (CYJPG_U32) 0 // CYJPG_YUV422 (CYJPG_U32) 1 // CYJPG_YUV411 (CYJPG_U32) 6 // CYJPG_YUV420 (CYJPG_U32) 2 // CYJPG_GRAYSCALE (CYJPG_U32) 3 // CYJPG_CMYK (CYJPG_U32) 4 // CYJPG_INVALID (CYJPG_U32) 7 /* Call Sample Application function if the previous operation did not fail. */ #define CALL_APPL_FUNC(ret_appl, execute) \ do { \ if ((ret_appl) == RES_DEC_SUCCESS) { \ (ret_appl) = (execute); \ } \ } while (0) /* Call JPEG Deocde Driver function if the previous operation did not fail. */ #define CALL_JPGDRV_FUNC(ret_appl, ret_drv, execute) \ do { \ if ((ret_appl) == RES_DEC_SUCCESS) { \ (ret_drv) = (execute); \ if ((ret_drv) != CYJPG_OK) { \ (ret_appl) = RES_DEC_FAILED_DRIVER; \ } \ } \ } while (0) /* AXI bus configuration */ CYJPG_AXICTL_S axi_config; /* IRQ configuration */ CYJPG_IRQCTL_S irq_config; /* JPEG Decode Core Configuration */ CYJPG_DECODEINFO_S dec_core_config; /* JPEG Decode Configuration */ CYJPG_JPGINFO_S jpg_config; /* Configuration for JPEG Driver initialization */ CYJPG_INIT_S init_config; /* IRQ Configuration for JPEGDEC */ CYJPG_STATIC const cy_stc_sysint_irq_t irq_cfg_jpeg = {.sysIntSrc = jpegdec_interrupt_jpeg_IRQn, //156 .intIdx = CPUIntIdx3_IRQn, .isEnabled = true}; static void jpeg_configuration_init(void) { /* AXI bus configuration */ axi_config.arcache = 0U; /* ARCACHE value of AXI transactions on Fetch Unit */ axi_config.awcache = 0U; /* AWCACHE value of AXI transactions on Store Unit */ axi_config.fetchburstlength = 0U; /* Maximum burst length for Fetch Unit */ axi_config.storeburstlength = 0U; /* Maximum burst length for Store Unit */ /* IRQ configuration */ irq_config.decodeintrmask = CYJPG_ENABLE; /* Masks assertion of INTR.CORE due to decoding completion */ irq_config.frameCompleteClear = CYJPG_DISABLE; /* Clear INTR.FRAME_COMPLETE */ irq_config.jpegCoreClear = CYJPG_DISABLE; /* Clear INTR.JPEG_CORE */ irq_config.fetchErrorClear = CYJPG_DISABLE; /* Clear INTR.FETCH_ERROR */ irq_config.storeErrorClear = CYJPG_DISABLE; /* Clear INTR.STORE_ERROR */ irq_config.frameCompleteMask = CYJPG_ENABLE; /* Interrupt mask for FRAME_COMPLETE */ irq_config.jpegCoreMask = CYJPG_ENABLE; /* Interrupt mask for JPEG_CORE */ irq_config.fetchErrorMask = CYJPG_ENABLE; /* Interrupt mask for FETCH_ERROR */ irq_config.storeErrorMask = CYJPG_ENABLE; /* Interrupt mask for STORE_ERROR */ irq_config.appMarkerEn = CYJPG_ENABLE; /* Interrupt Setting for INTR_DEC_EN.APPMARKER */ irq_config.comMarkerEn = CYJPG_ENABLE; /* Interrupt Setting for INTR_DEC_EN.COMMARKER */ irq_config.unknownMarkerEn = CYJPG_ENABLE; /* Interrupt Setting for INTR_DEC_EN.UNKNOWNMARKER */ irq_config.sizeAvailableEn = CYJPG_ENABLE; /* Interrupt Setting for INTR_DEC_EN.SIZEAVAILABLE */ irq_config.errorIntervalEn = CYJPG_DISABLE; /* Interrupt Setting for INTR_DEC_EN.ERRORINTERVAL */ irq_config.errorTotalDataEn = CYJPG_DISABLE; /* Interrupt Setting for INTR_DEC_EN.ERRORTOTALDATA */ irq_config.intMaskEn = CYJPG_DISABLE; /* Interrupt Setting for INTR_DEC_EN.INTMASK */ /* JPEG Decode Core Configuration */ dec_core_config.subsample = 0U; /* Sub-sampling mode defined in SOF marker segment */ dec_core_config.dri = 0U; /* Value downloaded from DRI marker segment */ dec_core_config.sizey = 0U; /* Y size value downloaded from SOF marker segment */ dec_core_config.sizex = 0U; /* X size value downloaded from SOF marker segment */ dec_core_config.cropstarty = 0U; /* Y crop start position */ dec_core_config.cropstartx = 0U; /* X crop start position */ dec_core_config.cropsizey = 0U; /* Crop size for Y direction */ dec_core_config.cropsizex = 0U; /* Crop size for X direction */ /* JPEG Decode Configuration */ jpg_config.fetchAddress = FETCH_BUF_START_ADDR; /* Start address of the JPEG image in bytes */ jpg_config.fetchLength = FETCH_BUF_LENGTH; /* JPEG image length in bytes */ jpg_config.storeAddress0 = STORE_BUF0_START_ADDR; /* Start address of the destination buffer 0 in multiple of 64 bytes */ jpg_config.storeStride0 = 0; /* Line stride of the destination buffer 0 in multiple of 64 bytes */ jpg_config.storeLength0 = STORE_BUF0_LENGTH; /* Destination buffer 0 length in multiple of 64 bytes */ jpg_config.storeAddress1 = STORE_BUF1_START_ADDR; /* Start address of the destination buffer 1 in multiple of 64 bytes */ jpg_config.storeStride1 = 0; /* Line stride of the destination buffer 1 in multiple of 64 bytes */ jpg_config.storeLength1 = STORE_BUF1_LENGTH; /* Destination buffer 1 length in multiple of 64 bytes */ jpg_config.upsamplingEn = CYJPG_DISABLE; /* Decoded pixels are up-sampled to YUV 4:4:4 */ jpg_config.markerskipEn = CYJPG_DISABLE; /* Enable/Disable Marker Skip Function */ jpg_config.cropEn = CYJPG_DISABLE; /* Enable/Disable Crop Function */ jpg_config.correctionEn = CYJPG_DISABLE; /* Enable/Disable Correction Function */ jpg_config.decodeinfo_s = &dec_core_config; /* Pointer to JPEG Decode Core Configuration */ /* JPEG Initial Configuration */ init_config.axictl_s = &axi_config; init_config.irqctl_s = &irq_config; init_config.jpginfo_s = &jpg_config; } /*****************************************************************************/ /* Macro Definitions */ /*****************************************************************************/ /* Result of Decoding APIs */ #define RES_DEC_SUCCESS 0x0U /* Success */ #define RES_DEC_FAILED_DRIVER 0x101U /* JPEG Driver API failed */ #define RES_DEC_FAILED_ILLEGAL_STATE 0x102U /* Illegal state error */ #define RES_DEC_FAILED_TIMEOUT_AXI 0x103U /* Timeout of AXI inactive timer */ #define RES_DEC_FAILED_CROPAREALIST 0x104U /* Crop areas include errors */ #define RES_DEC_FAILED_ABNORMAL 0x1FFU /* Abnormal error */ /*****************************************************************************/ /* Type Definitions */ /*****************************************************************************/ /* Decode State */ typedef enum { DEC_STATE_DISABLED = 0, /* Disabled */ DEC_STATE_CONFIG = 1, /* Configuration */ DEC_STATE_DECODING = 2, /* Decoding */ DEC_STATE_SUSPENDED = 3, /* Suspended */ DEC_STATE_SUSPENDED_SIZEAVAIL = 4, /* Suspended (SIZEAVAILABLE) */ DEC_STATE_COMPLETED = 5, /* Completed */ DEC_STATE_RECOVERY = 6 /* Recovery */ } JPG_SAMPLE_DEC_STATE_E; /* Recovery Cause */ typedef enum { DEC_RCV_CAUSE_NOTHING = 0, /* No cause */ DEC_RCV_CAUSE_CANCEL = 1, /* Cancel on-going decoding */ DEC_RCV_CAUSE_FETCH_STORE_ERR = 2, /* Fetch/Store Error */ DEC_RCV_CAUSE_INTR_DEC_ERR = 3, /* INTR_DEC Error */ DEC_RCV_CAUSE_NO_NORMAL_CORRECTED = 4, /* NORMALEND/CORRECTEDEND not generated */ DEC_RCV_CAUSE_UNDEFINED_STATE = 5, /* Undefined State */ } JPG_SAMPLE_DEC_RCV_CAUSE_E; /*****************************************************************************/ /* Local Variables/Constants */ /*****************************************************************************/ CYJPG_STATIC JPG_SAMPLE_DEC_STATE_E decode_state = DEC_STATE_DISABLED; /* Decode State */ CYJPG_STATIC JPG_SAMPLE_DEC_RCV_CAUSE_E recovery_cause = DEC_RCV_CAUSE_NOTHING; /* Recovery Cause */ CYJPG_STATIC CYJPG_BOOL first_dec_comp = CYJPG_FALSE; /* First decode completion */ CYJPG_STATIC CYJPG_BOOL gen_normal_corrected = CYJPG_FALSE; /* NORMALEND/CORRECTEDEND generated Flag */ /** \brief Update Decode State ** \param upd_state [in] Decode state to be updated ** \return result ** RES_DEC_SUCCESS: Success ** RES_DEC_FAILED_ILLEGAL_STATE: Illegal state error ** RES_DEC_FAILED_ABNORMAL: Abnormal error ** ** No remarks ** */ CYJPG_U32 Jpeg_DecUpdateState(JPG_SAMPLE_DEC_STATE_E upd_state) { /* Local variables */ CYJPG_U32 ret = RES_DEC_SUCCESS; /* Check current decode state */ switch (decode_state) { case DEC_STATE_DISABLED: { if (upd_state == DEC_STATE_CONFIG) { /* Update decode state */ decode_state = upd_state; } else { /* Illegal state transition */ ret = RES_DEC_FAILED_ILLEGAL_STATE; } break; } case DEC_STATE_CONFIG: { if ((upd_state == DEC_STATE_DECODING) || (upd_state == DEC_STATE_DISABLED)) { decode_state = upd_state; } else { ret = RES_DEC_FAILED_ILLEGAL_STATE; } break; } case DEC_STATE_DECODING: { if ((upd_state == DEC_STATE_SUSPENDED) || (upd_state == DEC_STATE_SUSPENDED_SIZEAVAIL) || (upd_state == DEC_STATE_COMPLETED) || (upd_state == DEC_STATE_RECOVERY) || (upd_state == DEC_STATE_DISABLED)) { decode_state = upd_state; } else { ret = RES_DEC_FAILED_ILLEGAL_STATE; } break; } case DEC_STATE_SUSPENDED: case DEC_STATE_SUSPENDED_SIZEAVAIL: { if ((upd_state == DEC_STATE_DECODING) || (upd_state == DEC_STATE_RECOVERY) || (upd_state == DEC_STATE_DISABLED)) { decode_state = upd_state; } else { ret = RES_DEC_FAILED_ILLEGAL_STATE; } break; } case DEC_STATE_COMPLETED: { if ((upd_state == DEC_STATE_CONFIG) || (upd_state == DEC_STATE_RECOVERY) || (upd_state == DEC_STATE_DISABLED)) { decode_state = upd_state; } else { ret = RES_DEC_FAILED_ILLEGAL_STATE; } break; } case DEC_STATE_RECOVERY: { if ((upd_state == DEC_STATE_CONFIG) || (upd_state == DEC_STATE_DISABLED)) { decode_state = upd_state; } else { ret = RES_DEC_FAILED_ILLEGAL_STATE; } break; } default: { ret = RES_DEC_FAILED_ABNORMAL; break; } } return ret; } /** \brief Notify NORMALEND/CORRECTEDEND is generated ** \param gen_normal [in] NORMALEND/CORRECTEDEND is generated or not ** \return void ** ** No remarks ** */ void Jpeg_DecNotifyNormalCorrected(CYJPG_BOOL gen_flag) { /* Set NORMALEND/CORRECTEDEND generated flag */ gen_normal_corrected = gen_flag; return; } /** \brief Notify cause of recovery ** \param rcv_cause [in] cause of recovery ** \return void ** ** No remarks ** */ void Jpeg_DecNotifyRcvCause(JPG_SAMPLE_DEC_RCV_CAUSE_E rcv_cause) { /* Set recovery cause */ recovery_cause = rcv_cause; return; } /*****************************************************************************/ /* Local Functions */ /*****************************************************************************/ /** \brief JPEG Decoder Core Interrupt ** \param No param ** \return void ** ** No remarks ** */ CYJPG_STATIC void Jpeg_kInterruptJpegDecoderCore(CYJPG_IRQSTATUS_S *irq_status) { /* Clear IRQ causes of INTR and INTR_DEC */ (void) CyJpg_ClearJpegCoreIrq(); /* Crop Size/MCU Unit Error occurs */ if ((irq_status->sizeAvailable == CYJPG_TRUE) && ((irq_status->cropSizeError == CYJPG_TRUE) || (irq_status->mcuUnitError == CYJPG_TRUE))) { /* Change state to Recovery */ (void) Jpeg_DecUpdateState(DEC_STATE_RECOVERY); /* Notify recovery cause as undefined status */ Jpeg_DecNotifyRcvCause(DEC_RCV_CAUSE_UNDEFINED_STATE); } /* Error interval/Error Total Data/Error marker occurs */ else if ((irq_status->errorInterval == CYJPG_TRUE) || (irq_status->errorTotalData == CYJPG_TRUE) || (irq_status->errorMarker == CYJPG_TRUE)) { /* Change state to Recovery */ (void) Jpeg_DecUpdateState(DEC_STATE_RECOVERY); /* Notify recovery cause as INTR_DEC error */ Jpeg_DecNotifyRcvCause(DEC_RCV_CAUSE_INTR_DEC_ERR); } /* JPEG image size is available */ else if (irq_status->sizeAvailable == CYJPG_TRUE) { /* Change state to Suspended (SIZEAVAILBLE) */ (void) Jpeg_DecUpdateState(DEC_STATE_SUSPENDED_SIZEAVAIL); } /* APP/COM/Unknown Marker is detected or JPEG image size is available */ else if ((irq_status->appMarker == CYJPG_TRUE) || (irq_status->comMarker == CYJPG_TRUE) || (irq_status->unknownMarker == CYJPG_TRUE)) { /* Change state to Suspended */ (void) Jpeg_DecUpdateState(DEC_STATE_SUSPENDED); } else { } /* JPEG decoder core has finished normally */ if ((irq_status->normalEnd == CYJPG_TRUE) || (irq_status->correctedEnd == CYJPG_TRUE)) { /* Notify NORMALEND/CORRECTEDEND generated */ Jpeg_DecNotifyNormalCorrected(CYJPG_TRUE); } return; } /** \brief Pixel Data Store Completion Interrupt ** \param irq_state [in] IRQ status ** \return void ** ** No remarks ** */ CYJPG_STATIC void Jpeg_kInterruptPixelDataStoreComp(CYJPG_IRQSTATUS_S *irq_status) { /* Clear IRQ cause of Pixel Data Store Completion Interrupt */ (void) CyJpg_ClearFrameCompIrq(); /* Change state to Completed */ (void) Jpeg_DecUpdateState(DEC_STATE_COMPLETED); if ((irq_status->normalEnd == CYJPG_TRUE) || (irq_status->correctedEnd == CYJPG_TRUE)) { /* Notify NORMALEND/CORRECTEDEND generated */ Jpeg_DecNotifyNormalCorrected(CYJPG_TRUE); } return; } /** \brief Fetch Unit Error Interrupt ** \param No param ** \return void ** ** No remarks ** */ CYJPG_STATIC void Jpeg_kInterruptFetchUnitError(void) { /* Clear IRQ cause of Fetch Unit Error Interrupt */ (void) CyJpg_SetErrorInfo(CYJPG_FETCH_ERROR); /* Change state to Recovery */ (void) Jpeg_DecUpdateState(DEC_STATE_RECOVERY); /* Notify recovery cause as Fetch/Store error */ Jpeg_DecNotifyRcvCause(DEC_RCV_CAUSE_FETCH_STORE_ERR); return; } /** \brief Store Unit Error Interrupt ** \param No param ** \return void ** ** No remarks ** */ CYJPG_STATIC void Jpeg_kInterruptStoreUnitError(void) { /* Clear IRQ cause of Store Unit Error Interrupt */ (void) CyJpg_SetErrorInfo(CYJPG_STORE_ERROR); /* Change state to Recovery */ (void) Jpeg_DecUpdateState(DEC_STATE_RECOVERY); /* Notify recovery cause as Fetch/Store error */ Jpeg_DecNotifyRcvCause(DEC_RCV_CAUSE_FETCH_STORE_ERR); return; } // JPEGDEC interrupt handler static void Jpeg_InterruptHandler(void) { /* Local variables */ CYJPG_IRQSTATUS_S irq_status; /* JPEG Decoder IRQ Status */ /* Get IRQ cause */ (void) CyJpg_GetJpgIrqCause(&irq_status); /* Fetch Unit Error Interrupt */ if (irq_status.intrFetchError == CYJPG_TRUE) { Jpeg_kInterruptFetchUnitError(); } /* Store Unit Error Interrupt */ if (irq_status.intrStoreError == CYJPG_TRUE) { Jpeg_kInterruptStoreUnitError(); } /* JPEG Decoder Core Interrupt */ if (irq_status.intrJpegCore == CYJPG_TRUE) { Jpeg_kInterruptJpegDecoderCore(&irq_status); } /* Pixel Data Store Completion Interrupt */ if (irq_status.intrFrameComplete == CYJPG_TRUE) { Jpeg_kInterruptPixelDataStoreComp(&irq_status); } return; } static CYGFX_BE_CONTEXT_OBJECT_S ctx; // drawing context for Blit Engine static CYGFX_SURFACE_OBJECT_S surfSrc; // source surface static CYGFX_SURFACE_OBJECT_S surfDst; // destination surface uint32_t tvii_convert_decoded_buffers(unsigned char *outbuffer, uint32_t width, uint32_t height, CYGFX_SM_FORMAT dst_format) { uint32_t ret_gfx = 0; UTIL_SUCCESS(ret_gfx, CyGfx_BeResetContext(&ctx)); UTIL_SUCCESS(ret_gfx, CyGfx_SmResetSurfaceObject(&surfSrc)); UTIL_SUCCESS(ret_gfx, CyGfx_SmAssignBuffer(&surfSrc, width, height, CYGFX_SM_FORMAT_YUV420, 0, 0)); UTIL_SUCCESS(ret_gfx, CyGfx_SmSetAttribute(&surfSrc, CYGFX_SM_ATTR_STRIDE, width)); UTIL_SUCCESS(ret_gfx, CyGfx_SmSetAttribute(&surfSrc, CYGFX_SM_ATTR_VIRT_ADDRESS, (CYGFX_U32) STORE_BUF0_START_ADDR)); UTIL_SUCCESS(ret_gfx, CyGfx_SmSetAttribute(&surfSrc, CYGFX_SM_ATTR_VIRT_ADDRESS_SEC, (CYGFX_U32) STORE_BUF1_START_ADDR)); UTIL_SUCCESS(ret_gfx, CyGfx_BeBindSurface(&ctx, CYGFX_BE_TARGET_SRC, &surfSrc)); UTIL_SUCCESS(ret_gfx, CyGfx_SmResetSurfaceObject(&surfDst)); UTIL_SUCCESS(ret_gfx, CyGfx_SmAssignBuffer(&surfDst, width, height, dst_format, (void *) outbuffer, 0)); UTIL_SUCCESS(ret_gfx, CyGfx_BeBindSurface(&ctx, CYGFX_BE_TARGET_STORE, &surfDst)); UTIL_SUCCESS(ret_gfx, CyGfx_BeBlt(&ctx, 0, 0)); CyGfx_BeFinish(&ctx); } void tvii_jpeg_init(void) { // Configuration jpeg_configuration_init(); // Initialize JPEG Interrupts int ret = Cy_SysInt_InitIRQ(&irq_cfg_jpeg); if (ret != 0) { qul_printf("Cy_SysInt_InitIRQ() failed\n"); return; } // Set interrupt handler Cy_SysInt_SetSystemIrqVector(irq_cfg_jpeg.sysIntSrc, Jpeg_InterruptHandler); // Set Priority/Enable IRQ NVIC_SetPriority(CPUIntIdx3_IRQn, 3); NVIC_ClearPendingIRQ(CPUIntIdx3_IRQn); NVIC_EnableIRQ(CPUIntIdx3_IRQn); // Initialize JPEG Decode Driver ret = CyJpg_Init(&init_config); if (ret != 0) { qul_printf("CyJpg_Init() failed\n"); return; } // Change state to Configuration */ Jpeg_DecUpdateState(DEC_STATE_CONFIG); return; } CYJPG_STATIC CYJPG_U32 Jpeg_DecOpeStartDec(void); CYJPG_STATIC CYJPG_U32 Jpeg_DecOpeSizeAvailIntr(void); CYJPG_STATIC CYJPG_U32 Jpeg_DecOpeCompletion(void); CYJPG_STATIC CYJPG_U32 Jpeg_DecOpeRecovery(void); /** \brief Decode JPEG images periodically ** \param No param ** \return Result of initialization ** RES_DEC_SUCCESS: OK ** Others : NG ** ** No remarks ** */ CYJPG_U32 Jpeg_DecStart(uint32_t addr, uint32_t size, uint32_t stride) { /* Local variables */ CYJPG_U32 result_appl = RES_DEC_SUCCESS; /* Result of Sample Application */ CYJPG_ERROR ret_drv; /* Return value from Jpeg Decode Driver */ /* Initialize variables */ first_dec_comp = CYJPG_FALSE; /* First decode completion */ gen_normal_corrected = CYJPG_FALSE; /* NORMALEND/CORRECTEDEND generated Flag */ jpg_config.fetchAddress = addr; jpg_config.fetchLength = size; jpg_config.storeStride0 = stride; jpg_config.storeStride1 = stride; #ifdef TVII_DEBUG_JPEG_DECODER qul_printf("jpg_config.storeStride0 %u\n", jpg_config.storeStride0); #endif /* Change state to Decoding */ CALL_APPL_FUNC(result_appl, Jpeg_DecUpdateState(DEC_STATE_DECODING)); /* Start decoding 1st JPEG image */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_StartDecoding(&jpg_config)); while (result_appl == RES_DEC_SUCCESS) { switch (decode_state) { case DEC_STATE_CONFIG: { #ifdef TVII_DEBUG_JPEG_DECODER qul_printf("DEC_STATE_CONFIG\n"); #endif /* Start JPEG decoding */ CALL_APPL_FUNC(result_appl, Jpeg_DecOpeStartDec()); break; } case DEC_STATE_DECODING: { #ifdef TVII_DEBUG_JPEG_DECODER qul_printf("DEC_STATE_DECODING\n"); CYJPG_DECODEINFO_S dec_info; /* Decode Information */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_GetDecInfo(&dec_info)); qul_printf("dec_info.subsample %u\n", dec_info.subsample); #endif break; } case DEC_STATE_SUSPENDED: { #ifdef TVII_DEBUG_JPEG_DECODER qul_printf("DEC_STATE_SUSPENDED\n"); #endif /* Change state to Decoding */ CALL_APPL_FUNC(result_appl, Jpeg_DecUpdateState(DEC_STATE_DECODING)); /* Resume Decoding */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_ResumeDecoding(&jpg_config)); #ifdef TVII_DEBUG_JPEG_DECODER CYJPG_DECODEINFO_S dec_info; /* Decode Information */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_GetDecInfo(&dec_info)); qul_printf("DEC_STATE_SUSPENDED\tdec_info.subsample %u\n", dec_info.subsample); #endif break; } case DEC_STATE_SUSPENDED_SIZEAVAIL: { #ifdef TVII_DEBUG_JPEG_DECODER qul_printf("DEC_STATE_SUSPENDED_SIZEAVAIL\n"); #endif /* Operation when Size Available Interrupt occurs */ CALL_APPL_FUNC(result_appl, Jpeg_DecOpeSizeAvailIntr()); break; } case DEC_STATE_COMPLETED: { #ifdef TVII_DEBUG_JPEG_DECODER qul_printf("DEC_STATE_COMPLETED\n"); #endif /* Operation for decoding completion */ CALL_APPL_FUNC(result_appl, Jpeg_DecOpeCompletion()); return RES_DEC_SUCCESS; break; } case DEC_STATE_RECOVERY: { #ifdef TVII_DEBUG_JPEG_DECODER qul_printf("DEC_STATE_RECOVERY\n"); #endif /* Operation for recovery */ CALL_APPL_FUNC(result_appl, Jpeg_DecOpeRecovery()); break; } default: { /* Abnormal error */ qul_printf("Jpeg Decoder: Abnormal error detected.\n"); result_appl = RES_DEC_FAILED_ABNORMAL; break; } } } return result_appl; } /** \brief Wait for AXI transactions to become inactive ** \param No param ** \return result ** RES_DEC_SUCCESS: Success ** RES_DEC_FAILED_DRIVER: JPEG Driver API failed ** RES_DEC_FAILED_TIMEOUT_AXI: Timeout of AXI inactive timer ** ** No remarks ** */ CYJPG_STATIC CYJPG_U32 Jpeg_DecWaitAxiInactive(void) { /* Local variables */ CYJPG_U32 result_appl = RES_DEC_SUCCESS; /* Result of Sample Application */ CYJPG_ERROR ret_drv; /* Return value from Jpeg Decode Driver */ // float elapsed_time; /* Elapsed Time */ CYJPG_CORESTATUS_S core_status; /* HW core status */ /* Get HW status */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_GetHwStatus(&core_status)); /* Check fetch/store AXI burst are finished */ if ((core_status.fetchAxiActive != CYJPG_FALSE) || (core_status.storeAxiActive != CYJPG_FALSE)) { do { /* Get HW status */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_GetHwStatus(&core_status)); if (result_appl == RES_DEC_SUCCESS) { /* Check fetch/store AXI burst are inactive */ if ((core_status.fetchAxiActive == CYJPG_FALSE) && (core_status.storeAxiActive == CYJPG_FALSE)) { /* Finish fetch/store AXI burst */ break; } } } while (result_appl == RES_DEC_SUCCESS); } return result_appl; } /** \brief Operation for Starting JPEG decode ** \param No param ** \return result ** RES_DEC_SUCCESS: Success ** RES_DEC_FAILED_DRIVER: JPEG Driver API failed ** RES_DEC_FAILED_ILLEGAL_STATE: Illegal state error ** ** No remarks ** */ CYJPG_STATIC CYJPG_U32 Jpeg_DecOpeStartDec(void) { /* Local variables */ CYJPG_U32 result_appl = RES_DEC_SUCCESS; /* Result of Sample Application */ CYJPG_ERROR ret_drv; /* Return value from Jpeg Decode Driver */ CYJPG_BOOL mod_config = CYJPG_FALSE; /* Flag of modifying configuration */ /* Change state to Decoding */ CALL_APPL_FUNC(result_appl, Jpeg_DecUpdateState(DEC_STATE_DECODING)); if (mod_config == CYJPG_FALSE) { /* Continue decoding JPEG image */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_ContinueDecoding(&jpg_config)); } else { /* Start decoding with configuration changes */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_StartDecoding(&jpg_config)); } return result_appl; } /** \brief Operation when Size Available Interrupt occurs ** \param No param ** \return result ** RES_DEC_SUCCESS: Success ** RES_DEC_FAILED_DRIVER: JPEG Driver API failed ** RES_DEC_FAILED_ILLEGAL_STATE: Illegal state error ** ** No remarks ** */ CYJPG_STATIC CYJPG_U32 Jpeg_DecOpeSizeAvailIntr(void) { /* Local variables */ CYJPG_U32 result_appl = RES_DEC_SUCCESS; /* Result of Sample Application */ CYJPG_ERROR ret_drv; /* Return value from Jpeg Decode Driver */ CYJPG_HWERRINFO_S hw_err_info; /* HW Error Information */ CYJPG_BOOL crop_error = CYJPG_FALSE; /* Crop Error Flag */ if (jpg_config.cropEn == CYJPG_ENABLE) { /* Get HW error information to check crop errors */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_GetHwErrorInfo(&hw_err_info)); if ((hw_err_info.correctionCropStatus[hw_err_info.correctionCropNum] & 0x00000030U) != 0U) { /* Crop Size Error (Bit#4) or MCU Unit Error (Bit#5) occurs */ crop_error = CYJPG_TRUE; } } if (crop_error == CYJPG_FALSE) { /* Change state to Decoding */ CALL_APPL_FUNC(result_appl, Jpeg_DecUpdateState(DEC_STATE_DECODING)); /* Resume Decoding */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_ResumeDecoding(&jpg_config)); } else { /* Change state to Recovery */ CALL_APPL_FUNC(result_appl, Jpeg_DecUpdateState(DEC_STATE_RECOVERY)); /* Notify recovery cause as undefined status */ Jpeg_DecNotifyRcvCause(DEC_RCV_CAUSE_UNDEFINED_STATE); } return result_appl; } /** \brief Operation for JPEG decode completion ** \param No param ** \return result ** RES_DEC_SUCCESS: Success ** RES_DEC_FAILED_ILLEGAL_STATE: Illegal state error ** ** No remarks ** */ CYJPG_STATIC CYJPG_U32 Jpeg_DecOpeCompletion(void) { /* Local variables */ CYJPG_U32 result_appl = RES_DEC_SUCCESS; /* Result of Sample Application */ /* Check Decode error: Not generated NORMALEND/CORRECTEDEND */ if (gen_normal_corrected == CYJPG_TRUE) { /* Check if the decoded data is 1st JPEG image */ if (first_dec_comp == CYJPG_FALSE) { first_dec_comp = CYJPG_TRUE; } /* Change state to Configuration */ CALL_APPL_FUNC(result_appl, Jpeg_DecUpdateState(DEC_STATE_CONFIG)); } else { /* Change state to Recovery */ CALL_APPL_FUNC(result_appl, Jpeg_DecUpdateState(DEC_STATE_RECOVERY)); /* Set recovery cause to "NORMALEND/CORRECTEDEND not generated" */ Jpeg_DecNotifyRcvCause(DEC_RCV_CAUSE_NO_NORMAL_CORRECTED); } /* Initialize NORMALEND/CORRECTEDEND generated flag */ Jpeg_DecNotifyNormalCorrected(CYJPG_FALSE); return result_appl; } /** \brief Operation for hardware status recovery ** \param No param ** \return result ** RES_DEC_SUCCESS: Success ** RES_DEC_FAILED_DRIVER: JPEG Driver API failed ** RES_DEC_FAILED_TIMEOUT_AXI: Timeout of AXI inactive timer ** RES_DEC_FAILED_ABNORMAL: Abnormal error ** ** No remarks ** */ CYJPG_STATIC CYJPG_U32 Jpeg_DecOpeRecovery(void) { /* Local variables */ CYJPG_U32 result_appl = RES_DEC_SUCCESS; /* Result of Sample Application */ CYJPG_ERROR ret_drv; /* Return value from Jpeg Decode Driver */ switch (recovery_cause) { case DEC_RCV_CAUSE_FETCH_STORE_ERR: { /* Wait for AXI transactions to become inactive */ CALL_APPL_FUNC(result_appl, Jpeg_DecWaitAxiInactive()); /* Perform SW reset */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_SwReset()); break; } case DEC_RCV_CAUSE_INTR_DEC_ERR: { /* Wait for AXI transactions to become inactive */ CALL_APPL_FUNC(result_appl, Jpeg_DecWaitAxiInactive()); break; } case DEC_RCV_CAUSE_CANCEL: case DEC_RCV_CAUSE_NO_NORMAL_CORRECTED: { /* Perform SW reset */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_SwReset()); /* Wait for AXI transactions to become inactive */ CALL_APPL_FUNC(result_appl, Jpeg_DecWaitAxiInactive()); break; } case DEC_RCV_CAUSE_UNDEFINED_STATE: { /* Perform SW reset */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_SwReset()); /* Wait for AXI transactions to become inactive */ CALL_APPL_FUNC(result_appl, Jpeg_DecWaitAxiInactive()); /* Deinitialize JPEG decode driver */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_DeInit()); if (result_appl == RES_DEC_SUCCESS) { /* Marker Skip Function must be disabled */ jpg_config.markerskipEn = CYJPG_DISABLE; /* Initialize JPEG decode driver */ CALL_JPGDRV_FUNC(result_appl, ret_drv, CyJpg_Init(&init_config)); } break; } default: { /* Abnormal error */ result_appl = RES_DEC_FAILED_ABNORMAL; break; } } if (result_appl == RES_DEC_SUCCESS) { /* Change state to Configuration */ CALL_APPL_FUNC(result_appl, Jpeg_DecUpdateState(DEC_STATE_CONFIG)); /* Initialize Recovery Cause */ Jpeg_DecNotifyRcvCause(DEC_RCV_CAUSE_NOTHING); /* Initialize first decode completion */ first_dec_comp = CYJPG_FALSE; } return result_appl; }