diff options
Diffstat (limited to 'source')
17 files changed, 1475 insertions, 30 deletions
diff --git a/source/application/main/include/UseCaseCommonUtils.hpp b/source/application/main/include/UseCaseCommonUtils.hpp index 68ffe42..182aea6 100644 --- a/source/application/main/include/UseCaseCommonUtils.hpp +++ b/source/application/main/include/UseCaseCommonUtils.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com> + * SPDX-FileCopyrightText: Copyright 2021-2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -56,12 +56,15 @@ bool SetAppCtxIfmIdx(arm::app::ApplicationContext& ctx, uint32_t idx, const std: namespace common { - enum OPCODES { - MENU_OPT_RUN_INF_NEXT = 1, /* Run on next vector. */ - MENU_OPT_RUN_INF_CHOSEN, /* Run on a user provided vector index. */ - MENU_OPT_RUN_INF_ALL, /* Run inference on all. */ - MENU_OPT_SHOW_MODEL_INFO, /* Show model info. */ - MENU_OPT_LIST_IFM /* List the current IFM. */ + enum OPCODES { + MENU_OPT_RUN_INF_NEXT = 1, /* Run on next vector. */ + MENU_OPT_RUN_INF_CHOSEN, /* Run on a user provided vector index. */ + MENU_OPT_RUN_INF_ALL, /* Run inference on all. */ + MENU_OPT_SHOW_MODEL_INFO, /* Show model info. */ + MENU_OPT_LIST_IFM, /* List the current IFM. */ +#if VSI_ENABLED + MENU_OPT_RUN_INF_VSI /* Run on input from VSI. */ +#endif }; } diff --git a/source/hal/source/components/vsi/CMakeLists.txt b/source/hal/source/components/vsi/CMakeLists.txt new file mode 100644 index 0000000..8d07459 --- /dev/null +++ b/source/hal/source/components/vsi/CMakeLists.txt @@ -0,0 +1,79 @@ +#---------------------------------------------------------------------------- +# SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#---------------------------------------------------------------------------- + +########################################################## +# Arm Virtual Streaming Interface initialization library # +########################################################## + +# Arm Virtual Streaming Interface is only available on +# certain supported platforms. + +cmake_minimum_required(VERSION 3.21.0) +set(ARM_VSI_COMPONENT arm_vsi) +project(${ARM_VSI_COMPONENT} + DESCRIPTION "Arm Virtual Streaming Interface initialization library" + LANGUAGES C CXX ASM) + +## Logging utilities: +if (NOT TARGET log) + if (NOT DEFINED LOG_PROJECT_DIR) + message(FATAL_ERROR "LOG_PROJECT_DIR needs to be defined.") + endif() + add_subdirectory(${LOG_PROJECT_DIR} ${CMAKE_BINARY_DIR}/log) +endif() + +# Create static library +add_library(${ARM_VSI_COMPONENT} STATIC) + +## Include directories - public +target_include_directories(${ARM_VSI_COMPONENT} + PUBLIC + include) + +## Component sources +target_sources(${ARM_VSI_COMPONENT} + PUBLIC + source/video_drv.c) + +## If the rte_components target has been defined, include it as a dependency here. This component +## gives access to certain CPU related functions and definitions that should come from the CMSIS +## or custom system setup and boot implementation files. +## If the component is not defined as a target, a dependency for this target should be added by +## the project importing this one. +if (TARGET rte_components) + target_link_libraries(${ARM_VSI_COMPONENT} PUBLIC + rte_components) +else() + message(WARNING + "rte_components target not defined." + "${ARM_VSI_COMPONENT} will need to be provided access to" + "RTE_Components.h header to include CPU specific definitions.") +endif() +## Compile definitions +target_compile_definitions(${ARM_VSI_COMPONENT} + PUBLIC + VSI_ENABLED) + +## Add dependencies +target_link_libraries(${ARM_VSI_COMPONENT} PUBLIC + log) + +# Display status +message(STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR}) +message(STATUS "*******************************************************") +message(STATUS "Library : " ${ARM_VSI_COMPONENT}) +message(STATUS "*******************************************************") diff --git a/source/hal/source/components/vsi/include/arm_vsi.h b/source/hal/source/components/vsi/include/arm_vsi.h new file mode 100644 index 0000000..1d307d1 --- /dev/null +++ b/source/hal/source/components/vsi/include/arm_vsi.h @@ -0,0 +1,121 @@ +/* +* SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* + * Virtual Streaming Interface (VSI) + */ + +#ifndef __ARM_VSI_H +#define __ARM_VSI_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __IM +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#endif +#ifndef __OM +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#endif +#ifndef __IOM +#define __IOM volatile /*! Defines 'read/write' structure member permissions */ +#endif + +#include <stdint.h> + +/* IRQ number assignment (should be moved to device header) */ +#define ARM_VSI0_IRQn 224 +#define ARM_VSI1_IRQn 225 +#define ARM_VSI2_IRQn 226 +#define ARM_VSI3_IRQn 227 +#define ARM_VSI4_IRQn 228 +#define ARM_VSI5_IRQn 229 +#define ARM_VSI6_IRQn 230 +#define ARM_VSI7_IRQn 231 + +/// Structure type to access the virtual streaming interface +typedef struct +{ + /// Interrupt Request (IRQ) + struct { + __IOM uint32_t Enable; /*!< (R/W) IRQ Enable */ + __OM uint32_t Set; /*!< (-/W) IRQ Set */ + __OM uint32_t Clear; /*!< (-/W) IRQ Clear */ + __IM uint32_t Status; /*!< (R/-) IRQ Status */ + } IRQ; + uint32_t reserved1[60]; + /// Time counter with 1MHz input frequency + struct { + __IOM uint32_t Control; /*!< (R/W) Timer Control */ + __IOM uint32_t Interval; /*!< (R/W) Timer Interval Value (in microseconds) */ + __IM uint32_t Count; /*!< (R/-) Timer Overflow Count */ + } Timer; + uint32_t reserved2[61]; + /// Direct Memory Access (DMA) Controller + struct { + __IOM uint32_t Control; /*!< (R/W) DMA Control */ + __IOM uint32_t Address; /*!< (R/W) DMA Memory Start Address */ + __IOM uint32_t BlockSize; /*!< (R/W) DMA Block Size (in bytes, multiple of 4) */ + __IOM uint32_t BlockNum; /*!< (R/W) DMA Number of Blocks (must be 2^n) */ + __IM uint32_t BlockIndex; /*!< (R/-) DMA Block Index */ + } DMA; + uint32_t reserved3[59]; + __IOM uint32_t Regs[64]; /*!< (R/W) User Registers */ +} ARM_VSI_Type; + +/* VSI Timer Control Definitions for Timer.Control register */ +#define ARM_VSI_Timer_Run_Pos 0U /*!< Timer Control: Run Position */ +#define ARM_VSI_Timer_Run_Msk (1UL << ARM_VSI_Timer_Run_Pos) /*!< Timer Control: Run Mask */ +#define ARM_VSI_Timer_Periodic_Pos 1U /*!< Timer Control: Periodic Position */ +#define ARM_VSI_Timer_Periodic_Msk (1UL << ARM_VSI_Timer_Periodic_Pos) /*!< Timer Control: Periodic Mask */ +#define ARM_VSI_Timer_Trig_IRQ_Pos 2U /*!< Timer Control: Trig_IRQ Position */ +#define ARM_VSI_Timer_Trig_IRQ_Msk (1UL << ARM_VSI_Timer_Trig_IRQ_Pos) /*!< Timer Control: Trig_IRQ Mask */ +#define ARM_VSI_Timer_Trig_DMA_Pos 3U /*!< Timer Control: Trig_DAM Position */ +#define ARM_VSI_Timer_Trig_DMA_Msk (1UL << ARM_VSI_Timer_Trig_DMA_Pos) /*!< Timer Control: Trig_DMA Mask */ + +/* VSI DMA Control Definitions for DMA.Control register */ +#define ARM_VSI_DMA_Enable_Pos 0U /*!< DMA Control: Enable Position */ +#define ARM_VSI_DMA_Enable_Msk (1UL << ARM_VSI_DMA_Enable_Pos) /*!< DMA Control: Enable Mask */ +#define ARM_VSI_DMA_Direction_Pos 1U /*!< DMA Control: Direction Position */ +#define ARM_VSI_DMA_Direction_Msk (1UL << ARM_VSI_DMA_Direction_Pos) /*!< DMA Control: Direction Mask */ +#define ARM_VSI_DMA_Direction_P2M (0UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction P2M */ +#define ARM_VSI_DMA_Direction_M2P (1UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction M2P */ + +/* Memory mapping of 8 VSI peripherals */ +#define ARM_VSI0_BASE (0x4FF00000UL) /*!< VSI 0 Base Address */ +#define ARM_VSI1_BASE (0x4FF10000UL) /*!< VSI 1 Base Address */ +#define ARM_VSI2_BASE (0x4FF20000UL) /*!< VSI 2 Base Address */ +#define ARM_VSI3_BASE (0x4FF30000UL) /*!< VSI 3 Base Address */ +#define ARM_VSI4_BASE (0x4FF40000UL) /*!< VSI 4 Base Address */ +#define ARM_VSI5_BASE (0x4FF50000UL) /*!< VSI 5 Base Address */ +#define ARM_VSI6_BASE (0x4FF60000UL) /*!< VSI 6 Base Address */ +#define ARM_VSI7_BASE (0x4FF70000UL) /*!< VSI 7 Base Address */ +#define ARM_VSI0 ((ARM_VSI_Type *)ARM_VSI0_BASE) /*!< VSI 0 struct */ +#define ARM_VSI1 ((ARM_VSI_Type *)ARM_VSI1_BASE) /*!< VSI 1 struct */ +#define ARM_VSI2 ((ARM_VSI_Type *)ARM_VSI2_BASE) /*!< VSI 2 struct */ +#define ARM_VSI3 ((ARM_VSI_Type *)ARM_VSI3_BASE) /*!< VSI 3 struct */ +#define ARM_VSI4 ((ARM_VSI_Type *)ARM_VSI4_BASE) /*!< VSI 4 struct */ +#define ARM_VSI5 ((ARM_VSI_Type *)ARM_VSI5_BASE) /*!< VSI 5 struct */ +#define ARM_VSI6 ((ARM_VSI_Type *)ARM_VSI6_BASE) /*!< VSI 6 struct */ +#define ARM_VSI7 ((ARM_VSI_Type *)ARM_VSI7_BASE) /*!< VSI 7 struct */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ARM_VSI_H */ diff --git a/source/hal/source/components/vsi/include/video_drv.h b/source/hal/source/components/vsi/include/video_drv.h new file mode 100644 index 0000000..73a6ef7 --- /dev/null +++ b/source/hal/source/components/vsi/include/video_drv.h @@ -0,0 +1,142 @@ +/* +* SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef VIDEO_DRV_H +#define VIDEO_DRV_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> + +/* Video Channel */ +#define VIDEO_DRV_IN0 (0UL) ///< Video Input channel 0 +#define VIDEO_DRV_OUT0 (1UL) ///< Video Output channel 0 +#define VIDEO_DRV_IN1 (2UL) ///< Video Input channel 1 +#define VIDEO_DRV_OUT1 (3UL) ///< Video Output channel 1 + +/* Video Event */ +#define VIDEO_DRV_EVENT_FRAME (1UL << 0) ///< Video frame received +#define VIDEO_DRV_EVENT_OVERFLOW (1UL << 1) ///< Video buffer overflow +#define VIDEO_DRV_EVENT_UNDERFLOW (1UL << 2) ///< Video buffer underflow +#define VIDEO_DRV_EVENT_EOS (1UL << 3) ///< Video end of stream + +/* Video Mode */ +#define VIDEO_DRV_MODE_SINGLE (0UL) ///< Single frame +#define VIDEO_DRV_MODE_CONTINUOS (1UL) ///< Continuos stream + +/* Return code */ +#define VIDEO_DRV_OK (0) ///< Operation succeeded +#define VIDEO_DRV_ERROR (-1) ///< Unspecified error +#define VIDEO_DRV_ERROR_PARAMETER (-2) ///< Parameter error + +/// Video Color Format +#define COLOR_FORMAT_BEGIN (0UL) +#define COLOR_GRAYSCALE8 (1UL) +#define COLOR_RGB888 (2UL) +#define COLOR_BGR565 (3UL) +#define COLOR_YUV420 (4UL) +#define COLOR_NV12 (5UL) +#define COLOR_NV21 (6UL) +#define COLOR_FORMAT_END (7UL) + +/// Video Status +typedef struct { + uint32_t active : 1; ///< Video stream active + uint32_t buf_empty : 1; ///< Video stream buffer empty + uint32_t buf_full : 1; ///< Video stream buffer full + uint32_t overflow : 1; ///< Video buffer overflow (cleared on GetStatus) + uint32_t underflow : 1; ///< Video buffer underflow (cleared on GetStatus) + uint32_t eos : 1; ///< Video end of stream (cleared on GetStatus) + uint32_t reserved : 26; +} VideoDrv_Status_t; + +/// \brief Video Events callback function type. +/// \param[in] channel channel number +/// \param[in] event events notification mask +/// \return none +typedef void (*VideoDrv_Event_t) (uint32_t channel, uint32_t event); + +/// \brief Initialize Video Interface. +/// \param[in] cb_event pointer to \ref VideoDrv_Event_t +/// \return return code +int32_t VideoDrv_Initialize (VideoDrv_Event_t cb_event); + +/// \brief De-initialize Video Interface. +/// \return return code +int32_t VideoDrv_Uninitialize (void); + +/// \brief Set Video Interface file. +/// \param[in] channel channel number +/// \param[in] name video filename (pointer to NULL terminated string) +/// \return return code +int32_t VideoDrv_SetFile (uint32_t channel, const char *name); + +/// \brief Configure Video Interface. +/// \param[in] channel channel number +/// \param[in] frame_width frame width in pixels +/// \param[in] frame_height frame height in pixels +/// \param[in] color_format pixel color format +/// \param[in] frame_rate frame rate (frames per second) +/// \return return code +int32_t VideoDrv_Configure (uint32_t channel, uint32_t frame_width, uint32_t frame_height, uint32_t color_format, uint32_t frame_rate); + +/// \brief Set Video Interface buffer. +/// \param[in] channel channel number +/// \param[in] buf pointer to buffer for video stream +/// \param[in] buf_size video stream buffer size in bytes +/// \return return code +int32_t VideoDrv_SetBuf (uint32_t channel, void *buf, uint32_t buf_size); + +/// \brief Flush Video Interface buffer. +/// \param[in] channel channel number +/// \return return code +int32_t VideoDrv_FlushBuf (uint32_t channel); + +/// \brief Start Stream on Video Interface. +/// \param[in] channel channel number +/// \param[in] mode stream mode +/// \return return code +int32_t VideoDrv_StreamStart (uint32_t channel, uint32_t mode); + +/// \brief Stop Stream on Video Interface. +/// \param[in] channel channel number +/// \return return code +int32_t VideoDrv_StreamStop (uint32_t channel); + +/// \brief Get Video Frame buffer. +/// \param[in] channel channel number +/// \return pointer to frame buffer +void *VideoDrv_GetFrameBuf (uint32_t channel); + +/// \brief Release Video Frame. +/// \param[in] channel channel number +/// \return return code +int32_t VideoDrv_ReleaseFrame (uint32_t channel); + +/// \brief Get Video Interface status. +/// \param[in] channel channel number +/// \return \ref VideoDrv_Status_t +VideoDrv_Status_t VideoDrv_GetStatus (uint32_t channel); + +#ifdef __cplusplus +} +#endif + +#endif /* VIDEO_DRV_H */ diff --git a/source/hal/source/components/vsi/source/video_drv.c b/source/hal/source/components/vsi/source/video_drv.c new file mode 100644 index 0000000..ab4e2e5 --- /dev/null +++ b/source/hal/source/components/vsi/source/video_drv.c @@ -0,0 +1,600 @@ +/* +* SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdint.h> +#include <string.h> +#include "video_drv.h" + +#include "RTE_Components.h" +#include "arm_vsi.h" + +// Video channel definitions +#ifndef VIDEO_INPUT_CHANNELS +#define VIDEO_INPUT_CHANNELS 1 +#endif +#if (VIDEO_INPUT_CHANNELS > 2) +#error "Maximum 2 Video Input channels are supported!" +#endif +#ifndef VIDEO_OUTPUT_CHANNELS +#define VIDEO_OUTPUT_CHANNELS 1 +#endif +#if (VIDEO_OUTPUT_CHANNELS > 2) +#error "Maximum 2 Video Output channels are supported!" +#endif + + +// Video peripheral definitions +#define VideoI0 ARM_VSI4 // Video Input channel 0 access struct +#define VideoI0_IRQn ARM_VSI4_IRQn // Video Input channel 0 Interrupt number +#define VideoI0_Handler ARM_VSI4_Handler // Video Input channel 0 Interrupt handler +#define VideoI1 ARM_VSI5 // Video Input channel 1 access struct +#define VideoI1_IRQn ARM_VSI5_IRQn // Video Input channel 1 Interrupt number +#define VideoI1_Handler ARM_VSI5_Handler // Video Input channel 1 Interrupt handler +#define VideoO0 ARM_VSI6 // Video Output channel 0 access struct +#define VideoO0_IRQn ARM_VSI6_IRQn // Video Output channel 0 Interrupt number +#define VideoO0_Handler ARM_VSI6_Handler // Video Output channel 0 Interrupt handler +#define VideoO1 ARM_VSI7 // Video Output channel 1 access struct +#define VideoO1_IRQn ARM_VSI7_IRQn // Video Output channel 1 Interrupt number +#define VideoO1_Handler ARM_VSI7_Handler // Video Output channel 1 Interrupt handler + +// Video Peripheral registers +#define Reg_MODE Regs[0] // Mode: 0=Input, 1=Output +#define Reg_CONTROL Regs[1] // Control: enable, continuos, flush +#define Reg_STATUS Regs[2] // Status: active, buf_empty, buf_full, overflow, underflow, eos +#define Reg_FILENAME_LEN Regs[3] // Filename length +#define Reg_FILENAME_CHAR Regs[4] // Filename character +#define Reg_FILENAME_VALID Regs[5] // Filename valid flag +#define Reg_FRAME_WIDTH Regs[6] // Requested frame width +#define Reg_FRAME_HEIGHT Regs[7] // Requested frame height +#define Reg_COLOR_FORMAT Regs[8] // Color format +#define Reg_FRAME_RATE Regs[9] // Frame rate +#define Reg_FRAME_INDEX Regs[10] // Frame index +#define Reg_FRAME_COUNT Regs[11] // Frame count +#define Reg_FRAME_COUNT_MAX Regs[12] // Frame count maximum + +// Video MODE register defintions +#define Reg_MODE_IO_Pos 0U +#define Reg_MODE_IO_Msk (1UL << Reg_MODE_IO_Pos) +#define Reg_MODE_Input (0UL << Reg_MODE_IO_Pos) +#define Reg_MODE_Output (1UL << Reg_MODE_IO_Pos) + +// Video CONTROL register definitions +#define Reg_CONTROL_ENABLE_Pos 0U +#define Reg_CONTROL_ENABLE_Msk (1UL << Reg_CONTROL_ENABLE_Pos) +#define Reg_CONTROL_CONTINUOS_Pos 1U +#define Reg_CONTROL_CONTINUOS_Msk (1UL << Reg_CONTROL_CONTINUOS_Pos) +#define Reg_CONTROL_BUF_FLUSH_Pos 2U +#define Reg_CONTROL_BUF_FLUSH_Msk (1UL << Reg_CONTROL_BUF_FLUSH_Pos) + +// Video STATUS register definitions +#define Reg_STATUS_ACTIVE_Pos 0U +#define Reg_STATUS_ACTIVE_Msk (1UL << Reg_STATUS_ACTIVE_Pos) +#define Reg_STATUS_BUF_EMPTY_Pos 1U +#define Reg_STATUS_BUF_EMPTY_Msk (1UL << Reg_STATUS_BUF_EMPTY_Pos) +#define Reg_STATUS_BUF_FULL_Pos 2U +#define Reg_STATUS_BUF_FULL_Msk (1UL << Reg_STATUS_BUF_FULL_Pos) +#define Reg_STATUS_OVERFLOW_Pos 3U +#define Reg_STATUS_OVERFLOW_Msk (1UL << Reg_STATUS_OVERFLOW_Pos) +#define Reg_STATUS_UNDERFLOW_Pos 4U +#define Reg_STATUS_UNDERFLOW_Msk (1UL << Reg_STATUS_UNDERFLOW_Pos) +#define Reg_STATUS_EOS_Pos 5U +#define Reg_STATUS_EOS_Msk (1UL << Reg_STATUS_EOS_Pos) + +// IRQ Status register definitions +#define Reg_IRQ_Status_FRAME_Pos 0U +#define Reg_IRQ_Status_FRAME_Msk (1UL << Reg_IRQ_Status_FRAME_Pos) +#define Reg_IRQ_Status_OVERFLOW_Pos 1U +#define Reg_IRQ_Status_OVERFLOW_Msk (1UL << Reg_IRQ_Status_OVERFLOW_Pos) +#define Reg_IRQ_Status_UNDERFLOW_Pos 2U +#define Reg_IRQ_Status_UNDERFLOW_Msk (1UL << Reg_IRQ_Status_UNDERFLOW_Pos) +#define Reg_IRQ_Status_EOS_Pos 3U +#define Reg_IRQ_Status_EOS_Msk (1UL << Reg_IRQ_Status_EOS_Pos) + +#define Reg_IRQ_Status_Msk Reg_IRQ_Status_FRAME_Msk | \ + Reg_IRQ_Status_OVERFLOW_Msk | \ + Reg_IRQ_Status_UNDERFLOW_Msk | \ + Reg_IRQ_Status_EOS_Msk + +// Video peripheral access structure +static ARM_VSI_Type * const pVideo[4] = { VideoI0, VideoO0, VideoI1, VideoO1 }; + +// Driver State +static uint8_t Initialized = 0U; +static uint8_t Configured[4] = { 0U, 0U, 0U, 0U }; + +// Event Callback +static VideoDrv_Event_t CB_Event = NULL; + +// Video Interrupt Handler +static void Video_Handler (uint32_t channel) { + uint32_t irq_status; + uint32_t event; + + irq_status = pVideo[channel]->IRQ.Status; + pVideo[channel]->IRQ.Clear = irq_status; + __DSB(); + __ISB(); + + event = 0U; + if (irq_status & Reg_IRQ_Status_FRAME_Msk) { + event |= VIDEO_DRV_EVENT_FRAME; + } + if (irq_status & Reg_IRQ_Status_OVERFLOW_Msk) { + event |= VIDEO_DRV_EVENT_OVERFLOW; + } + if (irq_status & Reg_IRQ_Status_UNDERFLOW_Msk) { + event |= VIDEO_DRV_EVENT_UNDERFLOW; + } + if (irq_status & Reg_IRQ_Status_EOS_Msk) { + event |= VIDEO_DRV_EVENT_EOS; + } + + if (CB_Event != NULL) { + CB_Event(channel, event); + } +} + +// Video channel 0 Interrupt Handler +#if (VIDEO_INPUT_CHANNELS >= 1) +void VideoI0_Handler (void); +void VideoI0_Handler (void) { + Video_Handler(0U); +} +#endif + +// Video channel 1 Interrupt Handler +#if (VIDEO_OUTPUT_CHANNELS >= 1) +void VideoO0_Handler (void); +void VideoO0_Handler (void) { + Video_Handler(1U); +} +#endif + +// Video channel 2 Interrupt Handler +#if (VIDEO_INPUT_CHANNELS >= 2) +void VideoI1_Handler (void); +void VideoI1_Handler (void) { + Video_Handler(2U); +} +#endif + +// Video channel 3 Interrupt Handler +#if (VIDEO_OUTPUT_CHANNELS >= 2) +void VideoO1_Handler (void); +void VideoO1_Handler (void) { + Video_Handler(3U); +} +#endif + +// Initialize Video Interface +int32_t VideoDrv_Initialize (VideoDrv_Event_t cb_event) { + + CB_Event = cb_event; + + // Initialize Video Input channel 0 + #if (VIDEO_INPUT_CHANNELS >= 1) + VideoI0->Timer.Control = 0U; + VideoI0->DMA.Control = 0U; + VideoI0->IRQ.Clear = Reg_IRQ_Status_Msk; + VideoI0->IRQ.Enable = Reg_IRQ_Status_Msk; + VideoI0->Reg_MODE = Reg_MODE_Input; + VideoI0->Reg_CONTROL = 0U; +// NVIC_EnableIRQ(VideoI0_IRQn); + NVIC->ISER[(((uint32_t)VideoI0_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI0_IRQn) & 0x1FUL)); + #endif + Configured[0] = 0U; + + // Initialize Video Output channel 0 + #if (VIDEO_OUTPUT_CHANNELS >= 1) + VideoO0->Timer.Control = 0U; + VideoO0->DMA.Control = 0U; + VideoO0->IRQ.Clear = Reg_IRQ_Status_Msk; + VideoO0->IRQ.Enable = Reg_IRQ_Status_Msk; + VideoO0->Reg_MODE = Reg_MODE_Output; + VideoO0->Reg_CONTROL = 0U; +// NVIC_EnableIRQ(VideoO0_IRQn); + NVIC->ISER[(((uint32_t)VideoO0_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoO0_IRQn) & 0x1FUL)); + #endif + Configured[1] = 0U; + + // Initialize Video Input channel 1 + #if (VIDEO_INPUT_CHANNELS >= 2) + VideoI1->Timer.Control = 0U; + VideoI1->DMA.Control = 0U; + VideoI1->IRQ.Clear = Reg_IRQ_Status_Msk; + VideoI1->IRQ.Enable = Reg_IRQ_Status_Msk; + VideoI1->Reg_MODE = Reg_MODE_Input; + VideoI1->Reg_CONTROL = 0U; +// NVIC_EnableIRQ(VideoI1_IRQn); + NVIC->ISER[(((uint32_t)VideoI1_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI1_IRQn) & 0x1FUL)); + #endif + Configured[2] = 0U; + + // Initialize Video Output channel 1 + #if (VIDEO_OUTPUT_CHANNELS >= 2) + VideoO1->Timer.Control = 0U; + VideoO1->DMA.Control = 0U; + VideoO1->IRQ.Clear = Reg_IRQ_Status_Msk; + VideoO1->IRQ.Enable = Reg_IRQ_Status_Msk; + VideoO1->Reg_MODE = Reg_MODE_Output; + VideoO1->Reg_CONTROL = 0U; +// NVIC_EnableIRQ(VideoO1_IRQn); + NVIC->ISER[(((uint32_t)VideoO1_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoO1_IRQn) & 0x1FUL)); + #endif + Configured[3] = 0U; + + __DSB(); + __ISB(); + + Initialized = 1U; + + return VIDEO_DRV_OK; +} + +// De-initialize Video Interface +int32_t VideoDrv_Uninitialize (void) { + + // De-initialize Video Input channel 0 + #if (VIDEO_INPUT_CHANNELS >= 1) +// NVIC_DisableIRQ(VideoI0_IRQn); + NVIC->ICER[(((uint32_t)VideoI0_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI0_IRQn) & 0x1FUL)); + VideoI0->Timer.Control = 0U; + VideoI0->DMA.Control = 0U; + VideoI0->IRQ.Clear = Reg_IRQ_Status_Msk; + VideoI0->IRQ.Enable = 0U; + VideoI0->Reg_CONTROL = 0U; + #endif + + // De-initialize Video Output channel 0 + #if (VIDEO_OUTPUT_CHANNELS >= 1) +// NVIC_DisableIRQ(VideoO0_IRQn); + NVIC->ICER[(((uint32_t)VideoO0_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoO0_IRQn) & 0x1FUL)); + VideoO0->Timer.Control = 0U; + VideoO0->DMA.Control = 0U; + VideoO0->IRQ.Clear = Reg_IRQ_Status_Msk; + VideoO0->IRQ.Enable = 0U; + VideoO0->Reg_CONTROL = 0U; + #endif + + // De-initialize Video Input channel 1 + #if (VIDEO_INPUT_CHANNELS >= 2) +// NVIC_DisableIRQ(VideoI1_IRQn); + NVIC->ICER[(((uint32_t)VideoI1_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI1_IRQn) & 0x1FUL)); + VideoI1->Timer.Control = 0U; + VideoI1->DMA.Control = 0U; + VideoI1->IRQ.Clear = Reg_IRQ_Status_Msk; + VideoI1->IRQ.Enable = 0U; + VideoI1->Reg_CONTROL = 0U; + #endif + + // De-initialize Video Output channel 1 + #if (VIDEO_OUTPUT_CHANNELS >= 2) +// NVIC_DisableIRQ(VideoO1_IRQn); + NVIC->ICER[(((uint32_t)VideoO1_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoO1_IRQn) & 0x1FUL)); + VideoO1->Timer.Control = 0U; + VideoO1->DMA.Control = 0U; + VideoO1->IRQ.Clear = Reg_IRQ_Status_Msk; + VideoO1->IRQ.Enable = 0U; + VideoO1->Reg_CONTROL = 0U; + #endif + + __DSB(); + __ISB(); + + Initialized = 0U; + + return VIDEO_DRV_OK; +} + +// Set Video Interface file +int32_t VideoDrv_SetFile (uint32_t channel, const char *name) { + const char *p; + uint32_t n; + + if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS)) || + (name == NULL)) { + return VIDEO_DRV_ERROR_PARAMETER; + } + + if (Initialized == 0U) { + return VIDEO_DRV_ERROR; + } + + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) { + return VIDEO_DRV_ERROR; + } + + // Register Video filename + n = strlen(name); + pVideo[channel]->Reg_FILENAME_LEN = n; + for (p = name; n != 0U; n--) { + pVideo[channel]->Reg_FILENAME_CHAR = *p++; + } + if (pVideo[channel]->Reg_FILENAME_VALID == 0U) { + return VIDEO_DRV_ERROR; + } + + return VIDEO_DRV_OK; +} + +// Configure Video Interface +int32_t VideoDrv_Configure (uint32_t channel, uint32_t frame_width, uint32_t frame_height, uint32_t color_format, uint32_t frame_rate) { + uint32_t pixel_size; + uint32_t block_size; + + if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS)) || + (frame_width == 0U) || + (frame_height == 0U) || + (frame_rate == 0U) || + (color_format <= COLOR_FORMAT_BEGIN) || + (color_format >= COLOR_FORMAT_END)) { + return VIDEO_DRV_ERROR_PARAMETER; + } + + switch (color_format) { + case COLOR_GRAYSCALE8: + pixel_size = 8U; + break; + case COLOR_YUV420: + pixel_size = 12U; + break; + case COLOR_BGR565: + pixel_size = 16U; + break; + case COLOR_RGB888: + case COLOR_NV12: + case COLOR_NV21: + pixel_size = 24U; + break; + default: + return VIDEO_DRV_ERROR_PARAMETER; + } + + block_size = (((frame_width * frame_height) * pixel_size) + 7U) / 8U; + block_size = (block_size + 3U) & ~3U; + + if (Initialized == 0U) { + return VIDEO_DRV_ERROR; + } + + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) { + return VIDEO_DRV_ERROR; + } + + pVideo[channel]->Reg_FRAME_WIDTH = frame_width; + pVideo[channel]->Reg_FRAME_HEIGHT = frame_height; + pVideo[channel]->Reg_COLOR_FORMAT = color_format; + pVideo[channel]->Reg_FRAME_RATE = frame_rate; + pVideo[channel]->Timer.Interval = 1000000U / frame_rate; + pVideo[channel]->DMA.BlockSize = block_size; + + Configured[channel] = 1U; + + return VIDEO_DRV_OK; +} + +// Set Video Interface buffer +int32_t VideoDrv_SetBuf (uint32_t channel, void *buf, uint32_t buf_size) { + uint32_t block_num; + + if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS)) || + (buf == NULL) || + (buf_size == 0U)) { + return VIDEO_DRV_ERROR_PARAMETER; + } + + if ((Initialized == 0U) || + (Configured[channel] == 0U)) { + return VIDEO_DRV_ERROR; + } + + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) { + return VIDEO_DRV_ERROR; + } + + block_num = buf_size / pVideo[channel]->DMA.BlockSize; + if (block_num == 0U) { + return VIDEO_DRV_ERROR; + } + + pVideo[channel]->Reg_FRAME_COUNT_MAX = block_num; + pVideo[channel]->DMA.BlockNum = block_num; + + pVideo[channel]->DMA.Address = (uint32_t)buf; + + Configured[channel] = 2U; + + return VIDEO_DRV_OK; +} + +// Flush Video Interface buffer +int32_t VideoDrv_FlushBuf (uint32_t channel) { + + if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS))) { + return VIDEO_DRV_ERROR_PARAMETER; + } + + if (Initialized == 0U) { + return VIDEO_DRV_ERROR; + } + + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) { + return VIDEO_DRV_ERROR; + } + + pVideo[channel]->Reg_CONTROL = Reg_CONTROL_BUF_FLUSH_Msk; + + return VIDEO_DRV_OK; +} + +// Start Stream on Video Interface +int32_t VideoDrv_StreamStart (uint32_t channel, uint32_t mode) { + uint32_t control; + + if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS)) || + (mode > VIDEO_DRV_MODE_CONTINUOS)) { + return VIDEO_DRV_ERROR_PARAMETER; + } + + if ((Initialized == 0U) || + (Configured[channel] < 2U)) { + return VIDEO_DRV_ERROR; + } + + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) { + return VIDEO_DRV_OK; + } + + control = Reg_CONTROL_ENABLE_Msk; + if (mode == VIDEO_DRV_MODE_CONTINUOS) { + control |= Reg_CONTROL_CONTINUOS_Msk; + } + pVideo[channel]->Reg_CONTROL = control; + + + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) == 0U) { + return VIDEO_DRV_ERROR; + } + + control = ARM_VSI_DMA_Enable_Msk; + if ((channel & 1U) == 0U) { + control |= ARM_VSI_DMA_Direction_P2M; + } else { + control |= ARM_VSI_DMA_Direction_M2P; + } + pVideo[channel]->DMA.Control = control; + + control = ARM_VSI_Timer_Run_Msk | + ARM_VSI_Timer_Trig_DMA_Msk | + ARM_VSI_Timer_Trig_IRQ_Msk; + if (mode == VIDEO_DRV_MODE_CONTINUOS) { + control |= ARM_VSI_Timer_Periodic_Msk; + } + pVideo[channel]->Timer.Control = control; + + return VIDEO_DRV_OK; +} + +// Stop Stream on Video Interface +int32_t VideoDrv_StreamStop (uint32_t channel) { + + if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS))) { + return VIDEO_DRV_ERROR_PARAMETER; + } + + if ((Initialized == 0U) || + (Configured[channel] < 2U)) { + return VIDEO_DRV_ERROR; + } + + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) == 0U) { + return VIDEO_DRV_OK; + } + + pVideo[channel]->Timer.Control = 0U; + pVideo[channel]->DMA.Control = 0U; + pVideo[channel]->Reg_CONTROL = 0U; + + return VIDEO_DRV_OK; +} + +// Get Video Frame buffer +void *VideoDrv_GetFrameBuf (uint32_t channel) { + void *frame = NULL; + + if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS))) { + return NULL; + } + + if ((Initialized == 0U) || + (Configured[channel] < 2U)) { + return NULL; + } + + if ((pVideo[channel]->Reg_MODE & Reg_MODE_IO_Msk) == Reg_MODE_Input) { + // Input + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_BUF_EMPTY_Msk) != 0U) { + return NULL; + } + } else { + // Output + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_BUF_FULL_Msk) != 0U) { + return NULL; + } + } + + frame = (void *)(pVideo[channel]->DMA.Address + (pVideo[channel]->Reg_FRAME_INDEX * pVideo[channel]->DMA.BlockSize)); + + return frame; +} + +// Release Video Frame +int32_t VideoDrv_ReleaseFrame (uint32_t channel) { + + if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS))) { + return VIDEO_DRV_ERROR_PARAMETER; + } + + if ((Initialized == 0U) || + (Configured[channel] < 2U)) { + return VIDEO_DRV_ERROR; + } + + if ((pVideo[channel]->Reg_MODE & Reg_MODE_IO_Msk) == Reg_MODE_Input) { + // Input + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_BUF_EMPTY_Msk) != 0U) { + return VIDEO_DRV_ERROR; + } + } else { + // Output + if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_BUF_FULL_Msk) != 0U) { + return VIDEO_DRV_ERROR; + } + } + + pVideo[channel]->Reg_FRAME_INDEX = 0U; + + return VIDEO_DRV_OK; +} + + +// Get Video Interface status +VideoDrv_Status_t VideoDrv_GetStatus (uint32_t channel) { + VideoDrv_Status_t status = { 0U, 0U, 0U, 0U, 0U, 0U, 0U }; + uint32_t status_reg; + + if ((((channel & 1U) == 0U) && ((channel >> 1) < VIDEO_INPUT_CHANNELS)) || + (((channel & 1U) != 0U) && ((channel >> 1) < VIDEO_OUTPUT_CHANNELS))) { + status_reg = pVideo[channel]->Reg_STATUS; + status.active = (status_reg & Reg_STATUS_ACTIVE_Msk) >> Reg_STATUS_ACTIVE_Pos; + status.buf_empty = (status_reg & Reg_STATUS_BUF_EMPTY_Msk) >> Reg_STATUS_BUF_EMPTY_Pos; + status.buf_full = (status_reg & Reg_STATUS_BUF_FULL_Msk) >> Reg_STATUS_BUF_FULL_Pos; + status.overflow = (status_reg & Reg_STATUS_OVERFLOW_Msk) >> Reg_STATUS_OVERFLOW_Pos; + status.underflow = (status_reg & Reg_STATUS_UNDERFLOW_Msk) >> Reg_STATUS_UNDERFLOW_Pos; + status.eos = (status_reg & Reg_STATUS_EOS_Msk) >> Reg_STATUS_EOS_Pos; + } + + return status; +} diff --git a/source/hal/source/platform/mps3/CMakeLists.txt b/source/hal/source/platform/mps3/CMakeLists.txt index 5008f0b..2791150 100644 --- a/source/hal/source/platform/mps3/CMakeLists.txt +++ b/source/hal/source/platform/mps3/CMakeLists.txt @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------- -# SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com> +# SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> # SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -133,6 +133,18 @@ if (CPU_PROFILE_ENABLED) target_compile_definitions(${PLATFORM_DRIVERS_TARGET} PUBLIC CPU_PROFILE_ENABLED) endif() +# If Virtual Streaming Interface is enabled, we need to link the vsi driver +if (VSI_ENABLED) + target_sources(${PLATFORM_DRIVERS_TARGET} + PRIVATE + source/vsi_mps3.c) + add_subdirectory(${COMPONENTS_DIR}/vsi ${CMAKE_BINARY_DIR}/vsi) + + target_link_libraries(${PLATFORM_DRIVERS_TARGET} + PUBLIC + arm_vsi) +endif () + # If Ethos-U is enabled, we need the driver library too if (ETHOS_U_NPU_ENABLED) diff --git a/source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h b/source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h index 2085c6a..9fb7b9e 100644 --- a/source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h +++ b/source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com> + * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -131,6 +131,14 @@ #define UARTRX5_IRQn (125) /* UART 5 RX Interrupt */ #define UARTTX5_IRQn (126) /* UART 5 TX Interrupt */ #define UART5_IRQn (127) /* UART 5 combined Interrupt */ +#define ARM_VSI0_IRQn (224) /* 224: VSI 0 */ +#define ARM_VSI1_IRQn (225) /* 225: VSI 1 */ +#define ARM_VSI2_IRQn (226) /* 226: VSI 2 */ +#define ARM_VSI3_IRQn (227) /* 227: VSI 3 */ +#define ARM_VSI4_IRQn (228) /* 228: VSI 4 */ +#define ARM_VSI5_IRQn (229) /* 229: VSI 5 */ +#define ARM_VSI6_IRQn (230) /* 230: VSI 6 */ +#define ARM_VSI7_IRQn (231) /* 231: VSI 7 */ /* #undef HDCLCD_IRQn */ #endif /* PERIPHERAL_IRQS_H */ diff --git a/source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h b/source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h index 95b62c7..0414f63 100644 --- a/source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h +++ b/source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com> + * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -129,6 +129,14 @@ #define UARTRX5_IRQn (125) /* UART 5 RX Interrupt */ #define UARTTX5_IRQn (126) /* UART 5 TX Interrupt */ #define UART5_IRQn (127) /* UART 5 combined Interrupt */ +#define ARM_VSI0_IRQn (224) /* 224: VSI 0 */ +#define ARM_VSI1_IRQn (225) /* 225: VSI 1 */ +#define ARM_VSI2_IRQn (226) /* 226: VSI 2 */ +#define ARM_VSI3_IRQn (227) /* 227: VSI 3 */ +#define ARM_VSI4_IRQn (228) /* 228: VSI 4 */ +#define ARM_VSI5_IRQn (229) /* 229: VSI 5 */ +#define ARM_VSI6_IRQn (230) /* 230: VSI 6 */ +#define ARM_VSI7_IRQn (231) /* 231: VSI 7 */ /* #undef HDCLCD_IRQn */ #endif /* PERIPHERAL_IRQS_H */ diff --git a/source/hal/source/platform/mps3/include/vsi_mps3.h b/source/hal/source/platform/mps3/include/vsi_mps3.h new file mode 100644 index 0000000..a8895ea --- /dev/null +++ b/source/hal/source/platform/mps3/include/vsi_mps3.h @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef VSI_MPS3_H +#define VSI_MPS3_H + +#include <stdint.h> +#include <stdbool.h> + +#include "peripheral_irqs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __IM +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#endif +#ifndef __OM +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#endif +#ifndef __IOM +#define __IOM volatile /*! Defines 'read/write' structure member permissions */ +#endif + +/// Structure type to access the virtual streaming interface +typedef struct +{ + /// Interrupt Request (IRQ) + struct { + __IOM uint32_t Enable; /*!< (R/W) IRQ Enable */ + __OM uint32_t Set; /*!< (-/W) IRQ Set */ + __OM uint32_t Clear; /*!< (-/W) IRQ Clear */ + __IM uint32_t Status; /*!< (R/-) IRQ Status */ + } IRQ; + uint32_t reserved1[60]; + /// Time counter with 1MHz input frequency + struct { + __IOM uint32_t Control; /*!< (R/W) Timer Control */ + __IOM uint32_t Interval; /*!< (R/W) Timer Interval Value (in microseconds) */ + __IM uint32_t Count; /*!< (R/-) Timer Overflow Count */ + } Timer; + uint32_t reserved2[61]; + /// Direct Memory Access (DMA) Controller + struct { + __IOM uint32_t Control; /*!< (R/W) DMA Control */ + __IOM uint32_t Address; /*!< (R/W) DMA Memory Start Address */ + __IOM uint32_t BlockSize; /*!< (R/W) DMA Block Size (in bytes, multiple of 4) */ + __IOM uint32_t BlockNum; /*!< (R/W) DMA Number of Blocks (must be 2^n) */ + __IM uint32_t BlockIndex; /*!< (R/-) DMA Block Index */ + } DMA; + uint32_t reserved3[59]; + __IOM uint32_t Regs[64]; /*!< (R/W) User Registers */ +} ARM_VSI_Type; + +/* VSI Timer Control Definitions for Timer.Control register */ +#define ARM_VSI_Timer_Run_Pos 0U /*!< Timer Control: Run Position */ +#define ARM_VSI_Timer_Run_Msk (1UL << ARM_VSI_Timer_Run_Pos) /*!< Timer Control: Run Mask */ +#define ARM_VSI_Timer_Periodic_Pos 1U /*!< Timer Control: Periodic Position */ +#define ARM_VSI_Timer_Periodic_Msk (1UL << ARM_VSI_Timer_Periodic_Pos) /*!< Timer Control: Periodic Mask */ +#define ARM_VSI_Timer_Trig_IRQ_Pos 2U /*!< Timer Control: Trig_IRQ Position */ +#define ARM_VSI_Timer_Trig_IRQ_Msk (1UL << ARM_VSI_Timer_Trig_IRQ_Pos) /*!< Timer Control: Trig_IRQ Mask */ +#define ARM_VSI_Timer_Trig_DMA_Pos 3U /*!< Timer Control: Trig_DAM Position */ +#define ARM_VSI_Timer_Trig_DMA_Msk (1UL << ARM_VSI_Timer_Trig_DMA_Pos) /*!< Timer Control: Trig_DMA Mask */ + +/* VSI DMA Control Definitions for DMA.Control register */ +#define ARM_VSI_DMA_Enable_Pos 0U /*!< DMA Control: Enable Position */ +#define ARM_VSI_DMA_Enable_Msk (1UL << ARM_VSI_DMA_Enable_Pos) /*!< DMA Control: Enable Mask */ +#define ARM_VSI_DMA_Direction_Pos 1U /*!< DMA Control: Direction Position */ +#define ARM_VSI_DMA_Direction_Msk (1UL << ARM_VSI_DMA_Direction_Pos) /*!< DMA Control: Direction Mask */ +#define ARM_VSI_DMA_Direction_P2M (0UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction P2M */ +#define ARM_VSI_DMA_Direction_M2P (1UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction M2P */ + +/* Memory mapping of 8 VSI peripherals */ +#define ARM_VSI0_BASE (0x4FF00000UL) /*!< VSI 0 Base Address */ +#define ARM_VSI1_BASE (0x4FF10000UL) /*!< VSI 1 Base Address */ +#define ARM_VSI2_BASE (0x4FF20000UL) /*!< VSI 2 Base Address */ +#define ARM_VSI3_BASE (0x4FF30000UL) /*!< VSI 3 Base Address */ +#define ARM_VSI4_BASE (0x4FF40000UL) /*!< VSI 4 Base Address */ +#define ARM_VSI5_BASE (0x4FF50000UL) /*!< VSI 5 Base Address */ +#define ARM_VSI6_BASE (0x4FF60000UL) /*!< VSI 6 Base Address */ +#define ARM_VSI7_BASE (0x4FF70000UL) /*!< VSI 7 Base Address */ +#define ARM_VSI0 ((ARM_VSI_Type *)ARM_VSI0_BASE) /*!< VSI 0 struct */ +#define ARM_VSI1 ((ARM_VSI_Type *)ARM_VSI1_BASE) /*!< VSI 1 struct */ +#define ARM_VSI2 ((ARM_VSI_Type *)ARM_VSI2_BASE) /*!< VSI 2 struct */ +#define ARM_VSI3 ((ARM_VSI_Type *)ARM_VSI3_BASE) /*!< VSI 3 struct */ +#define ARM_VSI4 ((ARM_VSI_Type *)ARM_VSI4_BASE) /*!< VSI 4 struct */ +#define ARM_VSI5 ((ARM_VSI_Type *)ARM_VSI5_BASE) /*!< VSI 5 struct */ +#define ARM_VSI6 ((ARM_VSI_Type *)ARM_VSI6_BASE) /*!< VSI 6 struct */ +#define ARM_VSI7 ((ARM_VSI_Type *)ARM_VSI7_BASE) /*!< VSI 7 struct */ + +/** + * @brief Initialises the VSI + * @return 0 if successful, error code otherwise + **/ +int vsi_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* VSI_MPS3_H */ diff --git a/source/hal/source/platform/mps3/source/platform_drivers.c b/source/hal/source/platform/mps3/source/platform_drivers.c index 73b388b..1f55bb9 100644 --- a/source/hal/source/platform/mps3/source/platform_drivers.c +++ b/source/hal/source/platform/mps3/source/platform_drivers.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> + * SPDX-FileCopyrightText: Copyright 2022-2024 Arm Limited and/or its affiliates <open-source-office@arm.com> * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,6 +40,10 @@ #endif /* ARM_NPU */ +#if VSI_ENABLED +#include "vsi_mps3.h" +#endif /* VSI_ENABLED */ + /** * @brief Checks if the platform is valid by checking * the CPU ID for the FPGA implementation against @@ -94,6 +98,12 @@ int platform_init(void) #endif /* ARM_NPU */ +#if VSI_ENABLED + if (0 != (err = vsi_init())) { + return err; + } +#endif /* VSI_ENABLED */ + /* Print target design info */ info("Target system design: %s\n", s_platform_name); return 0; diff --git a/source/hal/source/platform/mps3/source/vsi_mps3.c b/source/hal/source/platform/mps3/source/vsi_mps3.c new file mode 100644 index 0000000..8516c1c --- /dev/null +++ b/source/hal/source/platform/mps3/source/vsi_mps3.c @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "vsi_mps3.h" + +#include "log_macros.h" +#include "RTE_Components.h" +#include "peripheral_irqs.h" + +#include "video_drv.h" + +/* Exception / Interrupt Handler */ +#define DEFAULT_IRQ_HANDLER(handler_name) \ +void __WEAK __NO_RETURN handler_name(void); \ +void handler_name(void) { \ + while(1); \ +} + +DEFAULT_IRQ_HANDLER(ARM_VSI0_Handler) +DEFAULT_IRQ_HANDLER(ARM_VSI1_Handler) +DEFAULT_IRQ_HANDLER(ARM_VSI2_Handler) +DEFAULT_IRQ_HANDLER(ARM_VSI3_Handler) +DEFAULT_IRQ_HANDLER(ARM_VSI4_Handler) +DEFAULT_IRQ_HANDLER(ARM_VSI5_Handler) +DEFAULT_IRQ_HANDLER(ARM_VSI6_Handler) +DEFAULT_IRQ_HANDLER(ARM_VSI7_Handler) + +int vsi_init(void) +{ + /* Register the VSI handlers in our vector table. */ + NVIC_SetVector(ARM_VSI0_IRQn, (uint32_t)ARM_VSI0_Handler); + NVIC_SetVector(ARM_VSI1_IRQn, (uint32_t)ARM_VSI1_Handler); + NVIC_SetVector(ARM_VSI2_IRQn, (uint32_t)ARM_VSI2_Handler); + NVIC_SetVector(ARM_VSI3_IRQn, (uint32_t)ARM_VSI3_Handler); + NVIC_SetVector(ARM_VSI4_IRQn, (uint32_t)ARM_VSI4_Handler); + NVIC_SetVector(ARM_VSI5_IRQn, (uint32_t)ARM_VSI5_Handler); + NVIC_SetVector(ARM_VSI6_IRQn, (uint32_t)ARM_VSI6_Handler); + NVIC_SetVector(ARM_VSI7_IRQn, (uint32_t)ARM_VSI7_Handler); + + /* Initialize Video VSI. */ + if (VideoDrv_Initialize(NULL) != VIDEO_DRV_OK) { + printf_err("Failed to initialise video driver\n"); + return 1; + } + + info("VSI device initialised\n"); + + return 0; +} diff --git a/source/use_case/img_class/usecase.cmake b/source/use_case/img_class/usecase.cmake index 4c25989..f18522c 100644 --- a/source/use_case/img_class/usecase.cmake +++ b/source/use_case/img_class/usecase.cmake @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------- -# SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com> +# SPDX-FileCopyrightText: Copyright 2021, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> # SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,10 +28,12 @@ USER_OPTION(${use_case}_LABELS_TXT_FILE "Labels' txt file for the chosen model" FILEPATH) # Generate input files -generate_images_code("${${use_case}_FILE_PATH}" - ${SRC_GEN_DIR} - ${INC_GEN_DIR} - "${${use_case}_IMAGE_SIZE}") +generate_images_code( + INPUT_DIR "${${use_case}_FILE_PATH}" + SRC_OUT ${SRC_GEN_DIR} + HDR_OUT ${INC_GEN_DIR} + IMG_SIZE "${${use_case}_IMAGE_SIZE}" +) # Generate labels file set(${use_case}_LABELS_CPP_FILE Labels) diff --git a/source/use_case/object_detection/include/UseCaseHandler.hpp b/source/use_case/object_detection/include/UseCaseHandler.hpp index 9fe716f..43fb6bf 100644 --- a/source/use_case/object_detection/include/UseCaseHandler.hpp +++ b/source/use_case/object_detection/include/UseCaseHandler.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com> + * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,11 +17,39 @@ #ifndef OBJ_DET_HANDLER_HPP #define OBJ_DET_HANDLER_HPP +#if VSI_ENABLED +#include "DetectionResult.hpp" +#include <vector> +#endif + +#include <cstdint> #include "AppContext.hpp" namespace arm { namespace app { +#if VSI_ENABLED + typedef object_detection::DetectionResult OdResults; + + /** + * @brief Draw boxe(s) detected by the model. + * @param[in] image Pointer to the image. + * @param[in] imageWidth Image width. + * @param[in] imageHeight Image height. + * @param[in] results A vector of detection results. + **/ + void DrawDetectionBoxesVsi(uint8_t* image, + const uint32_t imageWidth, + const uint32_t imageHeight, + const std::vector<OdResults>& results); + /** + * @brief Handles the inference event when using VSI. + * @param[in] ctx Pointer to the application context. + * @return true or false based on execution success. + **/ + bool ObjectDetectionHandlerVsi(ApplicationContext& ctx); +#endif + /** * @brief Handles the inference event. * @param[in] ctx Pointer to the application context. diff --git a/source/use_case/object_detection/src/MainLoop.cc b/source/use_case/object_detection/src/MainLoop.cc index 4735bcb..fe21de6 100644 --- a/source/use_case/object_detection/src/MainLoop.cc +++ b/source/use_case/object_detection/src/MainLoop.cc @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com> + * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,7 +41,12 @@ static void DisplayDetectionMenu() printf(" %u. Run detection ifm at chosen index\n", common::MENU_OPT_RUN_INF_CHOSEN); printf(" %u. Run detection on all ifm\n", common::MENU_OPT_RUN_INF_ALL); printf(" %u. Show NN model info\n", common::MENU_OPT_SHOW_MODEL_INFO); - printf(" %u. List ifm\n\n", common::MENU_OPT_LIST_IFM); + printf(" %u. List ifm\n", common::MENU_OPT_LIST_IFM); +#if VSI_ENABLED + fflush(stdout); + printf(" %u. Run detection using VSI as input\n", common::MENU_OPT_RUN_INF_VSI); +#endif + printf("\n"); printf(" Choice: "); fflush(stdout); } @@ -99,6 +104,11 @@ void main_loop() case common::MENU_OPT_LIST_IFM: executionSuccessful = ListFilesHandler(caseContext); break; +#if VSI_ENABLED + case common::MENU_OPT_RUN_INF_VSI: + executionSuccessful = ObjectDetectionHandlerVsi(caseContext); + break; +#endif default: printf("Incorrect choice, try again."); break; diff --git a/source/use_case/object_detection/src/UseCaseHandler.cc b/source/use_case/object_detection/src/UseCaseHandler.cc index 9330187..1a20db5 100644 --- a/source/use_case/object_detection/src/UseCaseHandler.cc +++ b/source/use_case/object_detection/src/UseCaseHandler.cc @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates + * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates * <open-source-office@arm.com> SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,6 +28,235 @@ namespace arm { namespace app { +#if VSI_ENABLED +#include "video_drv.h" /* Video Driver API. */ + + /** + * @brief Draws a box in the image using the object detection result object. + * + * @param[out] imageData Pointer to the start of the image. + * @param[in] width Image width. + * @param[in] height Image height. + * @param[in] result Object detection result. + */ + static void DrawBox(uint8_t* imageData, + const uint32_t width, + const uint32_t height, + const OdResults& result) + { + UNUSED(height); + const auto x = result.m_x0; + const auto y = result.m_y0; + const auto w = result.m_w; + const auto h = result.m_h; + + const uint32_t step = width * 3; + uint8_t* const imStart = imageData + (y * step) + (x * 3); + + uint8_t* dst_0 = imStart; + uint8_t* dst_1 = imStart + (h * step); + + for (uint32_t i = 0; i < static_cast<uint32_t>(w); ++i) { + *dst_0 = 255; + *dst_1 = 255; + + dst_0 += 3; + dst_1 += 3; + } + + dst_0 = imStart; + dst_1 = imStart + (w * 3); + + for (uint32_t j = 0; j < static_cast<uint32_t>(h); ++j) { + *dst_0 = 255; + *dst_1 = 255; + + dst_0 += step; + dst_1 += step; + } + } + + void DrawDetectionBoxesVsi(uint8_t* image, + const uint32_t imageWidth, + const uint32_t imageHeight, + const std::vector<OdResults>& results) + { + for (const auto& result : results) { + DrawBox(image, imageWidth, imageHeight, result); + printf("Detection :: [%d" ", %d" + ", %d" ", %d" "]\n", + result.m_x0, + result.m_y0, + result.m_w, + result.m_h); + } + } + + /* Object detection VSI inference handler. */ + bool ObjectDetectionHandlerVsi(ApplicationContext& ctx) + { + /* Image buffer. */ + static uint8_t ImageBuf[IMAGE_DATA_SIZE]; + static uint8_t ImageOut[IMAGE_DATA_SIZE]; + + /* Model object creation and initialisation. */ + auto& model = ctx.Get<Model&>("model"); + + TfLiteTensor* inputTensor = model.GetInputTensor(0); + TfLiteTensor* outputTensor0 = model.GetOutputTensor(0); + TfLiteTensor* outputTensor1 = model.GetOutputTensor(1); + + if (!inputTensor->dims) { + printf_err("Invalid input tensor dims\n"); + return false; + } else if (inputTensor->dims->size < 3) { + printf_err("Input tensor dimension should be >= 3\n"); + return false; + } + + TfLiteIntArray* inputShape = model.GetInputShape(0); + const int inputImgCols = inputShape->data[arm::app::YoloFastestModel::ms_inputColsIdx]; + const int inputImgRows = inputShape->data[arm::app::YoloFastestModel::ms_inputRowsIdx]; + + /* Set up pre- and post-processing. */ + arm::app::DetectorPreProcess preProcess = + arm::app::DetectorPreProcess(inputTensor, true, model.IsDataSigned()); + + std::vector<arm::app::OdResults> results; + const arm::app::object_detection::PostProcessParams postProcessParams{ + inputImgRows, + inputImgCols, + arm::app::object_detection::originalImageSize, + arm::app::object_detection::anchor1, + arm::app::object_detection::anchor2}; + arm::app::DetectorPostProcess postProcess = + arm::app::DetectorPostProcess(outputTensor0, outputTensor1, results, postProcessParams); + + const size_t imgSz = inputTensor->bytes < IMAGE_DATA_SIZE ? + inputTensor->bytes : IMAGE_DATA_SIZE; + + if (sizeof(ImageBuf) < imgSz) { + printf_err("Image buffer is insufficient\n"); + return false; + } + + /* Configure Input Video. */ + if (VideoDrv_Configure(VIDEO_DRV_IN0, + arm::app::object_detection::originalImageSize, + arm::app::object_detection::originalImageSize, + COLOR_RGB888, 24U) != VIDEO_DRV_OK) { + printf_err("Failed to configure video input\n"); + return false; + } + + /* Set Input Video buffer. */ + if (VideoDrv_SetBuf(VIDEO_DRV_IN0, ImageBuf, IMAGE_DATA_SIZE) != VIDEO_DRV_OK) { + printf_err("Failed to set buffer for video input\n"); + return false; + } + + /* Set Output Video file (only when using AVH - default: Display) */ + // if (VideoDrv_SetFile(VIDEO_DRV_OUT0, "output_image.png") != VIDEO_DRV_OK) { + // printf_err("Failed to set filename for video output\n"); + // return 1; + // } + /* Configure Output Video. */ + if (VideoDrv_Configure(VIDEO_DRV_OUT0, + arm::app::object_detection::originalImageSize, + arm::app::object_detection::originalImageSize, + COLOR_RGB888, 24U) != VIDEO_DRV_OK) { + printf_err("Failed to configure video output\n"); + return false; + } + + /* Set Output Video buffer. */ + if (VideoDrv_SetBuf(VIDEO_DRV_OUT0, ImageOut, IMAGE_DATA_SIZE) != VIDEO_DRV_OK) { + printf_err("Failed to set buffer for video output\n"); + return false; + } + + auto imgCount = ctx.Get<uint32_t>("imgIndex"); + void* imgFrame = nullptr; + void* outFrame = nullptr; + + while (true) { +#if VSI_IMAGE_INPUT + if (VideoDrv_SetFile(VIDEO_DRV_IN0, GetFilePath(imgCount)) != VIDEO_DRV_OK) { + printf_err("Failed to set filename for video input\n"); + return false; + } +#endif + + VideoDrv_Status_t status; + + results.clear(); + + /* Start video capture (single frame). */ + if (VideoDrv_StreamStart(VIDEO_DRV_IN0, VIDEO_DRV_MODE_SINGLE) != VIDEO_DRV_OK) { + printf_err("Failed to start video capture\n"); + return false; + } + + /* Wait for video input frame. */ + do { + status = VideoDrv_GetStatus(VIDEO_DRV_IN0); + } while (status.buf_empty != 0U); + + /* Get input video frame buffer. */ + imgFrame = VideoDrv_GetFrameBuf(VIDEO_DRV_IN0); + + /* Run the pre-processing, inference and post-processing. */ + if (!preProcess.DoPreProcess(imgFrame, imgSz)) { + printf_err("Pre-processing failed.\n"); + return false; + } + + /* Run inference over this image. */ + printf("\rImage %" PRIu32 "; ", ++imgCount); + + if (!model.RunInference()) { + printf_err("Inference failed.\n"); + return false; + } + + if (!postProcess.DoPostProcess()) { + printf_err("Post-processing failed.\n"); + return false; + } + + /* Release input frame. */ + VideoDrv_ReleaseFrame(VIDEO_DRV_IN0); + + arm::app::DrawDetectionBoxesVsi(static_cast<uint8_t*>(imgFrame), inputImgCols, inputImgRows, results); + + /* Get output video frame buffer. */ + outFrame = VideoDrv_GetFrameBuf(VIDEO_DRV_OUT0); + + /* Copy image frame with detection boxes to output frame buffer. */ + memcpy(outFrame, imgFrame, IMAGE_DATA_SIZE); + + /* Release output frame. */ + VideoDrv_ReleaseFrame(VIDEO_DRV_OUT0); + + /* Start video output (single frame). */ + VideoDrv_StreamStart(VIDEO_DRV_OUT0, VIDEO_DRV_MODE_SINGLE); + + /* Check for end of stream (when using AVH with file as Video input). */ + if (status.eos != 0U) { + while (VideoDrv_GetStatus(VIDEO_DRV_OUT0).buf_empty == 0U); + break; + } + } + + IncrementAppCtxIfmIdx(ctx, "imgIndex"); + + /* De-initialize Video Interface. */ + //VideoDrv_Uninitialize(); + return true; + } + +#endif + /** * @brief Presents inference results along using the data presentation * object. diff --git a/source/use_case/object_detection/usecase.cmake b/source/use_case/object_detection/usecase.cmake index a36d3e0..cb0236b 100644 --- a/source/use_case/object_detection/usecase.cmake +++ b/source/use_case/object_detection/usecase.cmake @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------- -# SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com> +# SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> # SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -36,10 +36,24 @@ USER_OPTION(${use_case}_CHANNELS_IMAGE_DISPLAYED "Channels' image displayed on t BOOL) # Generate input files -generate_images_code("${${use_case}_FILE_PATH}" - ${SRC_GEN_DIR} - ${INC_GEN_DIR} - "${${use_case}_IMAGE_SIZE}") +if (VSI_IMAGE_INPUT) + set(${use_case}_COMPILE_DEFS "VSI_IMAGE_INPUT") + + generate_images_code( + INPUT_DIR "${${use_case}_FILE_PATH}" + SRC_OUT ${SRC_GEN_DIR} + HDR_OUT ${INC_GEN_DIR} + IMG_SIZE "${${use_case}_IMAGE_SIZE}" + GENERATE_FILE_PATHS + ) +else () + generate_images_code( + INPUT_DIR "${${use_case}_FILE_PATH}" + SRC_OUT ${SRC_GEN_DIR} + HDR_OUT ${INC_GEN_DIR} + IMG_SIZE "${${use_case}_IMAGE_SIZE}" + ) +endif () USER_OPTION(${use_case}_ACTIVATION_BUF_SZ "Activation buffer size for the chosen model" 0x00082000 diff --git a/source/use_case/vww/usecase.cmake b/source/use_case/vww/usecase.cmake index 7a4d876..99580cc 100644 --- a/source/use_case/vww/usecase.cmake +++ b/source/use_case/vww/usecase.cmake @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------- -# SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com> +# SPDX-FileCopyrightText: Copyright 2021, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com> # SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -58,7 +58,9 @@ generate_labels_code( ) # Generate input files -generate_images_code("${${use_case}_FILE_PATH}" - ${SRC_GEN_DIR} - ${INC_GEN_DIR} - "${${use_case}_IMAGE_SIZE}") +generate_images_code( + INPUT_DIR "${${use_case}_FILE_PATH}" + SRC_OUT ${SRC_GEN_DIR} + HDR_OUT ${INC_GEN_DIR} + IMG_SIZE "${${use_case}_IMAGE_SIZE}" +) |